我对透视转换到鸟瞰图感兴趣。到目前为止,我已经尝试了getPerspectiveTransform和findHomography,然后将其传递给warpPerspective。结果非常接近,但TL和BR存在偏差。此外,contourArea在转换后不会平等转换。
轮廓是一个内部有多种形状的正方形。
有关如何继续的任何建议。
到目前为止我所做的代码块。
std::vector<Point2f> quad_pts;
std::vector<Point2f> squre_pts;
cv::approxPolyDP( Mat(validContours[largest_contour_index]), contours_poly[0], epsilon, true );
if (approx_poly.size() > 4) return false;
for (int i=0; i< 4; i++)
quad_pts.push_back(contours_poly[0][i]);
if (! orderRectPoints(quad_pts))
return false;
float widthTop = (float)distanceBetweenPoints(quad_pts[1], quad_pts[0]); // sqrt( pow(quad_pts[1].x - quad_pts[0].x, 2) + pow(quad_pts[1].y - quad_pts[0].y, 2));
float widthBottom = (float)distanceBetweenPoints(quad_pts[2], quad_pts[3]); // sqrt( pow(quad_pts[2].x - quad_pts[3].x, 2) + pow(quad_pts[2].y - quad_pts[3].y, 2));
float maxWidth = max(widthTop, widthBottom);
float heightLeft = (float)distanceBetweenPoints(quad_pts[1], quad_pts[2]); // sqrt( pow(quad_pts[1].x - quad_pts[2].x, 2) + pow(quad_pts[1].y - quad_pts[2].y, 2));
float heightRight = (float)distanceBetweenPoints(quad_pts[0], quad_pts[3]); // sqrt( pow(quad_pts[0].x - quad_pts[3].x, 2) + pow(quad_pts[0].y - quad_pts[3].y, 2));
float maxHeight = max(heightLeft, heightRight);
int mDist = (int)max(maxWidth, maxHeight);
// transform TO points
const int offset = 50;
squre_pts.push_back(Point2f(offset, offset));
squre_pts.push_back(Point2f(mDist-1, offset));
squre_pts.push_back(Point2f(mDist-1, mDist-1));
squre_pts.push_back(Point2f(offset, mDist-1));
maxWidth += offset; maxHeight += offset;
Size matSize ((int)maxWidth, (int)maxHeight);
Mat transmtx = getPerspectiveTransform(quad_pts, squre_pts);
// Mat homo = findHomography(quad_pts, squre_pts);
warpPerspective(mRgba, mRgba, transmtx, matSize);
return true;
答案 0 :(得分:1)
你原来的预转换图像不太好,正方形有不同的尺寸,看起来很波浪。考虑到您的输入质量,您获得的结果非常好。
您可以尝试校准相机(https://docs.opencv.org/2.4/doc/tutorials/calib3d/camera_calibration/camera_calibration.html)以补偿镜头失真,结果可能会有所改善。
编辑:只是总结下面的评论,如果方形有圆角或模糊,aboutPolyDp可能无法正确定位角落。您可能需要通过其他方式改善角落位置,例如更清晰的原始图像,不同的预处理(中间滤波器或阈值,如您在评论中所建议的),或其他算法以获得更精细的角落位置(例如使用cornerubpix功能或检测Hough变换的边,然后计算它们的交叉点)