// Imagine++ project // Project: Panorama // Author: Pascal Monasse // Date: 2013/10/08 #include #include #include #include #include using namespace Imagine; using namespace std; // Record clicks in two images, until right button click void getClicks(Window w1, Window w2, vector& pts1, vector& pts2) { IntPoint2 p; Window w; int sw; while(true) { if(anyGetMouse(p, w, sw) == 3) break; if (w==w1) pts1.push_back(p); else pts2.push_back(p); setActiveWindow(w); std::cout << "point clicked : " << p << std::endl; drawCircle(p, 5, RED); drawCircle(p, 4, GREEN); } } // Return homography compatible with point matches Matrix getHomography(const vector& pts1, const vector& pts2) { size_t n = min(pts1.size(), pts2.size()); if(n<4) { cout << "Not enough correspondences: " << n << endl; return Matrix::Identity(3); } Matrix A(2*n,8); Vector B(2*n); for(size_t ii=0; ii H(3, 3); H(0,0)=B[0]; H(0,1)=B[1]; H(0,2)=B[2]; H(1,0)=B[3]; H(1,1)=B[4]; H(1,2)=B[5]; H(2,0)=B[6]; H(2,1)=B[7]; H(2,2)=1; // Sanity check for(size_t i=0; i x1(v1,3); Vector x2(v2,3); x1 = H*x1; cout << x1[1]*x2[2]-x1[2]*x2[1] << ' ' << x1[2]*x2[0]-x1[0]*x2[2] << ' ' << x1[0]*x2[1]-x1[1]*x2[0] << endl; } return H; } // Grow rectangle of corners (x0,y0) and (x1,y1) to include (x,y) void growTo(float& x0, float& y0, float& x1, float& y1, float x, float y) { if(xx1) x1=x; if(yy1) y1=y; } // Panorama construction void panorama(const Image& I1, const Image& I2, Matrix H) { Vector v(3); float x0=0, y0=0, x1=I2.width(), y1=I2.height(); v[0]=0; v[1]=0; v[2]=1; v=H*v; v/=v[2]; growTo(x0, y0, x1, y1, v[0], v[1]); v[0]=I1.width(); v[1]=0; v[2]=1; v=H*v; v/=v[2]; growTo(x0, y0, x1, y1, v[0], v[1]); v[0]=I1.width(); v[1]=I1.height(); v[2]=1; v=H*v; v/=v[2]; growTo(x0, y0, x1, y1, v[0], v[1]); v[0]=0; v[1]=I1.height(); v[2]=1; v=H*v; v/=v[2]; growTo(x0, y0, x1, y1, v[0], v[1]); cout << "x0 x1 y0 y1=" << x0 << ' ' << x1 << ' ' << y0 << ' ' << y1< I(int(x1-x0), int(y1-y0)); setActiveWindow( openWindow(I.width(), I.height()) ); I.fill(WHITE); H = inverse(H); for(int ii=0; ii new_v = H*v; new_v /= new_v[2]; bool in_I2 = 0<=v[0] && v[0]1? argv[1]: srcPath("image0006.jpg"); const char* s2 = argc>2? argv[2]: srcPath("image0007.jpg"); // Load and display images Image I1, I2; if( ! load(I1, s1) || ! load(I2, s2) ) { cerr<< "Unable to load the images" << endl; return 1; } Window w1 = openWindow(I1.width(), I1.height(), s1); display(I1,0,0); Window w2 = openWindow(I2.width(), I2.height(), s2); setActiveWindow(w2); display(I2,0,0); // Get user's clicks in images vector pts1, pts2; getClicks(w1, w2, pts1, pts2); vector::const_iterator it; cout << "pts1="<