鸟瞰opencv c++的透视变换
Perspective Transformation for bird's eye view opencv c++
我对透视转鸟瞰很感兴趣。到目前为止,我已经尝试了 getPerspectiveTransform 和 findHomography,然后将其传递给 warpPerspective。结果非常接近,但 TL 和 BR 存在偏差。 contourArea 也没有被平等翻译 post transformation.
轮廓是一个正方形,里面有多个形状。
关于如何继续的任何建议。
到目前为止我所做的代码块。
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;
Link to transformed image
Image pre-transformation
corner on pre-transformed image
Corners from CornerSubPix
你原来的变形前的图不太好,那里的方块大小不一,看起来是波浪形的。考虑到您输入的质量,您得到的结果相当不错。
您可以尝试校准您的相机 (https://docs.opencv.org/2.4/doc/tutorials/calib3d/camera_calibration/camera_calibration.html) 以补偿镜头畸变,您的结果可能会有所改善。
编辑:只是总结下面的评论,如果正方形有圆角或模糊,approxPolyDp 可能无法正确定位角。您可能需要通过其他方式改善角点位置,例如更清晰的原始图像、不同的预处理(中值滤波器或阈值,如您在评论中所建议的那样),或其他更精细角点位置的算法(例如使用 cornersubpix 函数或检测霍夫变换的边,然后计算它们的交点)
我对透视转鸟瞰很感兴趣。到目前为止,我已经尝试了 getPerspectiveTransform 和 findHomography,然后将其传递给 warpPerspective。结果非常接近,但 TL 和 BR 存在偏差。 contourArea 也没有被平等翻译 post transformation.
轮廓是一个正方形,里面有多个形状。
关于如何继续的任何建议。
到目前为止我所做的代码块。
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;
Link to transformed image
Image pre-transformation
corner on pre-transformed image
Corners from CornerSubPix
你原来的变形前的图不太好,那里的方块大小不一,看起来是波浪形的。考虑到您输入的质量,您得到的结果相当不错。
您可以尝试校准您的相机 (https://docs.opencv.org/2.4/doc/tutorials/calib3d/camera_calibration/camera_calibration.html) 以补偿镜头畸变,您的结果可能会有所改善。
编辑:只是总结下面的评论,如果正方形有圆角或模糊,approxPolyDp 可能无法正确定位角。您可能需要通过其他方式改善角点位置,例如更清晰的原始图像、不同的预处理(中值滤波器或阈值,如您在评论中所建议的那样),或其他更精细角点位置的算法(例如使用 cornersubpix 函数或检测霍夫变换的边,然后计算它们的交点)