#include #include #include #include #include #include using namespace std; //struct for holding rgb color values typedef struct { int r,g,b; } rgb; const int NUMANGLES = 260; const int NUMDIST = 260; int main(int argc, char *argv[]){ string magicnum, comment; int height, width, range; int color_threshhold = 50; int near_threshhold = 3; int blocklen = 32; vector colors; rgb blue, orange; blue.r = 66; blue.g = 99; blue.b = 176; orange.r = 203; orange.g = 130; orange.b = 35; colors.push_back(blue); colors.push_back(orange); ifstream in; cout << "opening file: " << argv[1] << endl; in.open(argv[1], ios::in); getline(in, magicnum); if(!(magicnum == "P3")){ cout << "error: image is not of type PPM!" << endl; return 0; } getline(in, comment); in >> width; in >> height; in >> range; cout << "width: " << width << " height: " << height << " range: " << range << endl; rgb** ppm = new rgb*[height]; for(int k = 0; k < height; k++) ppm[k] = new rgb[width]; rgb** blocks = new rgb*[height/blocklen]; for(int k = 0; k < height/blocklen; k++) blocks[k] = new rgb[width/blocklen]; int** car_blocks = new int*[height/blocklen]; for(int k = 0; k < height/blocklen; k++) car_blocks[k] = new int[width/blocklen]; int** pos_blocks = new int*[height/blocklen]; for(int k = 0; k < height/blocklen; k++) pos_blocks[k] = new int[width/blocklen]; cout << "reading file... " << endl; //read the input file into an array of rgb data structures for(int y = 0; y < height; y++){ for(int x=0; x < width; x++){ in >> ppm[y][x].r; in >> ppm[y][x].g; in >> ppm[y][x].b; } } in.close(); cout << "done. calculating color values... " << endl; for(int y = 0; y < height; y++){ for(int x=0; x < width; x++){ blocks[y/blocklen][x/blocklen].r += ppm[y][x].r; blocks[y/blocklen][x/blocklen].b += ppm[y][x].b; blocks[y/blocklen][x/blocklen].g += ppm[y][x].g; } } cout << "averaging... " << endl; for(int y = 0; y < height/blocklen; y++){ for(int x = 0; x < width/blocklen; x++){ blocks[y][x].r = blocks[y][x].r/(blocklen*blocklen); blocks[y][x].g = blocks[y][x].g/(blocklen*blocklen); blocks[y][x].b = blocks[y][x].b/(blocklen*blocklen); } } cout << "done.\ndetecting car... " << endl; for(int y = 0; y < height/blocklen; y++){ for(int x = 0; x < width/blocklen; x++){ for(int k = 0; k < colors.size(); k++){ if(abs(blocks[y][x].r - colors.at(k).r) < color_threshhold && abs(blocks[y][x].g - colors.at(k).g) < color_threshhold && abs(blocks[y][x].b - colors.at(k).b) < color_threshhold){ pos_blocks[y][x] = 1; } } } } cout << "done.\nremoving false positives... " << endl; for(int y = 0; y < height/blocklen; y++){ for(int x = 0; x < width/blocklen; x++){ int near = 0; int yoff = 0; int xoff = 1; if(y+yoff > -1 && y+yoff < height/blocklen && x+xoff > -1 && x+xoff < width/blocklen) if(pos_blocks[y+yoff][x+xoff] == 1){ near++; } yoff = 0; xoff = -1; if(y+yoff > -1 && y+yoff < height/blocklen && x+xoff > -1 && x+xoff < width/blocklen) if(pos_blocks[y+yoff][x+xoff] == 1){ near++; } yoff = 1; xoff = 0; if(y+yoff > -1 && y+yoff < height/blocklen && x+xoff > -1 && x+xoff < width/blocklen) if(pos_blocks[y+yoff][x+xoff] == 1){ near++; } yoff = -1; xoff = 0; if(y+yoff > -1 && y+yoff < height/blocklen && x+xoff > -1 && x+xoff < width/blocklen) if(pos_blocks[y+yoff][x+xoff] == 1){ near++; } yoff = 1; xoff = 1; if(y+yoff > -1 && y+yoff < height/blocklen && x+xoff > -1 && x+xoff < width/blocklen) if(pos_blocks[y+yoff][x+xoff] == 1){ near++; } yoff = 1; xoff = -1; if(y+yoff > -1 && y+yoff < height/blocklen && x+xoff > -1 && x+xoff < width/blocklen) if(pos_blocks[y+yoff][x+xoff] == 1){ near++; } yoff = -1; xoff = 1; if(y+yoff > -1 && y+yoff < height/blocklen && x+xoff > -1 && x+xoff < width/blocklen) if(pos_blocks[y+yoff][x+xoff] == 1){ near++; } yoff = -1; xoff = -1; if(y+yoff > -1 && y+yoff < height/blocklen && x+xoff > -1 && x+xoff < width/blocklen) if(pos_blocks[y+yoff][x+xoff] == 1){ near++; } if(near > near_threshhold) car_blocks[y][x] = 1; } } cout << "done.\nbeginning output... " << endl; //output the pixel-blocked image fstream out1; out1.open("blocks.ppm", fstream::out); out1 << "P3" << endl; comment = "#created by Andrew Stebbins"; out1 << comment << endl; out1 << (width/blocklen) << " " << (height/blocklen) << endl; out1 << range << endl; for(int y = 0; y < height/blocklen; y++){ for(int x = 0; x < width/blocklen; x++){ out1 << blocks[y][x].r << endl; out1 << blocks[y][x].g << endl; out1 << blocks[y][x].b << endl; } } out1.close(); //output original image with outlined car fstream out2; out2.open("foundcar.ppm", fstream::out); out2 << "P3" << endl; comment = "#created by Andrew Stebbins"; out2 << comment << endl; out2 << width << " " << height << endl; out2 << range << endl; bool color = false; for(int y = 0; y < height; y++){ for(int x = 0; x < width; x++){ if(car_blocks[y/blocklen][x/blocklen] == 1){ out2 << ppm[y][x].r << endl; out2 << ppm[y][x].g << endl; out2 << ppm[y][x].b << endl; } else{ out2 << 0 << endl; out2 << 0 << endl; out2 << 0 << endl; } } } out2.close(); cout << "done.\n"; return 0; }