gpt4 book ai didi

opencv - 实现 openCV 方法 warpPerspective()

转载 作者:太空宇宙 更新时间:2023-11-03 21:32:56 27 4
gpt4 key购买 nike

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

我按照这个定义找到了像素的新位置:

s*x' h1 h2 h3 x
s*y' = h4 h5 h6 * y
s h7 h8 1 1

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

但是当矩阵是这样的:[1.0340946,0.032195676,-6.419126;
0.00302419、1.0487343、-96.5203​​93;
3.7013847e-06, 0.00010837225, 1]
输出是这样的: enter image description here

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

    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;

}

H 被计算和验证。

那么,我访问矩阵 H 和 A 的方式有问题吗?

最佳答案

看我的回答here它应该回答你的两个问题。这个答案仍然使用 warpPerspective() 但它可以全面了解如何计算单应性图像在图像边界外多远,因此您可以在图像的每一侧适本地填充。

至于手动执行 warpPerspective(),您需要做的就是将所有图像坐标放入线性化的齐次数组中并乘以单应性,然后除以最后一个坐标即可得到到笛卡尔坐标。然后,您可以使用 remap()做插值。 remap() 的语法可能会让人困惑,所以你可以引用我的回答 here了解如何使用它。 This answer shows a manual transformation and interpolation,它应该给你(至少几乎)与warpPerspective()相同的结果。

关于opencv - 实现 openCV 方法 warpPerspective(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47501249/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com