弯曲曲面 [英] Unwarp curved surface
问题描述
我有一个粘贴圆形标签的圆柱对象.我提取图像的轮廓.
I have a cylindrical object on which a circular label is pasted. I extract the contour of the image.
我知道圆柱物体的半径以及标签.但是,并非每次获得的椭圆都是完全对称的.如何将椭圆展开成一个圆?
I know the radius of the cylindrical object as well as the label. But not every time the ellipse obtained will be exactly symmetrical. How can I unwrap the ellipse into a circle?
这是不对称的图像
已编辑 我试图扩展@Haris的解决方案,例如
EDITED I tried to extend @Haris's solution something like this
我希望不仅使用4个点,而且要使用一个点数组来获得更准确的圆.但是getPerspectiveTransform
不允许我得分超过4分.有更好的方法吗?
Instead of just just 4 points, I want to use an array of points to get a more accurate circle. But getPerspectiveTransform
won't allow me to have more than 4 points. Is there a better way to this?
推荐答案
因此,您想将对象转换为最小的封闭圆,
So you want to transform your object to minimum enclosing circle,
就像下面的图像一样,将芦苇矩形转换为绿色圆圈.那就是将边界矩形转换为边界圆.
Like in the below image transform reed rectangle to green circle. That is transform bounding rectangle to bounding circle.
执行以下操作
-
阈值图像
Find contour and calculate bounding rect and minmum enclosing circle for contour.
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);`
这里您需要根据边界框和圆计算出转换矩阵
Here you need calculate transformation matrix from bounding box and circle like
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);
这篇关于弯曲曲面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!