Python 3.x Opencv-椭圆轮廓未正确拟合

Python 3.x Opencv-椭圆轮廓未正确拟合,python-3.x,opencv,computer-vision,Python 3.x,Opencv,Computer Vision,我想围绕下图所示的同心椭圆绘制轮廓。我没有得到预期的结果 我尝试了以下步骤: 阅读图片 将图像转换为灰度 应用高斯模糊 获得精明的优势 绘制椭圆轮廓 以下是源代码: 下图显示了预期和实际结果: 源图像: 算法可以很简单: 将RGB转换为HSV,拆分并使用V通道 删除所有颜色线的阈值 用于删除非颜色线的HoughLinesP 椭圆中闭合孔的扩张+侵蚀 findContours+fitEllipse 结果: 对于新图像(添加黑色曲线),我的方法不起作用。似乎需要使用Hough椭圆检测,而不是“f

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

我尝试了以下步骤:

  • 阅读图片
  • 将图像转换为灰度
  • 应用高斯模糊
  • 获得精明的优势
  • 绘制椭圆轮廓
  • 以下是源代码:

    下图显示了预期和实际结果:

    源图像:


    算法可以很简单:

  • 将RGB转换为HSV,拆分并使用V通道

  • 删除所有颜色线的阈值

  • 用于删除非颜色线的HoughLinesP

  • 椭圆中闭合孔的扩张+侵蚀

  • findContours+fitEllipse

  • 结果:

    对于新图像(添加黑色曲线),我的方法不起作用。似乎需要使用Hough椭圆检测,而不是“findContours+fitEllipse”。 OpenCV没有实现,但您可以找到它或

    如果你不害怕C++代码(对于OpenCV库C++更具表现力),那么:

    cv::Mat rgbImg=cv::imread(“sqOOE.jpg”,cv::imread\u COLOR);
    cv::Mat hsvImg;
    cv::cvtColor(rgbImg、hsvImg、cv::COLOR_BGR2HSV);
    性病:媒介通道;
    cv::拆分(hsvImg、chans);
    cv::threshold(255-chans[2],chans[2],200255,cv::THRESH_二进制);
    std::向量linesP;
    cv::HoughLinesP(chans[2],linesP,1,cv_PI/180,50,chans[2]。第4,10行);
    用于(自动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::扩张(通道[2],通道[2],cv::getStructuringElement(cv::变形,cv::大小(3,3)),cv::点(-1,-1),4);
    cv::腐蚀(通道[2],通道[2],cv::getStructuringElement(cv::变形,cv::大小(3,3)),cv::点(-1,-1),3);
    矢量轮廓;
    向量层次;
    cv::findContours(通道[2],轮廓,层次,cv::RETR_树,cv::CHAIN_近似_简单);
    对于(size_t i=0;i4)
    {
    cv::ellipse(rgbImg,cv::fitEllipse(等高线[i]),cv::Scalar(255,025),2);
    }
    }
    cv::imshow(“rgbImg”,rgbImg);
    cv::waitKey(0);
    
    下次,请检查如何正确格式化代码块(这次为您完成);另外,由于您的问题是Python API,请避免使用
    c++
    标记(已删除)。@desertnaut感谢您的编辑manThank获得帮助。最后一个查询,我在源图像中添加了曲线。它与当前代码兼容吗?我试试看。您可以将图像保存为png格式吗?对于Graphicsorry来说,Jpeg是一个非常糟糕的选择。由于不便,我将JPG的格式更新为PNG。对于任何黑色曲线,我的算法都不起作用。我正在更新我的答案-添加到基于Hough的椭圆检测器的链接
    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()
    
    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);