Opencv 不倒曲面

Opencv 不倒曲面,opencv,distortion,unwarp,Opencv,Distortion,Unwarp,我有一个圆柱形物体,上面贴着一个圆形标签。我提取图像的轮廓 我知道圆柱形物体的半径和标签。但并非每次得到的椭圆都是完全对称的。如何将椭圆展开成一个圆 这是一幅不对称的图像 已编辑 我试着把@Haris的解决方案扩展成这样 我想用一组点来得到一个更精确的圆,而不是仅仅4个点。但是getPerspectiveTransform不允许我的分数超过4分。有更好的方法吗?因此,您希望将对象变换为最小封闭圆 如下图所示,将簧片矩形变换为绿色圆圈。即,将边界矩形变换为边界圆 下面的步骤也是如此 对图像设置

我有一个圆柱形物体,上面贴着一个圆形标签。我提取图像的轮廓

我知道圆柱形物体的半径和标签。但并非每次得到的椭圆都是完全对称的。如何将椭圆展开成一个圆

这是一幅不对称的图像

已编辑 我试着把@Haris的解决方案扩展成这样


我想用一组点来得到一个更精确的圆,而不是仅仅4个点。但是
getPerspectiveTransform
不允许我的分数超过4分。有更好的方法吗?

因此,您希望将对象变换为最小封闭圆

如下图所示,将簧片矩形变换为绿色圆圈。即,将边界矩形变换为边界圆

下面的步骤也是如此

  • 对图像设置阈值


好极了!但是现在内部的圆圈变形了。还有什么方法可以保持这一点吗?你不能通过排除变换坐标内的某些部分来进行变换。难道我们不能将靠近垂直轴的点拉伸得比远离垂直轴的点小一点吗?在你发布的结果图像中,因为内部的白色斑点(位于椭圆的垂直轴上)我们也在拉伸,难道我们不能有一个与点到垂直轴的距离成比例的拉伸吗?我认为使用warpPerspective是不可能的。你发布的图像中的“圆形标签”到底是什么?还有,你想取消图像的锐化,使白色斑点变成圆形,还是使灰色斑点变成圆形?实际上我已经处理了图像,你看到的只是“圆形标签”。最初,白色斑点和灰色斑点都是圆,我想在取消旋转后保留它们。另外,你能对相机和圆柱形物体之间的相对姿势做出任何假设吗?例如,可以假设图像的y轴与圆柱体的轴对齐吗?此外,您是否可以假设相机的光轴与圆柱体的轴在3D中相交?是的,图像的y轴与圆柱体的轴对齐。此外,圆柱体的表面始终平行于摄影机的平面(我假设这是您所问的),透视变换不是好方法。假设y轴和圆柱体轴对齐,则需要查找要应用于每个像素的局部水平偏移,以便将柱面变换为平面。我认为OpenCV函数不适用于此,但是如果您派生出适当的映射,您可以使用
cv::remap
()将其应用于图像。导出实际映射是一个数学问题,您应该问。
 Mat src=imread("src.png");
 Mat thr;
 cvtColor(src,thr,CV_BGR2GRAY);
 threshold( thr, thr, 20, 255,CV_THRESH_BINARY_INV );
 bitwise_not(thr,thr);
 vector< vector <Point> > contours; // Vector for storing contour
 vector< Vec4i > hierarchy;

 Mat dst(src.rows,src.cols,CV_8UC1,Scalar::all(0)); //create destination image
 findContours( thr.clone(), contours, hierarchy,CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE ); // Find the contours in the image
 drawContours( dst,contours, 0, Scalar(255,255,255),CV_FILLED, 8, hierarchy );
 Rect R=boundingRect(contours[0]);
 Point2f center;
 float radius;
 minEnclosingCircle( (Mat)contours[0], center, radius);`
std::vector<Point2f> src_pts;
std::vector<Point2f> dst_pts;

src_pts.push_back(Point(R.x,R.y));
src_pts.push_back(Point(R.x+R.width,R.y));
src_pts.push_back(Point(R.x,R.y+R.height));
src_pts.push_back(Point(R.x+R.width,R.y+R.height));

dst_pts.push_back(Point2f(center.x-radius,center.y-radius));
dst_pts.push_back(Point2f(center.x+radius,center.y-radius));
dst_pts.push_back(Point2f(center.x-radius,center.y+radius));
dst_pts.push_back(Point2f(center.x+radius,center.y+radius));

Mat transmtx = getPerspectiveTransform(src_pts,dst_pts);
Mat transformed = Mat::zeros(src.rows, src.cols, CV_8UC3);
warpPerspective(src, transformed, transmtx, src.size());
imshow("transformed", transformed);