Well this is my first post on the board; hopefully I got the code tags right.
For my advanced c++ course I had to write a program that read in a .bmp file that was 256 colors and 320x240 pixels.
Here are the instructions:
"Project #4
Image Processing
Write a C++ program to read an image and apply some statistical functions to it.
Write your Image C++ class in a header file, and call an instance of it from the source file.
1. Read an image
2. Find the MEAN of the image
3. Find the STDV of the image
4. Apply the following filter to the image and write the output image to the disk.
1 1 1
1 2 1
1 1 1
5. Write the result buffer to an image."
I managed to do all this but then he threw me a curve ball. He told us to dynamically allocate the buffers. I thought I knew how to do this but I was wrong apparently as I can't get it to work. If anyone can help me I would appreciate it.
Below is the code I have written.
file = Image.h
Code:
#include <fstream>
using namespace std;
typedef unsigned char uchar;
class CImage
{
public:
CImage(const char* filename);
~CImage();
void write(const char* filename);
double mean();
double stdv();
void filter();
private:
ifstream* m_pInFile;
ofstream* m_pOutFile;
uchar m_cHeaderData[1078];
uchar** m_cImageData;
uchar m_cFilter[3][3];
uchar** m_cFilteredData;
};
file = Image.cpp
Code:
#ifndef __IMAGE_H
#define __IMAGE_H
#define WIDTH 320
#define HEIGHT 240
#include "Image.h"
#include <cmath>
#endif
using namespace std;
typedef unsigned char uchar;
///////////////////////////////////////////////////////////////////////////////
// Constructor
///////////////////////////////////////////////////////////////////////////////
CImage::CImage(const char* filename)
{
m_cImageData = new uchar* [HEIGHT];
m_cFilteredData = new uchar* [HEIGHT];
for( int i = 0; i < HEIGHT; i++)
{
m_cImageData[i] = new uchar [WIDTH];
m_cFilteredData[i] = new uchar [WIDTH];
}
m_pInFile = new ifstream;
m_pInFile->open(filename, ios::in | ios::binary);
m_pInFile->seekg(0, ios::beg);
m_pInFile->read(reinterpret_cast<char*>(m_cHeaderData[i]), 1078);
for( i = 0; i < HEIGHT; i++)
{
m_pInFile->read(reinterpret_cast<char*>(m_cImageData[i]), WIDTH);
}
m_pInFile->close();
// define the filter for the image
char m_cFilter[3][3] = {
{1, 1, 1},
{1, 2, 1},
{1, 1, 1}
};
}
///////////////////////////////////////////////////////////////////////////////
// Destructor
///////////////////////////////////////////////////////////////////////////////
CImage::~CImage()
{
delete m_pInFile;
delete m_pOutFile;
for(int i = 0; i < HEIGHT; i++)
{
delete[] m_cImageData[i];
delete[] m_cFilteredData[i];
}
delete[] m_cImageData;
delete[] m_cFilteredData;
}
///////////////////////////////////////////////////////////////////////////////
// Output the filtered image to a new bitmap file
///////////////////////////////////////////////////////////////////////////////
void CImage::write(const char* filename)
{
filter();
m_pOutFile = new ofstream;
m_pOutFile->open(filename, ios::out | ios::trunc | ios::binary);
m_pOutFile->write(reinterpret_cast<char*>(m_cHeaderData), 1078);
for(int i = 0; i < HEIGHT; i++)
{
m_pOutFile->write(reinterpret_cast<char*>(m_cFilteredData[i]), WIDTH);
}
m_pOutFile->close();
}
///////////////////////////////////////////////////////////////////////////////
// Calculate the mean of all the pixels
///////////////////////////////////////////////////////////////////////////////
double CImage::mean()
{
double total = 0;
for(int i = 0; i < HEIGHT; i++)
{
for(int j = 0; j < WIDTH; j++)
{
total += m_cImageData[i][j];
}
}
return (total / (HEIGHT * WIDTH));
}
///////////////////////////////////////////////////////////////////////////////
// Calculate the standard deviation of all the pixels
///////////////////////////////////////////////////////////////////////////////
double CImage::stdv()
{
double avg = mean();
double radicand = 0;
for(int i = 0; i < HEIGHT; i++)
{
for(int j = 0; j < WIDTH; j++)
{
radicand += (m_cImageData[i][j] - avg) * (m_cImageData[i][j] - avg);
}
}
radicand /= (HEIGHT * WIDTH);
return sqrt(radicand);
}
///////////////////////////////////////////////////////////////////////////////
// Filter all the pixels
///////////////////////////////////////////////////////////////////////////////
void CImage::filter()
{
int sumofpixels = 0;
for(int i = 0; i < HEIGHT; i++)
{
strcpy(reinterpret_cast<char*>(m_cFilteredData[i]), reinterpret_cast<char*>(m_cImageData[i]));
}
for( i = 1; i < HEIGHT - 1; i++)
{
for(int j = 1; j < WIDTH - 1; j++)
{
sumofpixels = m_cFilter[0][0] * m_cImageData[i+1][j-1] + // top left corner
m_cFilter[0][1] * m_cImageData[i+1][j] + // top center
m_cFilter[0][2] * m_cImageData[i+1][j+1] + // top right corner
m_cFilter[1][0] * m_cImageData[i][j-1] + // center left
m_cFilter[1][1] * m_cImageData[i][j] + // center center
m_cFilter[1][2] * m_cImageData[i][j+1] + // center right
m_cFilter[2][0] * m_cImageData[i-1][j-1] + // bottom left corner
m_cFilter[2][1] * m_cImageData[i-1][j] + // bottom center
m_cFilter[2][2] * m_cImageData[i-1][j+1]; // bottom right corner
m_cFilteredData[i][j] = (sumofpixels / (m_cFilter[0][0] + m_cFilter[0][1] +
m_cFilter[0][2] + m_cFilter[1][0] +
m_cFilter[1][1] + m_cFilter[1][2] +
m_cFilter[2][0] + m_cFilter[2][1] +
m_cFilter[2][2]) );
}
}
}
file = Project4.cpp
Code:
#include "Image.h"
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
CImage ci("test.bmp");
ci.write("output.bmp");
cout << ci.mean() << endl;
cout << ci.stdv() << endl;
return 0;
}