int main(int argc, char *argv[]) { unsigned int max = 0; if ( argc != 2 ) { cerr << "Usage: " << argv[0] << " <filename>" << endl; return 1; } // Load the input image CImg< unsigned char > inputImage = CImg< unsigned char >(argv[1]); if ( inputImage.spectrum() != 3 ) { cerr << "The input must be a color image." << endl; return 1; } // Convert the input image to grayscale and compute the histogram unsigned int * histogram = new unsigned int [HISTOGRAM_SIZE]; CImg< unsigned char > grayImage = CImg< unsigned char >(inputImage.width(), inputImage.height(), 1, 1); CImg< unsigned char > histogramImage = CImg< unsigned char >(BAR_WIDTH * HISTOGRAM_SIZE, HISTOGRAM_SIZE, 1, 1); memset(reinterpret_cast< void * >(histogram), 0, HISTOGRAM_SIZE * sizeof(unsigned int)); int r=histogram1D(inputImage.width(), inputImage.height(), inputImage.data(), grayImage.data(), histogram); if(r==1){ cout << "ERROR\n"; return 1; } for ( int i = 0; i < HISTOGRAM_SIZE; i++ ) { if ( histogram[i] > max ) { max = histogram[i]; } } for ( int x = 0; x < HISTOGRAM_SIZE * BAR_WIDTH; x += BAR_WIDTH ) { unsigned int value = HISTOGRAM_SIZE - ((histogram[x / BAR_WIDTH] * HISTOGRAM_SIZE) / max); for ( unsigned int y = 0; y < value; y++ ) { for ( int i = 0; i < BAR_WIDTH; i++ ) { histogramImage[(y * HISTOGRAM_SIZE * BAR_WIDTH) + x + i] = 0; } } for ( int y = value; y < HISTOGRAM_SIZE; y++ ) { for ( int i = 0; i < BAR_WIDTH; i++ ) { histogramImage[(y * HISTOGRAM_SIZE * BAR_WIDTH) + x + i] = 255; } } } // Save output grayImage.save(("./" + string(argv[1]) + ".gray.par.bmp").c_str()); histogramImage.save(("./" + string(argv[1]) + ".hist.par.bmp").c_str()); return 0; }
// Main procedure //---------------- int main(int argc,char **argv) { // Create game graphics CImg<unsigned char> graphics[21] = { CImg<unsigned char>(data_tomato,100,100,1,3,false), CImg<unsigned char>(data_heart,100,100,1,3,false), CImg<unsigned char>(data_dynamite,100,100,1,3,false), CImg<unsigned char>(data_brain,100,100,1,3,false), CImg<unsigned char>(data_cdrom,100,100,1,3,false), CImg<unsigned char>(data_enemy,113,150,1,3,false), CImg<unsigned char>(data_enemy2,116,155,1,3,false), CImg<unsigned char>(data_enemy3,104,134,1,3,false), CImg<unsigned char>(data_enemy4,141,151,1,3,false), CImg<unsigned char>(data_enemy5,140,152,1,3,false), CImg<unsigned char>(data_enemy6,131,156,1,3,false), CImg<unsigned char>(data_enemy7,114,125,1,3,false), CImg<unsigned char>(data_enemy8,97,125,1,3,false), CImg<unsigned char>(data_enemy9,143,134,1,3,false), CImg<unsigned char>(data_enemy10,158,214,1,3,false), CImg<unsigned char>(data_enemy11,131,168,1,3,false), CImg<unsigned char>(data_enemy12,114,138,1,3,false), CImg<unsigned char>(data_enemy13,144,144,1,3,false), CImg<unsigned char>(data_enemy14,132,153,1,3,false), CImg<unsigned char>(data_enemy15,152,151,1,3,false), CImg<unsigned char>(data_enemy16,139,185,1,3,false), }; CImg<> masks[21]; const unsigned char black[] = { 0,0,0 }, white[] = { 255,255,255 }; // Display weapon selection menu CImg<unsigned char> back0(640,480,1,3), title(data_title,294,94,1,3,true), choose(data_choose,524,49,1,3,true); back0.fill(0).draw_image(back0.width()/2-title.width()/2,30,title).draw_image(back0.width()/2-choose.width()/2,150,choose); CImgDisplay disp(back0,"OdyKill"); int weapon=-1; while (!disp.is_closed() && !disp.button()) { weapon = -1; for (int k=0; k<5; k++) { const int mx = disp.mouse_x(), my = disp.mouse_y(); if (!((mx-40)/110==k && my>250 && my<350)) back0.draw_image(40+k*110,250,graphics[k]/2.0); else back0.draw_image(40+k*110,250,graphics[weapon=k]); } CImg<unsigned char> tmp = CImg<unsigned char>().draw_text(0,0, weapon==0?" Tomato ": weapon==1?" Heart ": weapon==2?" Dynamite ": weapon==3?" Brain ": weapon==4?" CD-Rom ": " ",white,black,1,32).resize(-100,-100,1,1), tmp2 = tmp.get_blur(6).normalize(0,255).draw_image(tmp,0.5f); cimg_forC(back0,k) back0.draw_image(250,390,0,k,tmp2); disp.resize(disp).display(back0).wait(); if (disp.is_keyCTRLLEFT() && disp.is_keyF()) disp.toggle_fullscreen(); if (disp.is_closed() || disp.is_keyQ() || disp.is_keyESC()) std::exit(0); } disp.hide_mouse(); /*--------------------------------- Go ! --------------------------------*/ const CImg<unsigned char> background = CImg<unsigned char>(100,100,1,3,0).noise(100,2).draw_plasma(). resize(back0.width(),back0.height(),1,3,5)/2.5; { for (unsigned int k=0; k<21; k++) { CImg<> tmp = graphics[k].resize(k<5?32:164,k<5?32:164,1,3); cimg_forXY(tmp,x,y) tmp(x,y) = (tmp(x,y,0)==255 && tmp(x,y,1)==255 && tmp(x,y,2)==255)?0.0f:1.0f; masks[k]=tmp.get_shared_channel(0); graphics[k].resize(k<5?32:164,k<5?32:164,1,3,5); }} CImg<unsigned char> canvas(background); int n = 5+((int)(200*cimg::rand())%16); CImg<unsigned char> tomato = graphics[weapon], enemy = graphics[n]; CImg<> m_tomato = masks[weapon], m_enemy = masks[n]; double angle=0; int tomato_x=0,tomato_y=0,shooted=0; double enemy_x=-1000, enemy_y=-1000, enemy_z=-1000, tomato_z = 0, vx = 0, vy = 0, vz = 0, va = 0; double speed = cimg_option("-speed",5.0,"Speed"); int timeleft = 2000, score = 0; CImg<unsigned char> r_enemy; // Main loop while (timeleft && !disp.is_closed() && !disp.is_keyESC() && !disp.is_keyQ()) { --timeleft; const int mx = disp.mouse_x()*back0.width()/disp.width(), my = disp.mouse_y()*back0.height()/disp.height(); // Handle object motion if (tomato_z>0) { tomato_z+=0.07; tomato_y -= (int)(20*std::cos(cimg::PI/7 + tomato_z*cimg::PI)); if (tomato_z>=1) { tomato_z=0; tomato_x = mx; tomato_y = my; } } if (!shooted) { enemy_x +=vx; enemy_y +=vy; enemy_z +=vz; } else { va = 10; enemy_y += vy; vy += 2; tomato_z = 0; if (enemy_y>5*canvas.height()/4) { shooted = 0; int n = 5 + ((int)(200*cimg::rand())%16); enemy = graphics[n]; m_enemy = masks[n]; enemy_x=cimg::crand()*1e8; enemy_y=cimg::crand()*1e8; enemy_z=cimg::crand()*1e8; va = angle = 0; } } if (enemy_x<0) { enemy_x=0; vx = speed*cimg::crand(); } if (enemy_x>canvas.width()) { enemy_x=canvas.width(); vx = speed*cimg::crand(); } if (enemy_y<0) { enemy_y=0; vy = speed*cimg::crand(); } if (!shooted && enemy_y>canvas.height()) { enemy_y=canvas.height(); vy = speed*cimg::crand(); } if (enemy_z<0.1) { enemy_z = 0.1; vz = speed*0.01*cimg::crand(); } if (enemy_z>0.7) { enemy_z = 0.7; vz = speed*0.01*cimg::crand(); } angle+=va; // Handle mouse interaction if (!disp.button()) { if (tomato_z==0) { tomato_x = mx; tomato_y = my; } } else tomato_z +=0.0001; // Detect shooting if (cimg::abs(tomato_z-enemy_z)<0.1) { if (tomato_x>enemy_x-r_enemy.width()/2 && tomato_x<enemy_x+r_enemy.width()/2 && tomato_y>enemy_y-r_enemy.height()/2 && tomato_y<enemy_y+r_enemy.height()/2) { score++; shooted = 1; } } // Draw into canvas canvas = background; r_enemy = enemy.get_resize((int)(8+enemy.width()*(1-enemy_z)),(int)(8+enemy.height()*(1-enemy_z)),-100,-100); CImg<> rm_enemy = m_enemy.get_resize(r_enemy.width(),r_enemy.height()); CImg<unsigned char> r_tomato = tomato.get_resize((int)(8+tomato.width()*(1-tomato_z)),(int)(8+tomato.height()*(1-tomato_z)),-100,-100); CImg<> rm_tomato = m_tomato.get_resize(r_tomato.width(),r_tomato.height()); if (angle!=0) { r_enemy.rotate((float)angle,0,0); rm_enemy.rotate((float)angle,0,0); cimg_forXY(r_enemy,x,y) r_enemy(x,y,0) = (r_enemy(x,y,0)+255)/2; } r_enemy*=(1-(enemy_z-0.1)/1.6); r_tomato*=(1-tomato_z/1.6); rm_enemy*=(1-(enemy_z-0.1)/1.6); if (enemy_z>tomato_z) { canvas.draw_image((int)(enemy_x - r_enemy.width()/2), (int)(enemy_y - r_enemy.height()/2), r_enemy,rm_enemy); if (tomato_x>=0) canvas.draw_image(tomato_x - r_tomato.width()/2, tomato_y - r_tomato.height()/2, r_tomato,rm_tomato); } else { if (tomato_x>=0) canvas.draw_image(tomato_x - r_tomato.width()/2, tomato_y - r_tomato.height()/2, r_tomato,rm_tomato); canvas.draw_image((int)(enemy_x - r_enemy.width()/2), (int)(enemy_y - r_enemy.height()/2), r_enemy,rm_enemy); } canvas.draw_text(1,1," Time left %d, Score = %d",white,0,0.5f,24,timeleft,score); disp.resize(disp).display(canvas).wait(25); if (disp.is_keyCTRLLEFT() && disp.is_keyF()) disp.toggle_fullscreen(); } std::fprintf(stderr,"\n\n YOUR SCORE : %d\n\n\n",score); return 0; }
void SaveToFile(const char *SavePath, Pixel *SourceBitmap, BMSize SourceWidth, BMSize SourceHeight) { CImg<Pixel> Bitmap = CImg<Pixel>(SourceBitmap, SourceWidth, SourceHeight, 1, 1, true); Bitmap.save(SavePath); }
unsigned int GetNPoints() { return data.size(); }
void CData::Read(const std::vector<double> &values) { data.assign(values.data(), values.size()); dt = 1.25; // ns tmax = dt*data.size(); }
void show_graph(CImgDisplay &disp, CImg<double> &data, const unsigned int plot_type, const unsigned int vertex_type, const char *const labelx, const double xmin, const double xmax, const char *const labely, const double ymin, const double ymax) { if (data.is_empty()) return; if (!disp) disp.assign(cimg_fitscreen(640,480,1),0,0).set_title("CImg<%s>", data.pixel_type()); const unsigned long siz = (unsigned long)data._width*data._height*data._depth, siz1 = cimg::max(1U,siz-1); const unsigned int old_normalization = disp.normalization(); disp.show().flush()._normalization = 0; double y0 = ymin, y1 = ymax, nxmin = xmin, nxmax = xmax; if (nxmin==nxmax) { nxmin = 0; nxmax = siz1; } int x0 = 0, x1 = data.width()*data.height()*data.depth() - 1, key = 0; for (bool reset_view = true, resize_disp = false; !key && !disp.is_closed(); ) { if (reset_view) { x0 = 0; x1 = data.width()*data.height()*data.depth()-1; y0 = ymin; y1 = ymax; reset_view = false; } CImg<double> zoom(x1-x0+1,1,1,data.spectrum()); cimg_forC(data,c) zoom.get_shared_channel(c) = CImg<double>(data.data(x0,0,0,c),x1-x0+1,1,1,1,true); if (y0==y1) { y0 = zoom.min_max(y1); const double dy = y1 - y0; y0-=dy/20; y1+=dy/20; } if (y0==y1) { --y0; ++y1; } const CImg<int> selection = zoom.get_select_graph(disp,plot_type,vertex_type, labelx, nxmin + x0*(nxmax-nxmin)/siz1, nxmin + x1*(nxmax-nxmin)/siz1, labely,y0,y1); const int mouse_x = disp.mouse_x(), mouse_y = disp.mouse_y(); if (selection[0]>=0) { if (selection[2]<0) reset_view = true; else { x1 = x0 + selection[2]; x0+=selection[0]; if (selection[1]>=0 && selection[3]>=0) { y0 = y1 - selection[3]*(y1-y0)/(disp.height()-32); y1-=selection[1]*(y1-y0)/(disp.height()-32); } } } else { bool go_in = false, go_out = false, go_left = false, go_right = false, go_up = false, go_down = false; switch (key = disp.key()) { case cimg::keyHOME : reset_view = resize_disp = true; key = 0; disp.set_key(); break; case cimg::keyPADADD : go_in = true; go_out = false; key = 0; disp.set_key(); break; case cimg::keyPADSUB : go_out = true; go_in = false; key = 0; disp.set_key(); break; case cimg::keyARROWLEFT : case cimg::keyPAD4 : go_left = true; go_right = false; key = 0; disp.set_key(); break; case cimg::keyARROWRIGHT : case cimg::keyPAD6 : go_right = true; go_left = false; key = 0; disp.set_key(); break; case cimg::keyARROWUP : case cimg::keyPAD8 : go_up = true; go_down = false; key = 0; disp.set_key(); break; case cimg::keyARROWDOWN : case cimg::keyPAD2 : go_down = true; go_up = false; key = 0; disp.set_key(); break; case cimg::keyPAD7 : go_left = true; go_up = true; key = 0; disp.set_key(); break; case cimg::keyPAD9 : go_right = true; go_up = true; key = 0; disp.set_key(); break; case cimg::keyPAD1 : go_left = true; go_down = true; key = 0; disp.set_key(); break; case cimg::keyPAD3 : go_right = true; go_down = true; key = 0; disp.set_key(); break; } if (disp.wheel()) { if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) go_out = !(go_in = disp.wheel()>0); else if (disp.is_keySHIFTLEFT() || disp.is_keySHIFTRIGHT()) go_left = !(go_right = disp.wheel()>0); else go_up = !(go_down = disp.wheel()<0); key = 0; } if (go_in) { const int xsiz = x1 - x0, mx = (mouse_x-16)*xsiz/(disp.width()-32), cx = x0 + (mx<0?0:(mx>=xsiz?xsiz:mx)); if (x1-x0>4) { x0 = cx - 7*(cx-x0)/8; x1 = cx + 7*(x1-cx)/8; if (disp.is_keyCTRLLEFT() || disp.is_keyCTRLRIGHT()) { const double ysiz = y1 - y0, my = (mouse_y-16)*ysiz/(disp.height()-32), cy = y1 - (my<0?0:(my>=ysiz?ysiz:my)); y0 = cy - 7*(cy-y0)/8; y1 = cy + 7*(y1-cy)/8; } else y0 = y1 = 0; } } if (go_out) { if (x0>0 || x1<(int)siz1) { const int delta_x = (x1-x0)/8, ndelta_x = delta_x?delta_x:(siz>1?1:0); const double ndelta_y = (y1-y0)/8; x0-=ndelta_x; x1+=ndelta_x; y0-=ndelta_y; y1+=ndelta_y; if (x0<0) { x1-=x0; x0 = 0; if (x1>=(int)siz) x1 = (int)siz1; } if (x1>=(int)siz) { x0-=(x1-siz1); x1 = (int)siz1; if (x0<0) x0 = 0; } } } if (go_left) { const int delta = (x1-x0)/5, ndelta = delta?delta:1; if (x0-ndelta>=0) { x0-=ndelta; x1-=ndelta; } else { x1-=x0; x0 = 0; } go_left = false; } if (go_right) { const int delta = (x1-x0)/5, ndelta = delta?delta:1; if (x1+ndelta<(int)siz) { x0+=ndelta; x1+=ndelta; } else { x0+=(siz1-x1); x1 = siz1; } go_right = false; } if (go_up) { const double delta = (y1-y0)/10, ndelta = delta?delta:1; y0+=ndelta; y1+=ndelta; go_up = false; } if (go_down) { const double delta = (y1-y0)/10, ndelta = delta?delta:1; y0-=ndelta; y1-=ndelta; go_down = false; } } } disp._normalization = old_normalization; }
unsigned int Size() { return data.size(); }
void CData::DrawGraph(CImg<unsigned char> &img, double minV, double maxV) { img.draw_graph(data, color.Get(), 1.0f, 1, 1, maxV - offsetY, minV - offsetY); }
void CDataList::Draw(CImg<unsigned char> &img, double minV, double maxV) { const double gridV = 100.0; const double gridT = 25.0; // ns const unsigned char col_black[3] = { 0, 0, 0 }; const unsigned char col_gray[3] = { 100, 180, 255 }; img.fill(255); if (n == 0) return; double maxT = list[0]->GetTSpan(); double gridX = img.width()/maxT; // pixel / ns double gridY = img.height()/(maxV-minV); // --- draw t-grid --------------------------------------------------------- for (double t = 0.0; t < maxT; t += gridT) { int x = int(t*gridX + 0.5); img.draw_line(x, 0, x, img.height()-20, col_gray, 1.0, 0x88888888 /* 0xCCCCCCCC */); } // --- draw v-grid --------------------------------------------------------- for (double v = minV+gridV; v < maxV; v += gridV) { int y = int(((maxV-v)*gridY) + 0.5); img.draw_line(0, y, img.width()-20, y, col_gray, 1.0, 0x88888888 /* 0xCCCCCCCC */); } // --- plots with zero line ------------------------------------------------ for (unsigned i=0; i<n; i++) { int y = int((maxV - list[i]->offsetY)*img.height()/(maxV-minV) + 0.5); img.draw_line(0, y, img.width(), y, col_gray, 1.0, 0xffffffff /* 0xCCCCCCCC */); list[i]->DrawGraph(img, minV, maxV); } // --- draw t-axis --------------------------------------------------------- int axisY = img.height() - 20; img.draw_line(0, axisY, img.width(), axisY, col_black, 1.0); for (double t = 0.0; t < maxT; t += 2*gridT) { int x = int(t*gridX + 0.5); img.draw_line(x, axisY-2, x, axisY+2, col_black, 1.0); img.draw_text(x-10, axisY+4, "%0.0f", col_black, 0, 1.0, 14, t); } // --- draw v-axis --------------------------------------------------------- for (double v = minV+gridV; v < maxV; v += gridV) { int y = int(((maxV-v)*gridY) + 0.5); img.draw_text(10, y-6, "%0.0f", col_black, 0, 1.0, 14, v); } }
// Main procedure //---------------- int main(int argc, char **argv) { // Display help (if option '-h' or '--help' specified) and retrieve program arguments cimg_usage("A small and funny game featuring colored balls.\n (by David Tschumperle)."); const char *score_file = cimg_option("-s",(char*)0,"Specify score file to use (0=default file)."); cimg_help("\n" "** Quick Help *********************************************************\n\n" "Goal : Delete the board by clicking on groups of adjacent colored balls\n" " (a group is made of at least two balls with the same color).\n" " Suppressing large sets gives higher scores.\n\n" "In-game keys : - BACKSPACE or SPACE = Undo last move\n" " - CTRL+F = Toggle fullscreen mode\n" " - ESC = Quit application\n" " - Q = End current game\n\n" "*********************************************************************"); // Load score file if available CImgList<unsigned int> score_history; char filename_history[1024]; std::sprintf(filename_history,"%s%s",score_file?"":cimg::temporary_path(),score_file?score_file:"/jawbreaker.score"); std::FILE *file = std::fopen(filename_history,"r"); if (file) { std::fclose(file); score_history = CImg<unsigned int>::get_load_dlm(filename_history)<'y'; } // Create ball graphics const unsigned int W = 12, H = 14, Wi = (W<<5), Hi = (H<<5); unsigned int score = 0, previous_score = 0, shape_score = 0, best_score = score_history?score_history.max():0U; const CImg<> colors(3,7,1,1, 255,255,255, 205,0,230, 0,235,0, 235,255,0, 235,0,0, 0,128,255, 450,350,300); const unsigned char white[] = { 255,255,255 }, orange[] = { 255,128,64 }, yellow[] = { 255,255,64 }, red[] = { 255,64,64 }, six = 6; CImgList<> balls0(7,32,32,1,3,0); cimglist_for(balls0,l) if (l) { balls0[l].draw_circle(16,16,14,colors.data(0,l)); cimg_forXYC(balls0[l],x,y,k) if (balls0(l,x,y,k)) (balls0(l,x,y,k)*=(32-x+y)/60.0f)+=20; balls0[l].draw_circle(16,16,14,colors.data(0,l),0.5f,~0U). draw_circle(20,10,5,colors.data(),0.2f).draw_circle(22,8,2,colors.data(),0.4f).cut(0,255); } // Create background graphics CImgList<unsigned char> balls(balls0); CImg<unsigned char> mask = balls[1].get_cut(0,1).channel(0).dilate(3), background = CImg<unsigned char>(Wi,Hi,1,3,0). noise(255,1).blur(6,20,0,true).equalize(100,0,255).blur(2,4,0,true); background.get_shared_channel(0)/=4; background.get_shared_channel(1)/=8; background.get_shared_channel(2)/=2; // Begin user-interaction loop. CImg<unsigned char> board, previous_board, selected_board, shape, img(background); CImgDisplay disp(img.width(),img.height(),"Jawbreaker",0); bool redraw = true, gameover = false, title = true; for (float opac = 0.0f; !disp.is_closed(); ) { // Init board if (!board) { (++((board.assign(W,H,1,1,5).noise(5,1))%=5)).get_shared_row(0).fill(0); opac = (float)(score = previous_score = shape_score = 0); gameover = false; redraw = title = true; previous_board = board; } // Draw graphical board if (redraw) { (img=background).draw_text(2,2,"Score : %u",yellow,0,0.7f,24,score). draw_text(Wi-90,2,"Best : %u",orange,0,0.9f,17,best_score); if (selected_board) { cimg_forXY(selected_board,x,y) if (selected_board(x,y)) img.draw_image(x<<5,y<<5,balls[selected_board(x,y)],mask); } else cimg_forXY(board,x,y) if (board(x,y)) img.draw_image(x<<5,y<<5,balls[board(x,y)],mask); if (title) { CImg<unsigned char> text1, text2; text1.draw_text(0,0,"- Jawbreaker -",white,0,1,48).resize(-100,-100,1,3); text2.draw_text(0,0,"Press button to start",yellow,0,1,24).resize(-100,-100,1,3); (img/=2).draw_image((Wi-text1.width())/2, (Hi-text1.height())/2, text1,text1.get_dilate(7),1,255). draw_image((Wi-text2.width())/2, (Hi+text1.height()+10)/2, text2,text2.get_dilate(5),0.7f,255); for (float i = 1; i<10 && !disp.is_keyESC(); i+=0.25) disp.display(img.get_crop((int)(Wi*(0.5f-i*i/200.0f)),(int)(Hi*(0.5f-i*i*i*i/20000.0f)), (int)(Wi*(0.5f+i*i/200.0f)),(int)(Hi*(0.5f+i*i*i*i/20000.0f)))).wait(20); } } if ((opac-=0.06f)>0) disp.display((+img).draw_text(disp.mouse_x()-8,disp.mouse_y()-80+(int)(60*opac),"+%u", white,0,(float)std::sqrt(opac),32,shape_score)).wait(20); else { if (redraw) { disp.display(img); redraw = false; } else disp.wait(); } // Handle key and window events if (disp.is_resized()) disp.resize(disp); if (disp.is_keyBACKSPACE() || disp.is_keySPACE()) { board = previous_board; score = previous_score; selected_board.assign(); redraw = true; disp.set_key(); } if (disp.is_keyQ()) { gameover = true; disp.set_key(); } if (disp.is_keyESC()) disp.close(); if (disp.is_keyCTRLLEFT() && disp.is_keyF()) disp.toggle_fullscreen().display(img); // Handle ball selection and removal const int x = disp.mouse_x()*board.width()/disp.width(), y = disp.mouse_y()*board.height()/disp.height(); if (disp.button()&1 && x>=0 && y>=0) { if (title) { title = false; redraw = true; } else { if (!board(x,y)) { selected_board.assign(); redraw = true; } else { if (!selected_board || selected_board(x,y)!=6) { (selected_board=board).draw_fill(x,y,0,&six,1,shape); if ((shape_score=(unsigned int)shape.sum())<2) selected_board.assign(); else { (shape_score-=1)*=shape_score; opac = 1.0f; redraw = true; } } else { selected_board.assign(); previous_board = board; previous_score = score; score += shape_score; board&=--shape; redraw = true; // Handle board modification due to ball removal for (int pmax = board.width(), p=0; p<pmax; ++p) { for (int q = board.height()-1, qs = q; q>=0; --q) { while (!board(p,qs)) --qs; board(p,q) = (qs>=0?board(p,qs--):0); } if (!board(p,board.height()-1)) { board.draw_image(p,board.get_crop(p,0,board.width()-1,board.height()-1).shift(-1)); if (p<pmax) { p--; pmax--; } } } // Test possible end of the game gameover = true; cimg_forXY(board,x,y) if (board(x,y) && ((y && board(x,y)==board(x,y-1)) || (x && board(x,y)==board(x-1,y)))) gameover = false; } } } disp.set_button(); } // If game is over... if (gameover && opac<=0) { CImg<unsigned char> text1, text2, text3, text4, text5, text6; text1.draw_text(0,0,"Game Over !",white,0,1,48).resize(-100,-100,1,3); const unsigned int remaining_balls = (unsigned int)board.get_cut(0,1).sum(); if (remaining_balls<8) { const unsigned int bonus = (22-2*remaining_balls)*10; score += bonus; text2.draw_text(0,0,"Jawbreaker Bonus : +%u",white,0,1,24,bonus); } score_history.insert(CImg<unsigned int>::vector(score)); text3.draw_text(0,0,"Final score : %u",yellow,0,1,24,score).resize(-100,-100,1,3); text4.draw_text(0,0,score>best_score?"** New record ! **":"Best score : %u", orange,0,1,24,score>best_score?score:best_score).resize(-100,-100,1,3); text5.draw_text(0,0,"Average score : %u",red,0,1,24, score_history?(unsigned int)(score_history>'x').mean():0U).resize(-100,-100,1,3); text6.draw_text(0,0,"Games played : %u",red,0,1,24,score_history.size()).resize(-100,-100,1,3); if (score>best_score) best_score = score; unsigned int yt = (Hi-text1.height())/2-20; (img/=2).draw_image((Wi-text1.width())/2,yt,text1,text1.get_dilate(7),1,255); yt+=80; if (text2) { img.draw_image((Wi-text2.width())/2,yt,text2,text2.get_dilate(5),1,255); yt+=25; } img.draw_image((Wi-text3.width())/2,yt,text3,text3.get_dilate(5),1,255). draw_image((Wi-text4.width())/2,yt+25,text4,text4.get_dilate(5),1,255). draw_image((Wi-text5.width())/2,yt+50,text5,text5.get_dilate(5),1,255). draw_image((Wi-text6.width())/2,yt+75,text6,text6.get_dilate(5),1,255).display(disp); for (disp.flush(); !disp.is_closed() && !disp.key() && !disp.button(); disp.wait()) if (disp.is_resized()) disp.resize(disp); disp.flush(); board.assign(); for (float i = 10; i>0 && !disp.is_keyESC(); i-=0.25) disp.display(img.get_crop((int)(Wi*(0.5f-i*i*i*i/20000.0f)),(int)(Hi*(0.5f-i*i/200.0f)), (int)(Wi*(0.5f+i*i*i*i/20000.0f)),(int)(Hi*(0.5f+i*i/200.0f)))).wait(20); } }
static int ph_dct_imagehash(CImg<uint8_t> src, ulong64 &hash) { CImg<float> meanfilter(7,7,1,1,1); CImg<float> img; if (src.spectrum() == 3){ img = src.RGBtoYCbCr().channel(0).get_convolve(meanfilter); } else if (src.spectrum() == 4){ int width = img.width(); int height = img.height(); int depth = img.depth(); img = src.crop(0,0,0,0,width-1,height-1,depth-1,2).RGBtoYCbCr().channel(0).get_convolve(meanfilter); } else { img = src.channel(0).get_convolve(meanfilter); } img.resize(32,32); CImg<float> *C = ph_dct_matrix(32); CImg<float> Ctransp = C->get_transpose(); CImg<float> dctImage = (*C)*img*Ctransp; CImg<float> subsec = dctImage.crop(1,1,8,8).unroll('x');; float median = subsec.median(); ulong64 one = 0x0000000000000001; hash = 0x0000000000000000; for (int i=0;i< 64;i++){ float current = subsec(i); if (current > median) hash |= one; one = one << 1; } delete C; return 0; }
int main(int argc, char ** argv){ BallFinder finder; unsigned char green[3] = {0,255,0}; CImg<UINT8> image; CImg<UINT8> orig; stringstream ss; string imageNum; vector<circle> circles; vector<outline> outlines; circle c; for (int i = 1; i <= 68; i++){ ss << i; ss >> imageNum; ss.clear(); image.load_jpeg(("../TestImages/Image-" + imageNum + ".jpg").c_str()); orig = image; image = finder.threshhold(image); image.save_jpeg(("../threshholdOutputImages/ThreshedImage-" + imageNum + ".jpg").c_str()); image.blur(image.width()/100); //minimal blurring needed for red, width/200 for blue image.save_jpeg(("../blurredOutputImages/BlurredImage-" + imageNum + ".jpg").c_str()); image = finder.booleanEdgeDetect(image); image.save_jpeg(("../edgedOutputImages/EdgedImage-" + imageNum + ".jpg").c_str()); outlines = finder.findOutlines(image); circles.clear(); for (unsigned int i = 0; i < outlines.size(); ++i){ c = outlines[i].isCircle(image.width()); if (c.r != -1){ circles.push_back(c); } } for (unsigned int i = 0; i < circles.size(); i++){ orig.draw_circle((int)circles[i].x,(int)circles[i].y,(int)circles[i].r, green, 0.5); } orig.save_jpeg(("../circleOutputImages/CircleImage-" + imageNum + ".jpg").c_str()); } return 0; }
int main(int argc, char *argv[]) { NSTimer total = NSTimer("total", false, false); if ( argc != 2 ) { cerr << "Usage: " << argv[0] << " <filename>" << endl; return 1; } // Load the input image CImg< unsigned char > inputImage = CImg< unsigned char >(argv[1]); if ( displayImages ) { inputImage.display("Input Image"); } if ( inputImage.spectrum() != 3 ) { cerr << "The input must be a color image." << endl; return 1; } cout << argv[1] << " = " << inputImage.width() << " X " << inputImage.height()<< endl; //Image is loaded, start timing total.start(); // Convert the input image to grayscale CImg< unsigned char > grayImage = CImg< unsigned char >(inputImage.width(), inputImage.height(), 1, 1); rgb2gray(inputImage.data(), grayImage.data(), inputImage.width(), inputImage.height(), total); total.stop(); if ( displayImages ) { grayImage.display("Grayscale Image"); } if ( saveAllImages ) { grayImage.save("./grayscale.bmp"); } total.start(); // Compute 1D histogram CImg< unsigned char > histogramImage = CImg< unsigned char >(BAR_WIDTH * HISTOGRAM_SIZE, HISTOGRAM_SIZE, 1, 1); unsigned int *histogram = new unsigned int [HISTOGRAM_SIZE]; histogram1D(grayImage.data(), histogramImage.data(), grayImage.width(), grayImage.height(), histogram, HISTOGRAM_SIZE, BAR_WIDTH, total); total.stop(); if ( displayImages ) { histogramImage.display("Histogram"); } if ( saveAllImages ) { histogramImage.save("./histogram.bmp"); } total.start(); // Contrast enhancement contrast1D(grayImage.data(), grayImage.width(), grayImage.height(), histogram, HISTOGRAM_SIZE, CONTRAST_THRESHOLD, total); total.stop(); if ( displayImages ) { grayImage.display("Contrast Enhanced Image"); } if ( saveAllImages ) { grayImage.save("./contrast.bmp"); } total.start(); delete [] histogram; // Triangular smooth (convolution) CImg< unsigned char > smoothImage = CImg< unsigned char >(grayImage.width(), grayImage.height(), 1, 1); triangularSmooth(grayImage.data(), smoothImage.data(), grayImage.width(), grayImage.height(), filter, total); // Job done, stop timing total.stop(); if ( displayImages ) { smoothImage.display("Smooth Image"); } smoothImage.save("./smooth.bmp"); // Wrap up cout << fixed << setprecision(6) << endl; cout << "Execution time: \t\t" << total.getElapsed() << " seconds." << endl << endl; return 0; }
int main(int argc, char **argv) { // Getting the sample const std::string fileLocation(""); const std::string filename("./img/firstSample.bmp"); const CImg<> origin((fileLocation + filename).c_str()); // Clusters initializing CImgList<> clusters(nbCluster, origin.width(), origin.height(), 1,1, 1.0 / float(nbCluster) ); CImgList<> clustersSave(clusters); // sauvegarde de l'itération précédente pour le critaire d'arrêt. CImgList<> influence(clusters); std::vector<float> nu(nbCluster, 122); float valueInit = 255 / nbCluster; for(unsigned int i = 0; i < nbCluster; ++i) { nu[i] = valueInit * i; } std::cout << EPSILON << std::endl; CImgDisplay disp(origin,"Input Image"); unsigned int sizeBuffer = origin.width() * origin.height(); auto euclidianDistance = make_EuclidianDistance<float>(nbCluster); auto kernel = make_kernel(euclidianDistance,sigma); auto kfcm = make_KFCM<float>(kernel, fuzzyCoef); //On definit l'epsilon comme très grande valeur float epsilon = std::numeric_limits<float>::max(); //Boucle principale for(unsigned int t = 0 ; epsilon > EPSILON && t < tMax; ++t) { // mise à jour des nu for(unsigned int i = 0; i < nbCluster; ++i) { // iteration sur les clusters float* ptrCluster = clusters(i).data(); const float* ptrOrigin = origin.data(); float denomi = 0; float nume = 0; for( unsigned int k = 0; k < sizeBuffer; ++k ){ // iteration sur les pixels float computedKernel = std::pow(*(ptrCluster + k), fuzzyCoef) * kernel(*(ptrOrigin + k), nu[i]); denomi += computedKernel; nume += computedKernel * *(ptrOrigin + k); } assert(denomi != 0); nu[i] = nume / denomi; std::cout<<"Nu i : " <<i << " : " << nu[i] << std::endl; } double wall0 = get_wall_time(); double cpu0 = get_cpu_time(); // mise à jour des clusters const float* ptrOrigin = origin.data(); /* for( unsigned int k = 0; k < tailleBuffer; ++k){ // iteration sur les pixels float denomi = 0; for(unsigned int j = 0; j < nbCluster; ++j){ // calcul de dénominateur nécessitant une sommation pour toutes les classes denomi += std::pow(1 - kernel(*(ptrOrigin + k), nu[j]), -1/(fuzzyCoef-1)); } assert(denomi != 0); for(unsigned int i = 0; i < nbCluster; ++i){ // calcul pour chaque classe *(clusters(i).data() + k) = std::pow(1 - kernel(*(ptrOrigin + k), nu[i]),-1/(fuzzyCoef-1) ) / denomi; } } */ for(unsigned int i = 0; i < nbCluster; ++i){ CImg_3x3(I,float); cimg_for3x3(clustersSave(i),x,y,0,0,I,float) { float intermediate = 0; for(unsigned int l = 0; l < nbNeighbors + 1; ++l){ intermediate += std::pow((1-I[i]), fuzzyCoef); } intermediate -= std::pow((1-Icc), fuzzyCoef); // float intermediate = std::pow(1-Ipp, fuzzyCoef); // intermediate += std::pow(1-Ipc, fuzzyCoef); // intermediate += std::pow(1-Ipn, fuzzyCoef); // intermediate += std::pow(1-Ipc, fuzzyCoef); // intermediate += std::pow(1-Icp, fuzzyCoef); // intermediate += std::pow(1-Ipn, fuzzyCoef); // intermediate += std::pow(1-Icn, fuzzyCoef); // intermediate += std::pow(1-Inn, fuzzyCoef); influence(i)(x,y) = ( alpha / (float)nbNeighbors ) * intermediate; } } std::vector<float> neighborInfluence(nbCluster); std::vector<float> Uik; for( unsigned int k = 0; k < sizeBuffer; ++k){ // iteration sur les pixels for(unsigned int i = 0; i < nbCluster; ++i){ neighborInfluence.push_back(*(*(influence.data(i)) + k)); } Uik = kfcm.updateClusters(*(ptrOrigin + k), nu, neighborInfluence); for(unsigned int i = 0; i < nbCluster; ++i){ // calcul pour chaque classe *(clusters(i).data() + k) = Uik[i]; } neighborInfluence.clear(); } double wall1 = get_wall_time(); double cpu1 = get_cpu_time(); std::cout << "Wall Time = " << wall1 - wall0 << std::endl; std::cout << "CPU Time = " << cpu1 - cpu0 << std::endl; //TODO : ameliorer le calcul de somme des différences pour l'EPSILON //Filtre des clusters //Operation de tri des pixels : un pixel de Uik n'appartient en fin de boucle qu'à un seul cluster for(unsigned int k = 0; k < sizeBuffer; ++k){ unsigned int clusterOwner = 0; float max = 0; for(unsigned int i = 0; i < nbCluster; ++i){ // iteration sur les classes // iteration sur les pixels float * pixel = (clusters(i).data() + k); float value = *pixel; if( value > max) { max = value; clusterOwner = i; } *pixel = 0; } *(clusters(clusterOwner).data() + k) = 255; } // Fixed : critère d'arrêt correct epsilon = std::abs(*(clusters(0).data())) - *(clustersSave(0).data()); for(unsigned int k = 0; k < sizeBuffer; ++k){ for(unsigned int i = 0; i < nbCluster; ++i){ // iteration sur les classes epsilon = std::max(epsilon, std::abs(*(clusters(i).data() + k)) - *(clustersSave(i).data() + k)) ; } } // epsilon /= 255; clustersSave = clusters; std::cout << "T : " << t << " Epsilon : " <<epsilon<< std::endl; } while (!disp.is_closed()) { disp.wait(); } CImgDisplay disp2(clusters(0),"Input Image"); while (!disp2.is_closed()) { disp2.wait(); } CImgDisplay disp3(clusters(1),"Input Image"); while (!disp3.is_closed()) { disp3.wait(); } std::cout << "End"<<std::endl; return 1; }
void display3D(CImg<T> image, const char *file_o,const float ratioz,const unsigned int di, const char *file_pose_i,const char *file_pose_o, unsigned int rtype,bool color_type) { std::cout<<"display image as 3D surface"<<std::flush; const CImg<unsigned char> norm=image.get_norm().normalize(0,255); // Compute surface with triangles. std::fprintf(stderr,"\n- Create image surface"); std::fflush(stderr); CImgList<unsigned int> primitives; ////image colors CImgList<unsigned char> colors; const CImg<> points = image.get_elevation3d(primitives,colors,norm*-ratioz); ////constant colors CImgList<unsigned char> colors2; colors2=colors; cimglist_for(colors2,l) colors2(l).fill(255);//white // Compute image isophotes. std::fprintf(stderr,"\n- Compute image isophotes"); std::fflush(stderr); CImgList<unsigned int> isoprimitives; ////image colors CImgList<unsigned char> isocolors; CImg<> isopoints; for (unsigned int i = 0; i<255; i+=di) { CImgList<> prims; const CImg<> pts = norm.get_isoline3d(prims,(float)i); isopoints.append_object3d(isoprimitives,pts,prims); } cimglist_for(isoprimitives,l) { const unsigned int i0 = isoprimitives(l,0); const float x0 = isopoints(i0,0), y0 = isopoints(i0,1); const unsigned char r = (unsigned char)image.linear_atXY(x0,y0,0), g = (unsigned char)image.linear_atXY(x0,y0,1), b = (unsigned char)image.linear_atXY(x0,y0,2); isocolors.insert(CImg<unsigned char>::vector(r,g,b)); } cimg_forX(isopoints,l) isopoints(l,2) = -ratioz*norm.linear_atXY(isopoints(l,0),isopoints(l,1)); ////constant colors CImgList<unsigned char> isocolors2; isocolors2=isocolors; cimglist_for(isocolors2,l) isocolors2(l).fill(255);//white // Save object if necessary if (file_o) { std::fprintf(stderr,"\n- Save 3d object as '%s'",cimg::basename(file_o)); std::fflush(stderr); points.save_off(primitives,colors,file_o); } //display GUI information std::fprintf(stderr, "\n- Enter interactive loop.\n\n" "GUI reminder: \n" " + Use mouse to rotate and zoom object\n" " + key 'F' : toggle Fullscreen\n" " + key 'Q' or 'ESC' : Quit (i.e. exit)\n" " load or save file:\n" " + key 'S' : Save displayed image (i.e. 3D view)\n" " + key 'O' : save pOse (i.e. 3D view parameters)\n" " + key 'R' : Read pose (i.e. 3D view parameters)\n" " render type:\n" " + key 'C' : color render (image or constant)\n" " + key 'T' : poinTs render\n" " + key 'L' : Lines render\n" " + key 'A' : fAces render\n" " + key 'H' : flat-sHaded faces render\n" " + key 'G' : Gouraud-shaded faces render\n" " + key 'P' : Phong-shaded faces render\n" " + key 'I' : Isophotes render\n" " + key 'BackSpace' : change rendering type (i.e. decrement type)\n" " + Any other key : change rendering type (i.e. increment type)\n\n" ); std::fflush(stderr); const char *const title = "Image viewed as a surface"; CImgDisplay disp(800,600,title,0); CImg<float> pose=CImg<float>::identity_matrix(4); //load pose if set if(file_pose_i) { std::cerr<<"- read pose from file \""<<file_pose_i<<"\"\n"<<std::flush; pose.load(file_pose_i); } //pose.print("pose");std::cerr<<std::flush; //GUI loop while (!disp.is_closed()) { const unsigned char text_color[3]= {123,234,234}; CImg<unsigned char> visu(disp.width(),disp.height(),1,3,0); visu.draw_text(10,10,"%s",text_color,0,1,24, rtype==0?"Points (0,T)":(rtype==1?"Lines (1,L)":(rtype==2?"Faces (2,A)":(rtype==3?"Flat-shaded faces (3,H)": (rtype==4?"Gouraud-shaded faces (4,G)":(rtype==5?"Phong-shaded faces (5,P)":"Isophotes (6,I)")))))); static bool first_time=(file_pose_i)?false:true; if (rtype==6) visu.display_object3d(disp,isopoints,isoprimitives,(color_type)?isocolors:isocolors2,first_time,1,-1,true, 500.0f,0.0f,0.0f,-5000.0f,0.0f,0.0f,true,pose.data()); else visu.display_object3d(disp,points,primitives,(color_type)?colors:colors2,first_time,rtype,-1,true, 500.0f,0.0f,0.0f,-5000.0f,0.0f,0.0f,true,pose.data()); first_time=false; //pose.print("pose");std::cerr<<std::flush; switch (disp.key()) { case 0: break; case cimg::keyBACKSPACE: rtype=(7+rtype-1)%7; break; case cimg::keyQ: case cimg::keyESC: disp.close(); break; //fullscreen display or not case cimg::keyF: if (disp.is_fullscreen()) disp.resize(800,600); else disp.resize(disp.screen_width(),disp.screen_height()); disp.toggle_fullscreen(); break; //save display case cimg::keyS: { std::string file_tmp="CImg_surface3D.png"; std::cerr<<"saving display as image in \""<<file_tmp<<"\".\n"<<std::flush; CImg<unsigned char> tmp; disp.snapshot(tmp); tmp.save(file_tmp.c_str()); } break; //save pose case cimg::keyO: { std::cerr<<"saving pose in file \""<<file_pose_o<<"\".\n"<<std::flush; pose.save(file_pose_o); } break; //load pose case cimg::keyR: { std::cerr<<"loading pose from file \""<<file_pose_i<<"\".\n"<<std::flush; pose.load(file_pose_i); } break; //display type case cimg::keyC: color_type=(color_type)?false:true; break;//color type case cimg::keyT: rtype=0; break;//poinTs case cimg::keyL: rtype=1; break;//Lines case cimg::keyA: rtype=2; break;//fAces case cimg::keyH: rtype=3; break;//flat-sHaded faces case cimg::keyG: rtype=4; break;//Gouraud-shaded faces case cimg::keyP: rtype=5; break;//Phong-shaded faces case cimg::keyI: rtype=6; break;//Isophotes default: rtype = (rtype+1)%7; break; }//Key switch }//GUI loop }
void display1D2D(CImg<T> image) { //convert image to RGB image.resize(-100,-100,1,3); // Create two display window, one for the image, the other for the color profile. CImgDisplay main_disp(image,"Color image (Click on mouse buttons: left and right)",0), draw_disp(image.width(),512,"Color profile along X or Y axis",0); bool refresh_draw=true; // button, X and Y-coordinate of the mouse pointer over the image int bm,xm,ym; bm=xm=ym=0; // Define colors used to plot the profile, and a hatch to draw the vertical line unsigned long hatch = 0xF0F0F0F0; const unsigned char // R G B red[] = {255, 0, 0}, green[] = { 0,255, 0}, blue [] = { 0, 0,255}, black[] = { 0, 0, 0}, white[] = {255,255,255}; //display and post process image as color or grey scale CImg<unsigned char> image_pp(image); //event loop //This loop ends when one of the two display window is closed or when the keys 'ESC' or 'Q' are pressed. while(!main_disp.is_closed() && !draw_disp.is_closed() && !main_disp.is_keyESC() && !draw_disp.is_keyESC() && !main_disp.is_keyQ() && !draw_disp.is_keyQ()) { // Handle display window resizing (if any) if (main_disp.is_resized()) main_disp.resize().display(image); draw_disp.resize(); //key board if(main_disp.is_keyC()||main_disp.is_keyV()||main_disp.is_keyL()||main_disp.is_keyI()) { PR(main_disp.key()); //post process image (color or grey scale) switch(main_disp.key()) { //RGB color case 'c': { main_disp.set_title("Color image (Click on mouse buttons: left and right)"); std::cout<<"\rswitch to color image. "<<std::flush; image_pp=image; } break; //convert to grey level case 'v': case 'l': case 'i': { CImg<unsigned char> grey_level; main_disp.set_title("Grey level image (Click on mouse buttons: left and right)"); std::cout<<"\rswitch to grey level image based on "; switch(main_disp.key()) { case 'v': std::cout<<"value. "; grey_level=image.get_RGBtoHSV().get_channel(2)*255; break; case 'l': std::cout<<"lightness."; grey_level=image.get_RGBtoHSL().get_channel(2)*255; break; case 'i': std::cout<<"intensity."; grey_level=image.get_RGBtoHSI().get_channel(2)*255; break; }//switch grey std::cout<<std::flush; cimg_forC(image_pp,c) image_pp.get_shared_channel(c)=grey_level; } break; }//switch color or grey //display new image image_pp.display(main_disp); //reset key buffer main_disp.set_key(); refresh_draw=true; } //mouse button if(main_disp.button()!=0) { PR(main_disp.button()); PR(main_disp.mouse_x()); PR(main_disp.mouse_y()); if(main_disp.mouse_x()>=0 && main_disp.mouse_y()>=0) { // Mouse pointer is over the image bm=main_disp.button(); // button of the mouse over the image xm=main_disp.mouse_x();// X-coordinate of the mouse pointer over the image ym=main_disp.mouse_y();// Y-coordinate of the mouse pointer over the image refresh_draw=true; } else { // else display a text in the profile display window. CImg<unsigned char>(draw_disp.width(),draw_disp.height()).fill(255). draw_text(draw_disp.width()/2-110,draw_disp.height()/2-5,"Mouse pointer is outside the image",black). display(draw_disp); } } //draw graphs in draw display if(refresh_draw) { PR(refresh_draw); const int xl=xm*draw_disp.width()/main_disp.width(),// Corresponding X-coordinate of the hatched line x =xm*image.width()/main_disp.width(), // Corresponding X-coordinate of the pointed pixel in the image y =ym*image.height()/main_disp.height(); // Corresponding Y-coordinate of the pointex pixel in the image // Retrieve color component values at pixel (x,y) const unsigned int val_red = image_pp(x,y,0), val_green = image_pp(x,y,1), val_blue = image_pp(x,y,2); if(bm==1) { //display actual line on main display CImg<unsigned char>(image_pp). draw_line(0,ym,main_disp.width()-1,ym,white,0.5f,hatch=cimg::rol(hatch)). display(main_disp); //Create and display the graph of the intensity profile int width=image.width(),height=draw_disp.height(); draw_disp.set_title("Color profile along X axis").resize(width,height,true); CImg<unsigned char>(width,height,1,3,255). draw_grid(-50*100.0f/width,-50*100.0f/256,0,0,false,true,black,0.2f,0xCCCCCCCC,0xCCCCCCCC). draw_axes(0,image.width()-1.0f,255.0f,0.0f,black). draw_graph(image_pp.get_shared_row(y,0,0),red,1,1,0,255,1). draw_graph(image_pp.get_shared_row(y,0,1),green,1,1,0,255,1). draw_graph(image_pp.get_shared_row(y,0,2),blue,1,1,0,255,1). draw_text(30,5,"Pixel (%d,%d)={%d %d %d}",black,0,1,13,xm,ym,val_red,val_green,val_blue). draw_line(xl,0,xl,draw_disp.height()-1,black,0.5f,hatch=cimg::rol(hatch)). display(draw_disp); }//bm==1 if(bm==2) { //display actual line on main display CImg<unsigned char>(image_pp). draw_line(xm,0,xm,main_disp.height()-1,white,0.5f,hatch=cimg::rol(hatch)). display(main_disp); //Create and display the graph of the intensity profile int width=image.height(),height=draw_disp.height(); draw_disp.set_title("Color profile along Y axis").resize(width,height,true); CImg<unsigned char>(width,height,1,3,255). draw_grid(-50*100.0f/width,-50*100.0f/256,0,0,false,true,black,0.2f,0xCCCCCCCC,0xCCCCCCCC). draw_axes(0,image.height()-1.0f,255.0f,0.0f,black). draw_graph(image_pp.get_crop(x,0,0,0,x,image.height()-1,0,0),red,1,1,0,255,1).//red graph draw_graph(image_pp.get_crop(x,0,0,1,x,image.height()-1,0,1),green,1,1,0,255,1).//green graph draw_graph(image_pp.get_crop(x,0,0,2,x,image.height()-1,0,2),blue,1,1,0,255,1).//blue graph draw_text(30,5,"Pixel (%d,%d)={%d %d %d}",black,0,1,13,xm,ym,val_red,val_green,val_blue).//actual position and RGB as text draw_line(xl,0,xl,draw_disp.height()-1,black,0.5f,hatch=cimg::rol(hatch)). display(draw_disp); }//bm==2 refresh_draw=false; }//draw window // Temporize event loop cimg::wait(20); }//event loop }