Opencv-椭圆轮廓不正确

时间:2019-02-14 09:49:27

标签: python-3.x opencv computer-vision

我想在下图所示的同心椭圆周围绘制轮廓。我没有得到预期的结果。

我尝试了以下步骤:

  1. 阅读图像
  2. 将图像转换为灰度。
  3. 应用高斯模糊
  4. 获取Canny边缘
  5. 绘制椭圆轮廓​​

以下是源代码:

import cv2

target=cv2.imread('./source image.png')

targetgs = cv2.cvtColor(target,cv2.COLOR_BGRA2GRAY)

targetGaussianBlurGreyScale=cv2.GaussianBlur(targetgs,(3,3),0)

canny=cv2.Canny(targetGaussianBlurGreyScale,30,90)


kernel=cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))
close=cv2.morphologyEx(canny,cv2.MORPH_CLOSE,kernel)


_,contours,_=cv2.findContours(close,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)

if len(contours) != 0:
    for c in contours:
        if len(c) >= 50:
            hull=cv2.convexHull(c)
            cv2.ellipse(target,cv2.fitEllipse(hull),(0,255,0),2)

cv2.imshow('mask',target)
cv2.waitKey(0)
cv2.destroyAllWindows()

下图显示了预期和实际结果: Expected & Actual Result Image

源图像:

Source Image

1 个答案:

答案 0 :(得分:2)

算法可以很简单:

  1. 将RGB转换为HSV,拆分并使用V通道。

  2. 删除所有颜色线的阈值。

  3. HoughLinesP用于删除非色线。

  4. 扩张+侵蚀,形成椭圆形的小孔。

  5. findContours + fitEllipse。

结果:

Result image

对于新图像(添加黑色曲线),我的方法无效。似乎您需要使用霍夫椭圆检测代替“ findContours + fitEllipse”。 OpenCV没有实现,但是您可以找到herehere

如果您不怕C ++代码(对于OpenCV库C ++更具表现力),则:

cv::Mat rgbImg = cv::imread("sqOOE.jpg", cv::IMREAD_COLOR);

cv::Mat hsvImg;
cv::cvtColor(rgbImg, hsvImg, cv::COLOR_BGR2HSV);

std::vector<cv::Mat> chans;
cv::split(hsvImg, chans);
cv::threshold(255 - chans[2], chans[2], 200, 255, cv::THRESH_BINARY);

std::vector<cv::Vec4i> linesP;
cv::HoughLinesP(chans[2], linesP, 1, CV_PI/180, 50, chans[2].rows / 4, 10);
for (auto l : linesP)
{
    cv::line(chans[2], cv::Point(l[0], l[1]), cv::Point(l[2], l[3]), cv::Scalar::all(0), 3, cv::LINE_AA);
}
cv::dilate(chans[2], chans[2], cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3)), cv::Point(-1, -1), 4);
cv::erode(chans[2], chans[2], cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3)), cv::Point(-1, -1), 3);

std::vector<std::vector<cv::Point> > contours;
std::vector<cv::Vec4i> hierarchy;
cv::findContours(chans[2], contours, hierarchy, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE);

for (size_t i = 0; i < contours.size(); i++)
{
    if (contours[i].size() > 4)
    {
        cv::ellipse(rgbImg, cv::fitEllipse(contours[i]), cv::Scalar(255, 0, 255), 2);
    }
}

cv::imshow("rgbImg", rgbImg);
cv::waitKey(0);