实现openCV方法warpPerspective()

时间:2017-11-26 21:34:41

标签: opencv transform panoramas image-stitching 360-panorama

我试图从头开始实现openCV方法warpPerspective(),我在下面编写代码,它可以处理y和x的移位但是,当我从findHomography()传递单应矩阵到我做的函数时,它总是给出空白与warpPerspective()输出相比较的图像。

我按照此定义查找像素的新位置:

[1.0340946, 0.032195676, -6.419126; 0.00302419, 1.0487343, -96.520393; 3.7013847e-06, 0.00010837225, 1]

我的映射适用于简单移位,如{1,0.5,-51,0,1,50,0,0,1} enter image description here

但矩阵如下: Mat transform(Mat A, Mat H) { // allocate array of all locations int Numrows = A.rows; int Numcols = A.cols; int channels = A.channels(); cout << "rows " << Numrows << "col " << Numcols << "channels " << channels <<endl; int size = Numrows*Numcols; int MaxX,MaxY = -1000; int MinX,MinY = 1000; int *TransArry = (int *)malloc(sizeof(int)*size); int Idx; int homeX=Idx % Numcols; int homeY=Idx / Numcols; cout << H << endl; waitKey(); for (Idx=0; Idx < size; ++Idx ){ homeX=Idx % Numcols; homeY=Idx / Numcols; float x = (H.at<float>(0,0) * (homeX)) +( H.at<float>(0,1) * (homeY)) + ( H.at<float>(0,2) * 1) ; float y = (H.at<float>(1,0) * (homeX)) +( H.at<float>(1,1) * (homeY)) + ( H.at<float>(1,2) * 1) ; float s = (H.at<float>(2,0) * (homeX)) +( H.at<float>(2,1) * (homeY)) + ( H.at<float>(2,2) * 1) ; cout << " x = " << x << " y= " << y << " s= " << s; x = (x/s); y = y/s; // for the first col in TransMatrix if (homeX ==0){ if (x > MaxX) MaxX = x; if (x < MinX) MinX = x; } //for thee first row in TransMatrix if (homeY ==0){ if (y > MaxY) MaxY = y; if (y < MinY) MinY = y; } if((y)>=A.rows || (y)<0 || (x)>=A.cols || (x)<0){ TransArry[Idx] = -1; cout << "x= " << x << "y= "<< y << endl; }else{ TransArry[Idx] = (y * Numcols + x); } //cout << Numcols << endl; cout << "New index of " << Idx << "is " << TransArry[Idx] << endl; } Mat tranImg ; A.copyTo(tranImg); tranImg = tranImg - tranImg; cout << "Rows" << tranImg.rows << "cols" << tranImg.cols << "cha" << A.channels() << endl; waitKey(); // Remap Image for (Idx=0; Idx < size; Idx ++ ){ homeX=Idx % Numcols; homeY=Idx / Numcols; //tranImg.at<uchar>(homeY, homeX) =0; if(TransArry[Idx] != -1){ //cout << "Index " << Idx << "Passed " << endl; int newhomeX=TransArry[Idx] % Numcols; // Col ID int newhomeY=TransArry[Idx] / Numcols; // Row ID cout << "Index is " << Idx << endl; cout << "HomeX is " << homeX << " and HomeY is " << homeY << endl; cout << "New Index is " << TransArry[Idx] << endl; cout << "New HomeX is " << newhomeX << " and New HomeY is " << newhomeY << endl; cout << "*****************************************"<< endl; // if (!(Idx%100)) sleep(20); tranImg.at<uchar>(newhomeY, (newhomeX*channels)) = A.at<uchar>(homeY, homeX*channels); if(channels>1) tranImg.at<uchar>(newhomeY, newhomeX*channels+1) = A.at<uchar>(homeY, homeX*channels+1); if(channels>2) tranImg.at<uchar>(newhomeY, newhomeX*channels+2) = A.at<uchar>(homeY, homeX*channels+2); // if (!(Idx%100)){ // imshow("inside", tranImg); // waitKey(1); // } } } //cout << tranImg << endl; return tranImg; } 输出是这样的: enter image description here

我的实施: - 给出H和图像A, - 在A中找到像素的新位置并将它们保存在TransArry中。其中数组的索引是A的线性化索引。 - 将A的像素重新映射到tranImg。

{{1}}

H被calaculated并验证。

那么,我访问矩阵H和A的方式是否存在问题?

1 个答案:

答案 0 :(得分:0)

我发现了问题。您使用的坐标是浮点值而不是整数。将x和y强制转换为整数,并将值x限制为floor(x / s)和y = floor(y / s)。