More C++ questions. I'm trying to pixelate an image that has been read into an array by making nxn non-overlapping windows and making each value the average of the window. (The read and write image functions are given to us.)
So 2x2:
10 20 30 40
11 21 31 41
12 22 32 42
13 23 33 43
is transformed to:
16 16 36 36
16 16 36 36
18 18 37 37
18 18 37 37
However, my code only seems to be doing it for the first column of nxn windows in the image, and it's not even the whole column. What's making it stop? Why isn't it working for each nxn window in the whole row?
So 2x2:
10 20 30 40
11 21 31 41
12 22 32 42
13 23 33 43
is transformed to:
16 16 36 36
16 16 36 36
18 18 37 37
18 18 37 37
However, my code only seems to be doing it for the first column of nxn windows in the image, and it's not even the whole column. What's making it stop? Why isn't it working for each nxn window in the whole row?
Code:
#include <iostream>
#include <cassert>
#include <cstdlib>
#include <fstream>
#include <cmath>
using namespace std;
const int MAXWIDTH = 512;
const int MAXHEIGHT = 512;
void readImage(int image[MAXWIDTH][MAXHEIGHT], int &width, int &height);
void writeImage(int image[MAXWIDTH][MAXHEIGHT], int width, int height);
int main() {
//Ask user for number n
int n;
cout << "Enter n: " << endl;
cin >> n;
int imageArray[MAXWIDTH][MAXHEIGHT];
int imageWidth, imageHeight;
//Input PMM file into array
readImage(imageArray, imageWidth, imageHeight);
//Copy image to 2nd array
int pixelatedImage[MAXWIDTH][MAXHEIGHT];
for(int row = 0; row < imageHeight; row++)
{
for(int col = 0; col < imageWidth; col++)
{
pixelatedImage[col][row] = imageArray[col][row];
}
}
//make n x n windows
int i = 0;
int j = 0;
int runningI = 0;
int runningJ = 0;
int runningTotal = 0;
int average;
int rowN = n;
int colN = n;
while(rowN < imageHeight)
{
while (colN < imageWidth)
{
//Get average of n x n window
runningTotal = 0;
while(j < rowN)
{
while(i < colN)
{
runningTotal += pixelatedImage[j][i];
i++;
}
j++;
runningI = i;
//Restart i
i = i - n;
}
runningJ = j;
//Restart j
j = j - n;
average = round(runningTotal/(n*n));
//Write average to n x n window
while(j < rowN)
{
while(i < colN)
{
pixelatedImage[j][i] = average;
i++;
}
j++;
//Restart i
i = i - n;
}
//Restart j
j = j - n;
//Move to next n x n window column in current row of windows
colN += n;
i = runningI;
}
//Move down to next window row
rowN += n;
j = runningJ;
}
//Write the 2nd array into outImage
writeImage(pixelatedImage, imageWidth, imageHeight);
}
// reads a PPM file.
// Notice that: width and height are passed by reference!
void readImage(int image[MAXWIDTH][MAXHEIGHT], int &width, int &height) {
char c;
int x;
ifstream instr;
instr.open("inImage.pgm");
// read the header P3
instr >> c; assert(c == 'P');
instr >> c; assert(c == '2');
// skip the comments (if any)
while ((instr>>ws).peek() == '#') { instr.ignore(4096, '\n'); }
instr >> width;
instr >> height;
assert(width <= MAXWIDTH);
assert(height <= MAXHEIGHT);
int max;
instr >> max;
assert(max == 255);
for (int row = 0; row < height; row++)
for (int col = 0; col < width; col++)
instr >> image[col][row];
instr.close();
return;
}
void writeImage(int image[MAXWIDTH][MAXHEIGHT], int width, int height) {
ofstream ostr;
ostr.open("outImage.pgm");
if (ostr.fail()) {
cout << "Unable to write file\n";
exit(1);
};
// print the header
ostr << "P2" << endl;
// width, height
ostr << width << ' ';
ostr << height << endl;
ostr << 255 << endl;
for (int row = 0; row < height; row++) {
for (int col = 0; col < width; col++) {
assert(image[col][row] < 256);
assert(image[col][row] >= 0);
ostr << image[col][row] << ' ';
// lines should be no longer than 70 characters
if ((col+1)%16 == 0) ostr << endl;
}
ostr << endl;
}
ostr.close();
return;
}