int main(int argc, char *argv[]) { QApplication app(argc, argv); DrawWindow window; SceneController ctrl; window.setController( &ctrl ); window.show(); return app.exec(); }
int main(void) { char* g_image_filename="images/lena.jpg"; Mat src = imread( g_image_filename, 1 ); if (src.empty()) { std::cout << "!!! Failed imread()\n ./colors <image filename>" << std::endl; return -1; } DrawWindow WIPC = DrawWindow(src.cols,src.rows,"IPC countours"); // w,h Shapes SIPC; ImageParserContours IPC; if (1) { IPC.setMinContourLength(5); IPC.setCannyThreshold(50); IPC.parseImage(src); IPC.useRandomColors(1); //IPC.draw(); // IPC.defineShapes(&SIPC); //IPC.printImageData(1); WIPC.clearWindow(230,230,230); // default background is white SIPC.drawAll(&WIPC); WIPC.show(); } DrawWindow WIPK = DrawWindow(src.cols,src.rows,"IPK pixel regions"); // w,h Shapes SIPK; ImageParserKmeans IPK; if (1) { IPK.setMinPixelsInRegion(5); IPK.parseImage(src); IPK.useRandomColors(1); IPK.draw(); IPK.defineShapes(&SIPK); // IPC.printImageData(1); WIPK.clearWindow(230,230,230); // default background is white SIPK.drawAll(&WIPK); WIPK.show(); } while (1) { int k = waitKey(33); if (k==27) { // Esc key to stop return(0); } } return 0; }
void draw() { RNG rng(12345); DrawWindow W = DrawWindow(kmeans_image.cols,kmeans_image.rows,"Regions"); // w,h W.clearWindow(0,255,0); for (int r=0; r<regions.size(); r++) { int num_pixels=regions[r].size(); if (num_pixels>=min_region_pixels) { W.setPenColor(region_colors[r][2],region_colors[r][1],region_colors[r][0]); if (use_random_colors) { W.setPenColor(rng.uniform(100,200),rng.uniform(100,200),rng.uniform(100,200)); } printf("%i region: %lu pixels %i,%i,%i\n",r,regions[r].size(),region_colors[r][2],region_colors[r][1],region_colors[r][0]); W.drawRegion(regions[r]); } } W.show(); //while (waitKey(33)<0) { } }
// given an image, return a list of contiguous regions in pixels (e.g., if an image has // 3 separate regions of red, each region will be a different list of pixels) void defineRegionsInImage(Mat *image) { RNG rng(12345); int debug = 0; //Mat done_image = image->clone(); int rows=image->rows; int cols=image->cols; int* done = new int [rows*cols]; // which pixels are done std::vector<Point> wavefront; // will automatically allocate member if needed int num_regions=0; for (int i=0; i<rows*cols; i++) { done[i]=-1; } std::vector<Vec3b> colors; // uninitialized. Let sortColorsInImage fill it. sortColorsInImage(image,colors); // prints out which colors are in image for (int c=0; c<colors.size(); c++) { printf("Finding regions of color:(%d,%d,%d)\n",colors[c][0],colors[c][1],colors[c][2]); int start_i=0; // where left off looking for a color Vec3b set_color; if (debug) { set_color[0]=rng.uniform(100,200); set_color[1]=rng.uniform(100,200); set_color[2]=rng.uniform(100,200); } else { set_color = colors[c]; } int num_regions_for_a_color = 0; int found_color=1; while (found_color) { found_color = 0; std::vector<Point> region; // points in this region (auto expands array if needed) // find one pixel of this color that hasn't been done for (int i=start_i; i<cols; i++) { start_i=i; // for speedup for (int j=0; j<rows; j++) { if (done[i*rows+j] == -1) { Vec3b color = image->at<Vec3b>(Point(i,j)); if (color[0] == colors[c][0] && color[1] == colors[c][1] && color[2] == colors[c][2]) { if (!found_color) { // *if* added to reduce bugs? //printf(" - first pixel found at pixel %d,%d\n",i,j); wavefront.push_back(Point(i,j)); region.push_back(Point(i,j)); num_regions++; num_regions_for_a_color++; done[i*rows+j]=num_regions; // 1=is in wavefront //printf("X:%d %d to %d %d\n",i,j,region[0].x,region[0].y); //printf("X:%d %d to %d %d\n",i,j,wavefront[0].x,wavefront[0].y); } found_color=1; i=image->cols; j=image->rows; } } } } if (found_color) { // expand a wavefront from the found pixel that matches the color // wavefront from that pixel and mark all adjacent ones while (wavefront.size()) { Point p=wavefront[wavefront.size()-1]; wavefront.pop_back(); // count how many of each color of the neighbors of i,j int left=max(p.x-1 , 0); int right=min(p.x+1 , cols-1); int top=max(p.y-1 , 0); int bottom=min(p.y+1 ,rows-1); //int pixels=(1+right-left)*(1+bottom-top) - 1; // how many neighbor pixels to compare for (int n=left; n<=right; n++) { for (int m=top; m<=bottom; m++) { if (n!=p.x && m!=p.y && done[n*rows+m]==-1) { // candidate pixel Vec3b color = image->at<Vec3b>(Point(n,m)); if (color[0] == colors[c][0] && color[1] == colors[c][1] && color[2] == colors[c][2]) { done[n*rows+m]=num_regions; // in wavefront wavefront.push_back(Point(n,m)); region.push_back(Point(n,m)); } } } } } regions.push_back(region); region_colors.push_back(colors[c]); // print out region if (debug) { printf("REGION %d.%d [%d,%d](%d,%d,%d): %lu points\n",num_regions,num_regions_for_a_color, region[0].x,region[0].y, colors[c][0],colors[c][1],colors[c][2],region.size()); } if (region.size()>=min_region_pixels) { for (int i=0; i<region.size(); i++) { if (i<10) { if (debug) { printf("(%d,%d)",region[i].x,region[i].y); if (i!=region.size()-1) { printf(","); } } } image->at<Vec3b>(Point(region[i].x,region[i].y)) = set_color; // change to xxx } if (debug) printf("\n"); } else { Vec3b set_color; set_color[0]=0; set_color[1]=255; set_color[2]=0; for (int i=0; i<region.size(); i++) { image->at<Vec3b>(Point(region[i].x,region[i].y))=set_color; } num_regions--; } while(region.size()) { region.pop_back(); } } } } DrawWindow DW = DrawWindow(cols,rows,"Done grid"); // w,h DW.clearWindow(255,255,255); for (int i=0; i<cols; i++) { for (int j=0; j<rows; j++) { int d=min(2*done[i*rows+j],255); DW.setPenColor(d,d,d); if (done[i*rows+j]<0) { DW.setPenColor(0,0,255); } else if (done[i*rows+j]<min_region_pixels) { DW.setPenColor(255,0,0); } else if (done[i*rows+j]<2*min_region_pixels) { DW.setPenColor(255,255,0); } else if (done[i*rows+j]<5*min_region_pixels) { DW.setPenColor(0,255,0); } DW.drawPixel(i,j); } } DW.show(); // move a small region's pixels into a larger neighbor //void moveSmallRegionsIntoNeighbors() { if (0) { int num_moved=1; int max_loops=10; int total_candidate_pixels=0; while (num_moved>0 && max_loops>0) { num_moved=0; max_loops--; for (int i=0; i<cols; i++) { for (int j=0; j<rows; j++) { int region_id=done[i*rows+j]; int size=regions[region_id].size(); if (size<min_region_pixels) { total_candidate_pixels++; int left=max(i-1,0); int right=min(i+1,image->cols-1); int top=max(j-1,0); int bottom=min(j+1,image->rows-1); int largest_pixels=9999990; int largest_region_id=-1; for (int n=left; n<=right; n++) { for (int m=top; m<=bottom; m++) { if (n!=i || m!=j) { int size=regions[done[n*rows+m]].size(); if (size>=min_region_pixels && size<largest_pixels) { largest_pixels=size; largest_region_id=done[n*rows+m]; } } } } if (largest_region_id>=0) { // move this pixel into this region num_moved++; printf("%i: moved %i,%i from %i(%i pxs) to %i(%i pxs) region\n",total_candidate_pixels,i,j,done[i*rows+j],size,largest_region_id,largest_pixels); regions[largest_region_id].push_back(Point(i,j)); done[i*rows+j]=largest_region_id; Vec3b set_color; set_color[0]=0; set_color[1]=0; set_color[2]=255; image->at<Vec3b>(j,i)=set_color; // remove the point from the original tiny region //printf("BEFORE %lu\n",regions[region_id].size()); //int remove_index=-1; for (int p=0; p<=regions[region_id].size(); p++) { //printf("x=%i y=%i\n",regions[region_id][p].x,regions[region_id][p].y); //if (regions[region_id][p].x==i && regions[region_id][p].y==j) { remove_index=p; } } //printf("removing %d\n",remove_index); //regions[region_id].erase(regions[region_id].begin()+remove_index); //continue; //p=regions[region_id].size()+1; // get out of loop so can only remove 1 point from list //regions[region_id].erase(std::remove(regions[region_id].begin(), regions[region_id].end(), Point(i,j)), regions[region_id].end()); //printf("AFTER %lu\n",regions[region_id].size()); } } } } } printf("Moved %d pixels to larger regions (loop #%d)\n",num_moved,10-max_loops); } printf("Defined %d regions\n",num_regions); delete [] done; }