//-----------------------------------------------------------------------------
// Programmer: Braden Andros
// Name: hw5.cpp
// Description: TODO
//-----------------------------------------------------------------------------
#include "Image.h"
#include <iostream>
#include <stack>
using namespace std;
// define struct to hold pixel location
struct PixelLocation {
int r;
int c;
};
// possible function prototypes that you may consider using (optional):
bool findPixelLocationWithGivenValue(const Image &image, int pixelValue, int &foundRow, int &foundCol);
int markConnectedComponent(Image &image, int seedRow, int seedCol, int ccLabel);
int main( int argc, char* argv[] )
{
// get input/output image file names from command line
if (argc != 4)
{
std::cout << "Usage instructions: " << std::endl;
std::cout << "> hw5.exe inputFileName.bmp thresholdedOutputFileName.bmp largeCCOutputFileName.bmp" << std::endl;
return -1;
}
std::string inputFileName(argv[1]);
std::string thresholdedOutputFileName(argv[2]);
std::string largeCCOutputFileName(argv[3]);
// read image from input file
std::cout << "Reading input image: " << inputFileName << std::endl;
Image myImage;
bool success = myImage.readFromBMPFile(inputFileName);
if (! success)
{
std::cout << "Error reading input image." << std::endl;
return -1;
}
const int THRESHOLD = 128;
const int LARGE = 500;
int r = myImage.getNumRows();
int c = myImage.getNumCols();
for (int i=0; i<r; i++)
{
for (int j=0; j<c; j++)
{
if (myImage.getPixel(i,j)>THRESHOLD)
{
myImage.setPixel(i, j, 255);
}
else
{
myImage.setPixel(i, j, 0);
}
}
}
myImage.writeToBMPFile(thresholdedOutputFileName);
int seedRow=0;
int seedCol=0;
int largeLabel=0;
int connectedLabel=1;
int val=0;
while (findPixelLocationWithGivenValue(myImage, 255, seedRow, seedCol))
{
val = markConnectedComponent(myImage, seedRow, seedCol, connectedLabel);
connectedLabel++;
if (val>=500)
{
largeLabel++;
}
else
{
myImage.setAllPixelsWithOldValToNewVal(255,0);
}
}
myImage.switchToRandomColorMapping();
myImage.writeToBMPFile(largeCCOutputFileName);
return 0;
}
bool findPixelLocationWithGivenValue(const Image &image, int pixelValue, int &foundRow, int &foundCol)
{
int r = image.getNumRows();
int c = image.getNumCols();
for (int i = foundRow; i<r; i++)
{
for (int j = foundCol; j<c; j++)
{
if (image.getPixel(i,j)==pixelValue)
{
foundRow=i;
foundCol=j;
return true;
}
}
}
return false;
}
int markConnectedComponent(Image &image, int seedRow, int seedCol, int ccLabel)
{
int numPixels=0;
stack<PixelLocation> pixelStack;
PixelLocation currPixel = {seedRow, seedCol};
const int seedVal = image.getPixel(seedRow, seedCol);
pixelStack.push(currPixel);
while (!pixelStack.empty())
{
currPixel = pixelStack.top();
PixelLocation neighbors[] = {{currPixel.r+1, currPixel.c},{currPixel.r-1, currPixel.c}, {currPixel.r, currPixel.c+1}, {currPixel.r, currPixel.c-1}};
size_t numNeighbors = sizeof(neighbors) / sizeof(*neighbors);
pixelStack.pop();
if (seedVal==image.getPixel(currPixel.r, currPixel.c))
{
image.setPixel(currPixel.r, currPixel.c, ccLabel);
for (int i=0; i < numNeighbors; i++)
{
numPixels++;
if (image.isInBounds(neighbors[i].r, neighbors[i].c))
{
pixelStack.push(neighbors[i]);
numPixels++;
}
}
}
}
return numPixels;
}