#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "FrameInfo.h" #include "MyPair.h" using namespace Magick; using namespace std; void findObj(Image* img, int x, int y, vector > & shape ,bool eightCon=true, bool colorLookingFor=true); void eightConnObj(Image* img, int x, int y, vector > & obj, bool color=true); void fourConnObj(Image* img, int x, int y, vector > & obj, bool color=true); void findObjIterative(Image* img, int x, int y, vector > & shape, bool eightCon, double colorLookingFor); void fourConnObjIterative(Image* img, int x, int y, vector > & obj, double colorLookingFor); vector covariantDecomposition(vector > & points); pair getCentroid(vector > & points); bool isInterface(Image* orig, unsigned int x, unsigned int y); void writeFrameImage(int fn, string imS); int roundT(double v) {return int(v+0.5);} const double PI = atan(1.0)*4.0; const double FACTOR_EIGEN = 100; Image* residual; Image* imgForFilter; ostream &operator<<(ostream &out, FlyObject & fO) { fO.output(out); return out; } ostream &operator<<(ostream &out, FrameInfo & fI) { fI.output(out); return out; } vector > > shapeVectors; vector > shape; vector > sizeNIndexVector; void bubbleSort() { for(int i=1; i a = sizeNIndexVector[j]; pair b = sizeNIndexVector[j+1]; if (a.first < b.first) { pair c = sizeNIndexVector[j]; sizeNIndexVector[j] = sizeNIndexVector[j+1]; sizeNIndexVector[j+1] = c; } } } } void fillResidualWithObj(vector > & obj, ColorRGB c) { for (unsigned int i = 0; ipixelColor(obj[i].first, obj[i].second, c); } void writeHist(const char* filename, map & len) { map::iterator front = len.begin(), back = len.end(); back--; unsigned int first = front->first, last = back->first; /*if (cutoff != -1 && cutoff < int(last)) last = cutoff; */ cout << "Min: " << first << endl << "Max: " << last << endl << "Count: " << last-first << endl; //vector hist(last-first, 0); vector hist(last+1, 0); cout << "hist size: " << hist.size() << endl; try{ for(unsigned int j = 0; j= int(hist.size()) ) hist.resize(j-first,0); hist[roundT(j-first)] = len[j]; */ /*if ( roundT(j) >= int(hist.size()) ) hist.resize(j,0); hist[roundT(j)] = len[j]; */ hist[j] = len[j]; } } catch (...) { cerr << "Bad histogram bucketing" << endl; } /*if ( (cutoff >= 0) && (cutoffcolumns(); int height = original->rows(); sprintf(buffer,"%ix%i",width,height); imgForFilter = new Image(buffer, "white"); shape.clear(); // find the black background from location (0,0) ColorMono topLeftColor = ColorMono(original->pixelColor(0,0)); ColorMono topRightColor = ColorMono(original->pixelColor(width-1,0)); ColorMono bottomRightColor = ColorMono(original->pixelColor(width-1,height-1)); ColorMono bottomLeftColor = ColorMono(original->pixelColor(0,height-1)); if (topLeftColor.mono() == false) { findObjIterative(original, 0, 0, shape, false, 0.0); } else if (topRightColor.mono() == false) { cout << "Top left is not black pixel for FLOOD FILLING so flood filling from top right\n"; findObjIterative(original, width-1, 0, shape, false, 0.0); } else if (bottomRightColor.mono() == false) { cout << "Top left/Top right are not black pixel for FLOOD FILLING so flood filling from bottom right\n"; findObjIterative(original, width-1, height-1, shape, false, 0.0); } else { cout << "Top left/top right/bottom right are not black pixel for FLOOD FILLING so flood filling from the bottomleft\n"; findObjIterative(original, 0, height-1, shape, false, 0.0); } string inputFileName = outputFileLocation + "temp/" + savedFileName; Image* final_image = imgForFilter; sprintf(buffer,"%ix%i",width,height); // residual image is initialized with black representing not visited. residual = new Image(buffer, "black"); shapeVectors.clear(); sizeNIndexVector.clear(); // find the objects and sort according to size int objectCounter = 0; for (int x=0; x 0) { shapeVectors.push_back(shape); pair si(s, objectCounter); sizeNIndexVector.push_back(si); objectCounter++; } } } bubbleSort(); // take the largest object double currentLargestSize = static_cast(sizeNIndexVector[0].first); double secondLargest = 0; double ratio = 0; if (sizeNIndexVector.size() > 1) { secondLargest = static_cast(sizeNIndexVector[1].first); ratio = secondLargest/currentLargestSize; } // find the largest to second largest ratio if it is less than the defined ratio then // the objects are single object int numberOfObjects = 0; if (sizeNIndexVector.size() == 1) { numberOfObjects = 1; } else if (ratio <= ratioSecondLargestToLargest ) { numberOfObjects = 1; } else { numberOfObjects = 2; } Image* imgFinal = new Image(buffer, "black"); for (int n=0; npixelColor(shapeVectors[ sizeNIndexVector[n].second ][i].first, shapeVectors[ sizeNIndexVector[n].second ][i].second, "white"); } } // write final image cout << finalImageName << " \r"; imgFinal->write( finalImageName.c_str() ); { // // writing the single in red // if (numberOfObjects == 1) { // // Image* singleObjectFinal = new Image(buffer, "black"); // // int totalPoints = sizeNIndexVector[0].first; // // cout << "Output the single object of size = "<pixelColor(shapeVectors[ sizeNIndexVector[0].second ][i].first, shapeVectors[ sizeNIndexVector[0].second ][i].second, "red"); // } // // //string singleImageName = "output/filtered/single/"+fileName; // string singleImageName = outputFileLocation + "single/"+ savedFileName; // // singleObjectFinal->write(singleImageName.c_str()); // // } // } return 0; } void findObjIterative(Image* img, int x, int y, vector > & shape, bool eightCon, double colorLookingFor) { assert(imgForFilter != NULL); fourConnObjIterative(img, x, y, shape, colorLookingFor); } void fourConnObjIterative(Image* img, int x, int y, vector > & obj, double colorLookingFor) { /* Flood-fill (node, target-color, replacement-color): 1. Set Q to the empty queue. 2. If the color of node is not equal to target-color, return. 3. Add node to Q. 4. For each element n of Q: 5. If the color of n is equal to target-color: 6. Set w and e equal to n. 7. Move w to the west until the color of the node to the west of w no longer matches target-color. 8. Move e to the east until the color of the node to the east of e no longer matches target-color. 9. Set the color of nodes between w and e to replacement-color. 10. For each node n between w and e: 11. If the color of the node to the north of n is target-color, add that node to Q. If the color of the node to the south of n is target-color, add that node to Q. 12. Continue looping until Q is exhausted. 13. Return. */ queue< MyPair > Q; ColorRGB imgpixel = ColorRGB(img->pixelColor(x,y)); if ( (imgpixel.red() != colorLookingFor) and (imgpixel.green() != colorLookingFor) and (imgpixel.blue() != colorLookingFor)) { cout << "Returning without floodfilling because the first pixel is not the colorLookingFor"<columns(),height = img->rows(); while (Q.empty() != true) { MyPair n = Q.front(); Q.pop(); ColorRGB westColor; ColorRGB eastColor; ColorRGB nColor; MyPair i,j; nColor = ColorRGB(img->pixelColor(n.first, n.second)); if ( (nColor.red() == colorLookingFor) and (nColor.green() == colorLookingFor) and (nColor.blue() == colorLookingFor)) { //cout << "Current pixel is of the black color ("<pixelColor(e.first, e.second)); else { //cout << "outside of the image boundary in x direction so break the while loop for east"<pixelColor(i.first, i.second, ColorRGB(colorLookingFor, colorLookingFor, colorLookingFor) ); // change the color to green to indicate that it is visited img->pixelColor(i.first, i.second, ColorRGB(0.0, 1.0, 0.0)); //cout << "Current pixel visited "<=0 ) { MyPair n(i.first, i.second-1); ColorRGB northColor = ColorRGB(img->pixelColor(n.first, n.second)); if ((northColor.red() == colorLookingFor) and (northColor.green() == colorLookingFor) and (northColor.blue() == colorLookingFor)) { Q.push(n); //cout << "North pixel not visited so pushed "<pixelColor(s.first, s.second)); //cout << "South color "<size; i++) retval.push_back(gsl_vector_get(eigenVal, i)); for (j = 0; jsize2; j++) for (i = 0; isize1; i++) retval.push_back(gsl_matrix_get(eigenVec, i, j)); retval.push_back(static_cast(centroid.first)); retval.push_back(static_cast (centroid.second)); // for (i=0; i<2; i++) { // gsl_vector_view evec_i = gsl_matrix_column (eigenVec, i); // //printf ("eigenvalue = %g\n", eval_i); // cout<<"eigenvector = \n"; // gsl_vector_fprintf (stdout, &evec_i.vector, "%g"); // } gsl_vector_free(eigenVal); gsl_matrix_free(matrice); gsl_matrix_free(eigenVec); return retval; } // isInterface for binary image bool isInterface(Image* orig, unsigned int x, unsigned int y) { ColorMono currentpixel = (ColorMono)orig->pixelColor(x,y); // If the current pixel is black pixel then it is not boundary pixel // error check if (currentpixel.mono() == false) return false; // If the current pixel is not black then it is white. So, now we need // to check whether any four of its neighbor pixels (left, top, right, // bottom ) is black. If any of this neighbor is black then current // pixel is a neighbor pixel. Otherwise current pixel is not neighbor // pixel. ColorMono leftneighborpixel = (ColorMono)orig->pixelColor(x-1,y); ColorMono topneighborpixel = (ColorMono)orig->pixelColor(x,y-1); ColorMono rightneighborpixel = (ColorMono)orig->pixelColor(x+1,y); ColorMono bottomneighborpixel = (ColorMono)orig->pixelColor(x,y+1); // If leftneighborpixel is black and currentpixel is white then it is // boundary pixel if ( leftneighborpixel.mono() != currentpixel.mono()) return true; // If topneighborpixel is black and currentpixel is white then it is // boundary pixel else if (topneighborpixel.mono() != currentpixel.mono()) return true; // If rightneighborpixel is black and currentpixel is white then it // is boundary pixel else if (rightneighborpixel.mono() != currentpixel.mono()) return true; // If bottomneighborpixel is black and currentpixel is white then it // is boundary pixel else if (bottomneighborpixel.mono() != currentpixel.mono()) return true; // Else all of its neighbor pixels are white so it can not be a // boundary pixel else return false; }