I am working on a assignment that performs convolution without using external libraries. The problem is that the resulting image is supposed to be blurred but the produced image is wrong.
Here is the link to the picture i am talking about.
The program takes the first 5 bytes of the greyscale RAW image as header and the rest into a 2D vector. Each pixel intensity (0-255) is represented by one byte in unsigned char. The 2D vector is used for convolution then the resulting vector is written into a new RAW image with the header.
#include <iostream>
#include <string>
#include <fstream>
#include <stdio.h>
#include <vector>
#include <math.h>
using namespace std;
vector<unsigned char> header;
vector < vector<unsigned char> > img;
short int width = 0;
short int height = 0;
void read(string filename, short int &width, short int &height, vector < vector<unsigned char> > &img, vector<unsigned char> &header)
{
const char* path = (char*)filename.c_str();
cout << endl << "Opening: " << path << endl << endl;
ifstream inputfile;
inputfile.open(path, ios::binary);
inputfile.seekg(0);
if (!inputfile)
{
inputfile.clear();
string pathin;
cout << "File not found "<< endl <<"Enter name of image to open : ";
getline(cin, pathin);
read(pathin, width, height, img, header);
}
else
{ //copy header into array
unsigned char h = 0;
for (int x = 0; x < 5; x++)
{
inputfile >>(h);
header.push_back(h);
}
//extract width and height from array
width = (header[1]<<8 | header[0]);
height = (header[3]<<8 | header[2]);
//copy image data into array
char a = '0';
for (int x = 0; x < width; x++)
{
vector <unsigned char> row;
for (int y = 0; y < height; y++)
{
inputfile.get(a);
row.push_back(a);
a = '0';
}
img.push_back(row);
}
inputfile.close();
}
return;
}
void convolution(vector < vector<unsigned char> > &img, short int width, short int height)
{
vector < vector<int> > mask = { { 1, 1, 1 },
{ 1, 1, 1 },
{ 1, 1, 1 } };
int sum;
double min = 0, max = 0, norm = 0;
vector<vector<int>> temp;
for (int i = 0; i < width; ++i)
{
vector<int>temprow;
for (int j = 0; j < height; ++j)
{
temprow.push_back(0);
}
temp.push_back(temprow);
}
for (int i = 1; i < (width-1); i++)
{
for (int j = 1; j < (height-1); j++)
{
sum = 0;
for (int u = -1; u <= 1; u++)
{
for (int v = -1; v <= 1; v++)
{
sum = sum + img[i + u][j + v] * (mask[u+1][v+1]);
}
}
if (sum > max)
max = sum;
if (sum < min)
sum = min;
temp[i][j] = sum;
}
}
//normalize pixels
norm = ceil(max / 255);
cout << "norm = "<<norm<<endl;
for (int i = 1; i < width; i++)
{
for (int j = 1; j < height; j++)
{
temp[i][j] = temp[i][j] /norm ;
}
}
//get max and min again
cout << "max = " << max << endl << "min = " << min<<endl;
max = 0; min = 0;
for (int i = 1; i < width-1; i++)
{
for (int j = 1; j < height-1; j++)
{
if (temp[i][j] > max)
max = temp[i][j];
if (temp[i][j] < min)
min = temp[i][j];
}
}
cout << "max = " << max << endl << "min = " << min << endl;
//display temp
cout << "temp: ";
for (int i = 0; i < 5; i++)
{
cout << endl;
for (int j = 0; j < 5; j++)
{
cout << temp[i][j] << " ";
}
}
//convert int to char
for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
img[i][j] = temp[i][j] & 0xff;
}
}
cout << endl;
//display img
cout << "img: ";
for (int i = 0; i < 5; ++i)
{
cout << endl;
for (int j = 0; j < 5; ++j)
printf("%d ", ((unsigned char)(img[i][j])));
}
cout << endl << endl;
}
void write(short int width, short int height, vector < vector<unsigned char> > img, vector<unsigned char> header)
{
string path = "test.raw";
ofstream output;
output.open(path, ios::binary);
for (int i = 0; i < 5; ++i)
{
cout << endl;
for (int j = 0; j < 5; ++j)
printf("%d ", ((unsigned char)(img[i][j])));
}
if (!output)
{
cout << "Error saving file." << endl;
return;
}
else
{
for (int x = 0; x < 5; x++)
output.put (header[x]);
for (int x = 0; x < width; x++)
{
for (int y = 0; y < height; y++)
output.put (img[x][y]);
}
output.close();
cout << "File is saved as: " << path << endl << endl;
}
}
int main()
{
string pathin;
cout << "Enter name of image to open: ";
cin >> pathin;
read(pathin, width, height, img, header);
convolution(img, width, height);
write(width, height, img, header);
system("PAUSE");
return 0;
}
At this point i am convinced something went wrong at writing stage since there is supposed to be a black border but it is missing in the image. I could display the data with openCV but couldn't get it to work either. I hope someone can point out what is causing this problem.

