opencv:在二进制图像中拟合最小封闭椭圆

Luc*_*uca 2 c++ opencv image-processing

我已经使用 OpenCV 和抓取实现来生成前景的二进制掩码。这表示为 CV_8UC1 的 opencv 矩阵,其中属于前景的像素值为 255,背景为零(即它是一个二进制掩码)。因此,像所附的图像一样:在此处输入图片说明

我想找到这个蒙版图像的最小封闭椭圆。我在网上找到的例子似乎有点复杂,我无法将其翻译成我的需要。我试着简单地使用

// result is my OpenCV array of 
cv::RotatedRect e = cv::fitEllipse(result);

OpenCV Error: Assertion failed (points.checkVector(2) >= 0 && 
(points.depth() == CV_32F || points.depth() == CV_32S)) in fitEllipse, 
file /home/luca/Downloads/opencv-2.4.10/modules/imgproc
/src/contours.cpp, line 2019

terminate called after throwing an instance of 'cv::Exception'
what():  /home/luca/Downloads/opencv-2.4.10/modules/imgproc
/src/contours.cpp:2019: error: (-215) points.checkVector(2) >= 0 && 
(points.depth() == CV_32F || points.depth() == CV_32S) in function 
fitEllipse
Run Code Online (Sandbox Code Playgroud)

即使我将其转换为 32 位有符号整数,该错误仍然存​​在:

cv::Mat r;
result.convertTo(r, CV_32S);
cv::RotatedRect e = cv::fitEllipse(r);
Run Code Online (Sandbox Code Playgroud)

pla*_*dia 5

函数fitEllipse接受一个 cv::Point 数组,而不是图像。所以你想先通过findContours运行你的图像。请注意,findContours修改图像,因此您可能需要先制作副本。

std::vector< std::vector<cv::Point> > contours;
cv::Mat tmp = result.clone();
cv::findContours(tmp, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); // edited to change from CV_CHAIN_APPROX_SIMPLE
cv::RotatedRect e = cv::fitEllipse(contours[0]);
Run Code Online (Sandbox Code Playgroud)

以上假设您的图像中只有一个轮廓。您可能想要搜索contours最大的轮廓(使用大小或面积)以防有任何噪音(并验证您是否至少获得了一个轮廓)。