Exemple #1
0
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;
}
Exemple #2
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);
	}

}
Exemple #10
0
// 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);
    }
  }
Exemple #11
0
    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;   
}
Exemple #13
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;
}
Exemple #14
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
}