📄 cimg_demo.cpp
字号:
case 13: { // Oriented convolutions //----------------------- const CImg<unsigned char> img = CImg<unsigned char>("img/sh0r.pgm").noise(50,2); CImg<float> mask(16,16); CImgList<unsigned char> visu = img<<img<<img; const float value = 255; CImgDisplay disp(visu,"Original image, Oriented kernel and Convolved image",0,1); for (float angle=0; !disp.is_closed && disp.key!=cimg::keyQ && disp.key!=cimg::keyESC; angle+=0.1f) { const float ca = (float)cos(angle), sa = (float)sin(angle); const CImg<> u = CImg<>::vector(ca,sa), v = CImg<>::vector(-sa,ca), tensor = 30*u*u.get_transpose() + 2*v*v.get_transpose(); mask.draw_gaussian(0.5f*mask.dimx(),0.5f*mask.dimy(),tensor,&value); mask/=mask.sum(); visu[1] = mask.get_resize(img).normalize(0,255). draw_text(2,2,&value,0,11,1,"Angle = %d deg",cimg::mod((int)(angle*180/cimg::PI),360)); visu[2] = img.get_convolve(mask); disp.resize(disp.window_dimx(),(int)(disp.dimy()*disp.window_dimx()/disp.dimx()),false). display(visu).wait(25); } } break; case 14: { // Shade bobs //------------ CImg<unsigned char> img(300,300,1,1,0), palette; CImgDisplay disp(img,"Shade Bobs"); float t=100, rx=0, ry=0, rz=0, rt=0, rcx=0; const unsigned char one = 1; int nbbobs = 0, rybobs = 0; while (!disp.is_closed && disp.key!=cimg::keyESC && disp.key!=cimg::keyQ) { if ((t+=0.015f)>4*cimg::PI) { img.fill(0); rx=(float)(cimg::crand()); ry=(float)(cimg::crand()); rz=(float)(cimg::crand()); rt=(float)(cimg::crand()); rcx = 0.6f*(float)(cimg::crand()); t=0; palette = CImg<unsigned char>(3,4+(int)(12*cimg::rand()),1,1,0).noise(255,2).resize(3,256,1,1,3); palette(0)=palette(1)=palette(2)=0; nbbobs = 20+(int)(cimg::rand()*80); rybobs = (10+(int)(cimg::rand()*50))*cimg::min(img.dimx(),img.dimy())/300; disp.key = disp.button = 0; } for (int i=0; i<nbbobs; i++) { const float r = (float)(ry + rx*cos(6*rz*t) + (1-rx)*sin(6*rt*t)), a = (float)((360*sin(rz*t)+30*ry*i)*cimg::PI/180), ax = (float)(i*2*cimg::PI/nbbobs+t); const int cx = (int)((1+rcx*cos(ax)+r*cos(a))*img.dimx()/2), cy = (int)((1+rcx*sin(ax)+r*sin(a))*img.dimy()/2); img.draw_circle(cx,cy,(float)rybobs,&one,0L,-1.0f); } CImg_3x3(I,unsigned char); CImg<unsigned char> tmp(img); cimg_for3x3(tmp,x,y,0,0,I) img(x,y) = (Inc+Ipc+Icn+Icp+(Icc<<2))>>3; CImg<unsigned char> visu(img.dimx(),img.dimy(),1,3); cimg_forXY(visu,xx,yy) { const unsigned char *col = palette.ptr(0,img(xx,yy)); visu(xx,yy,0) = *(col++); visu(xx,yy,1) = *(col++); visu(xx,yy,2) = *(col++); } disp.display(visu).wait(25); if (disp.is_typed(cimg::keyCTRLLEFT,cimg::keyF)) disp.resize(disp.is_fullscreen?300:640,disp.is_fullscreen?300:480).toggle_fullscreen(); if (disp.is_resized) img.resize(disp.resize(false),3); if ((disp.key && disp.key!=cimg::keyCTRLLEFT) || disp.button) t=70; } } break; case 15: { // Fourier Filtering //------------------- const CImg<unsigned char> img = CImg<unsigned char>("img/lena.pgm").resize(256,256); CImgList<> F = img.get_FFT(); cimglist_apply(F,translate)(img.dimx()/2,img.dimy()/2,0,0,2); const CImg<unsigned char> mag = ((F[0].get_pow(2) + F[1].get_pow(2)).sqrt()+1.0f).log().normalize(0,255); CImgList<unsigned char> visu(img,mag); CImgDisplay disp(visu,"Fourier Filtering"); CImg<unsigned char> mask(img.dimx(),img.dimy(),1,1,1); unsigned char one[1] = { 1 }, zero[1] = { 0 }, white[1]={255}; float rmin = 0, rmax = 256; while (!disp.is_closed && disp.key!=cimg::keyQ && disp.key!=cimg::keyESC) { disp.wait(); const int xm = disp.mouse_x-img.dimx(), ym = disp.mouse_y, x = xm-img.dimx()/2, y = ym-img.dimy()/2; if (disp.button && xm>=0 && ym>=0) { const float r = cimg::max(0.0f,(float)sqrt((float)x*x+y*y)-3.0f); if (disp.button&1) rmax = r; if (disp.button&2) rmin = r; if ((int)rmin>=(int)rmax) rmin = cimg::max(rmax-1.0f,0.0f); mask.fill(0).draw_circle(mag.dimx()/2,mag.dimy()/2,(float)rmax,one). draw_circle(mag.dimx()/2,mag.dimy()/2,(float)rmin,zero); CImgList<> nF(F); cimglist_for(F,l) nF[l].mul(mask).translate(-img.dimx()/2,-img.dimy()/2,0,0,2); visu[0] = nF.FFT(true)[0].normalize(0,255); } if (disp.is_resized) disp.resize(disp); visu[1] = mag.get_mul(mask).draw_text(5,5,white,zero,11,0.6f,"Freq Min/Max = %d / %d",(int)rmin,(int)rmax); visu.display(disp); } } break; case 16: { // Image Zoomer //-------------- const CImg<unsigned char> img("img/logo.ppm"); CImgDisplay disp(img,"Original Image",0,3), dispz(300,300,"Zoomed Image",0,3); disp.move((CImgDisplay::screen_dimx()-dispz.dimx())/2,(CImgDisplay::screen_dimy()-dispz.dimy()-disp.dimy())/2); dispz.move(disp.window_x,disp.window_y + disp.window_height + 40); int factor = 20,x=0,y=0; bool grid = false, redraw = false; while (!disp.is_closed && !dispz.is_closed && disp.key!=cimg::keyQ && dispz.key!=cimg::keyQ && disp.key!=cimg::keyESC && dispz.key!=cimg::keyESC ) { if (disp.mouse_x>=0) { x = disp.mouse_x; y = disp.mouse_y; redraw = true; } if (redraw) { const int x0 = x-factor, y0 = y-factor, x1 = x+factor, y1 = y+factor; const unsigned char red[3] = { 255,0,0 }, black[3] = { 0,0,0 }, white[3] = { 255,255,255 }; (+img).draw_line(x0,y0,x1,y0,red).draw_line(x1,y0,x1,y1,red). draw_line(x1,y1,x0,y1,red).draw_line(x0,y1,x0,y0,red).display(disp); CImg<unsigned char> visu = img.get_crop(x0,y0,x1,y1).draw_point(x-x0,y-y0,red,0.2f).resize(dispz); if (grid) { const int bfac = 2*factor+1; for (int i=0; i<bfac; i++) { const int X = i*dispz.dimx()/bfac, Y = i*dispz.dimy()/bfac; visu.draw_line(X,0,X,dispz.dimy()-1,black).draw_line(0,Y,dispz.dimx()-1,Y,black); } } visu.draw_text(2,2,white,0,11,1.0f,"Coords (%d,%d)",x,y).display(dispz); } if (disp.button&1) { factor=(int)(factor/1.5f); if (factor<5) factor = 5; disp.button=0; redraw = true; } if (disp.button&2) { factor=(int)(factor*1.5f); if (factor>40) factor = 40; disp.button=0; redraw = true; } if (disp.button&4 || dispz.button) { grid = !grid; disp.button = dispz.button = 0; redraw = true; } if (disp.is_resized) disp.resize(disp); if (dispz.is_resized) { dispz.resize(); redraw = true; } CImgDisplay::wait(disp,dispz); } } break; case 17: { // Blobs Editor //-------------- CImg<unsigned int> img(300,300,1,3); CImgList<unsigned int> colors; CImgList<> blobs; CImgDisplay disp(img,"Blobs Editor",0); bool moving = false; unsigned int white[3] = { 255,255,255 }; for (float alpha=0; !disp.is_closed && disp.key!=cimg::keyESC && disp.key!=cimg::keyQ; alpha+=0.1f) { const int xm = disp.mouse_x*img.dimx()/disp.dimx(), ym = disp.mouse_y*img.dimy()/disp.dimy(); int selected = -1; img.fill(0); if (!blobs.is_empty()) { float dist=0, dist_min = (float)img.dimx()*img.dimx() + img.dimy()*img.dimy(); cimglist_for(blobs,l) { const CImg<>& blob = blobs[l]; const float xb = blob[0], yb = blob[1], rb = blob[2], sigma = (float)(rb*(1+0.05f*cos(blob[3]*alpha))), sigma2 = 2*sigma*sigma, precision = 4.5f*sigma2; const int tx0 = (int)(xb-3*sigma), ty0 = (int)(yb-3*sigma), tx1 = (int)(xb+3*sigma), ty1 = (int)(yb+3*sigma); const unsigned int col1 = colors[l](0), col2 = colors[l](1), col3 = colors[l](2), wh = img.dimx()*img.dimy(), x0 = tx0<0?0:tx0, y0 = ty0<0?0:ty0, x1 = tx1>=img.dimx()?(img.dimx()-1):tx1, y1 = ty1>=img.dimy()?(img.dimy()-1):ty1; float dy = y0-yb; unsigned int *ptr = img.ptr(x0,y0); for (unsigned int y=y0; y<=y1; y++) { float dx = x0-xb; for (unsigned int x=x0; x<=x1; x++) { float dist = dx*dx + dy*dy; if (dist<precision) { const float val = (float)exp(-dist/sigma2); *ptr += (unsigned int)(val*col1); *(ptr+wh) += (unsigned int)(val*col2); *(ptr+2*wh) += (unsigned int)(val*col3); } ++dx; ++ptr; } ptr+=img.dimx()-(x1-x0)-1; ++dy; } if ((dist=(xb-xm)*(xb-xm)+(yb-ym)*(yb-ym))<dist_min) { dist_min = dist; selected = l; } } for (unsigned int *ptr1 = img.ptr(0,0,0,1), *ptr2 = img.ptr(0,0,0,2), *ptr3 = img.ptr(img.size()-1)+1, off=0, wh=img.dimx()*img.dimy(); ptr1>img.data; off++) { unsigned int val1 = *(--ptr1), val2 = *(--ptr2), val3 = *(--ptr3); const unsigned int pot = val1*val1 + val2*val2 + val3*val3; if (pot<128*128) { *ptr1=*ptr3=255*off/wh; *ptr2=180*off/wh; } else { if (pot<140*140) { *ptr1>>=1; *ptr2>>=1; *ptr3>>=1; } else { *ptr1 = val1<255?val1:255; *ptr2 = val2<255?val2:255; *ptr3 = val3<255?val3:255; } } } cimglist_for(blobs,ll) { const CImg<>& blob = blobs[ll]; const int rb = (int)(blob[2]*(1+0.05f*cos(blob[3]*alpha))), xb = (int)(blob[0]+rb/2.5f), yb = (int)(blob[1]-rb/2.5f); img.draw_circle(xb,yb,rb/2.0f,white,0,0.2f).draw_circle(xb,yb,rb/3.0f,white,0,0.2f). draw_circle(xb,yb,rb/5.0f,white,0,0.2f); } } else { CImg<unsigned int> text; text.draw_text("CImg Blobs Editor\n" "-----------------\n\n" "* Left mouse button :\n Create and Move Blobs.\n\n" "* Right mouse button :\n Remove nearest Blobs.\n\n" "* Colors and size of Appearing Blobs\n" " are randomly chosen.\n\n\n" " >> Press mouse button to start ! <<", 0,0,white); img.fill(100).draw_image(text,text,(img.dimx()-text.dimx())/2,(img.dimy()-text.dimy())/2,0,0,255U); } if (disp.mouse_x>=0 && disp.mouse_y>=0) { if (disp.button&1) { float dist_selected = 0; if (selected>=0) { const float a = xm-blobs[selected](0), b = ym-blobs[selected](1), c = blobs[selected](2); dist_selected = a*a+b*b-c*c; } if (moving || dist_selected<0) { blobs[selected](0) = (float)xm; blobs[selected](1) = (float)ym; } else { blobs.insert(CImg<>::vector((float)xm,(float)ym,(float)(10+30*cimg::rand()),(float)(3*cimg::rand()))); colors.insert(CImg<>(3).fill(0).noise(255,1).normalize(0,255)); } moving = true; } else moving = false; if (selected>=0 && disp.button&2) { blobs.remove(selected); colors.remove(selected); disp.button = 0; } } img.display(disp.wait(25)); if (disp.is_resized) { img.resize(disp.resize(false)); cimglist_for(blobs,l) if (blobs[l](0)>=img.dimx() || blobs[l](1)>=img.dimy()) { blobs.remove(l); colors.remove(l--); } } } } break; case 18: { // Double Torus //------------- CImg<unsigned char> visu(300,256,1,3,0); CImgDisplay disp(visu,"Double 3D Torus"); CImgList<> points, opacities; CImgList<unsigned int> primitives; CImgList<unsigned char> colors; const float a = 60, b = 20; const unsigned int na = 20, nb = 10; for (unsigned int v=0; v<na; v++) for (unsigned int u=0; u<nb; u++) { const float alpha = (float)(u*2*cimg::PI/nb), beta = (float)(v*2*cimg::PI/na), x = (float)((a+b*cos(alpha))*cos(beta)), y = (float)((a+b*cos(alpha))*sin(beta)), z = (float)(b*sin(alpha)); points.insert(CImg<>::vector(x,y,z)); } CImgList<> points2(points); const CImg<> rot0 = CImg<>::rotation_matrix(1,0,0,(float)cimg::PI/2), dx = CImg<>::vector(30,0,0); cimglist_for(points,l) { points2[l] = rot0*points[l] + dx; points[l]-=dx; } const unsigned int N = points.size; points.insert(points2); for (unsigned int vv=0; vv<na; vv++) for (unsigned int uu=0; uu<nb; uu++) { const int nv = (vv+1)%na, nu = (uu+1)%nb; primitives.insert(CImg<unsigned int>::vector(nb*vv+nu,nb*vv+uu,nb*nv+uu)); primitives.insert(CImg<unsigned int>::vector(nb*vv+nu,nb*nv+uu,nb*nv+nu)); primitives.insert(CImg<unsigned int>::vector(N+nb*vv+nu,N+nb*vv+uu,N+nb*nv+uu)); primitives.insert(CImg<unsigned int>::vector(N+nb*vv+nu,N+nb*nv+uu,N+nb*nv+nu)); colors.insert(CImg<>::vector(255,255,0)); colors.insert(CImg<>::vector(255,200,0)); colors.insert(CImg<>::vector(100,255,100)); colors.insert(CImg<>::vector(200,255,200)); opacities.insert(2,CImg<>(1,1,1,1,1.0f)); opacities.insert(2,CImg<>(1,1,1,1,0.3f)); } float alpha=0, beta=0, gamma=0, theta=0; while (!disp.is_closed && disp.key!=cimg::keyQ && disp.key!=cimg::keyESC) { visu.get_shared_channels(1,2).fill(0); visu.get_shared_line(visu.dimy()-1,0,0).noise(200,1); CImg_3x3(I,unsigned char); cimg_for3x3(visu,x,y,0,0,I) visu(x,y,0) = (Icc+Ipn+Icn+Inn)>>2; { for (unsigned int y=0; y<100; y++) memset(visu.ptr(0,y,0,2),255-y*255/100,visu.dimx()); } const CImg<> rot = CImg<>::rotation_matrix(1,1,0,(alpha+=0.01f))*CImg<>::rotation_matrix(1,0,1,(beta-=0.02f))* CImg<>::rotation_matrix(0,1,1,(gamma+=0.03f)); CImgList<> rpoints(points); cimglist_for(points,l) rpoints[l]=rot*points[l]; if (disp.is_resized) disp.resize(false); if (disp.is_typed(cimg::keyCTRLLEFT,cimg::keyF)) { disp.toggle_fullscreen(); if (disp.is_fullscreen) disp.resize(disp.screen_dimx(), disp.screen_dimy(),false);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -