当前位置: 首页 > 知识库问答 >
问题:

OpenCV将Canny边转换为轮廓

车靖琪
2023-03-14

我有一个OpenCV应用程序,它来自一个办公室内部(很多细节)的网络摄像头流,在那里我必须找到一个人工标记。标记是白色背景上的黑色正方形。我使用Canny找到边缘和cvFindContours进行轮廓绘制,然后approxPolyDP和co.进行过滤和查找候选对象,然后使用局部直方图进行进一步过滤,bla bla bla bla。。。

这或多或少是有效的,但不是我想要的。FindContours总是返回一个闭合循环,即使Canny创建了一条非闭合线。我得到一条在这条线的两边形成一个圈的轮廓线。对于Canny图像(我的标记)上的闭合边,我得到两个轮廓,一个在内侧,另一个在外侧。我必须解决此操作的问题:

>

  • 我得到每个标记的2个轮廓(没那么严重)

    最琐碎的过滤是不可用的(拒绝非闭合轮廓)

    所以我的问题是:有可能得到非闭合Canny边的非闭合轮廓吗?或者,解决上述两个问题的标准方法是什么?

    Canny是一个非常好的工具,但我需要一种方法将2D b/w图像转换成易于处理的东西。类似于连通分支,按组件的行走顺序列出所有像素。因此,我可以过滤循环,并将其输入约PolyDP。

    更新:我错过了一些重要的细节:标记可以是任何方向(它不是正面对着相机,没有直角),事实上我正在做的是基于标记的2D投影的3D方向估计。

  • 共有3个答案

    林君博
    2023-03-14

    我会这样做的。Canny用于边缘检测2。使用HoughtTransform检测边缘。3.检测角度为90的两条边。

    韶亮
    2023-03-14

    我有同样的问题,重复的轮廓,甚至扩张和侵蚀也不能解决它:

    Mat src=imread("E:\\test.bmp"),gry,bin,nor,dil,erd;
    GaussianBlur( src, nor, Size(5,5),0 );  
    cvtColor(nor,gry,CV_BGR2GRAY);  
    Canny(gry,bin,100,150,5,true);
    dilate(bin,dil,Mat());
    erode(dil,erd,Mat());
    Mat tmp=bin.clone();
    vector<vector<Point>> conts;
    vector<Vec4i> hier;
    findContours(tmp,conts,hier,CV_RETR_TREE,CV_CHAIN_APPROX_SIMPLE);
    

    此图像(test.bmp)包含3个轮廓,但findContours返回6!我使用了阈值并解决了问题:

    Mat src=imread("E:\\test.bmp"),gry,bin,nor,dil,erd;
    GaussianBlur( src, nor, Size(5,5),0 );  
    cvtColor(nor,gry,CV_BGR2GRAY);
    threshold(gry,bin,0,255,THRESH_BINARY+THRESH_OTSU);     
    vector<vector<Point>> conts;
    vector<Vec4i> hier;
    findContours(bin,conts,hier,CV_RETR_TREE,CV_CHAIN_APPROX_SIMPLE);
    

    现在它返回4个轮廓,其中第一个是图像边界(索引为0的轮廓),可以很容易地跳过。

    邹锦
    2023-03-14

    对于问题中的两个问题,我找到了一个简单明了的解决方案。诀窍是启用2级层次结构生成(在FindCountors中)并查找具有父级的轮廓。这将返回封闭Canny边的内部轮廓,仅此而已。非闭合边将自动丢弃,并且每个标记将具有单个轮廓。

    vector<vector<Point> > contours;
    vector<Vec4i> hierarchy;
    findContours(CannyImage, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_NONE, Point(0,0) );
    for (unsigned int i=0; i<contours.size(); i++)
        if (hierarchy[i][3] >= 0)   //has parent, inner (hole) contour of a closed edge (looks good)
            drawContours(contourImage, contours, i, Scalar(255, 0, 0), 1, 8);
    

    它也可以反过来工作,即:寻找具有子级的轮廓(层次[i][2]

     类似资料:
    • 我有一个边缘被坎尼探测到。我想提取边缘的轮廓。 我已经检查了下面的帖子。OpenCV转换Canny边缘到轮廓。 但是它没有处理复杂的形状。例如,带矩形的圆或带线的圆。 cv::findContours()函数有两个问题。1.返回非闭合边的闭合轮廓,但我需要非闭合轮廓2。为闭合边返回2个闭合轮廓(可能其中一个轮廓用于边,另一个用于边的内侧,但我想要两个轮廓中的一个。 有没有办法解决这个问题?谢谢。

    • Canny边缘检测用于检测图像中的边缘。 它接受灰度图像作为输入,并使用多级算法。可以使用类的方法在图像上执行此操作,以下是此方法的语法。 该方法接受以下参数 - image - 表示此操作的源(输入图像)的对象。 edges - 表示此操作的目标(边缘)的对象。 threshold1 - 类型为的变量表示滞后过程的第一个阈值。 threshold2 - 类型为的变量表示滞后过程的第二个阈值。 示

    • 我想提取图像的轮廓,用点坐标序列表示。 使用,我能够生成一个只包含图像边缘的二进制图像。然后,我尝试使用来提取轮廓。不过,结果并不好。 对于每一条边,我通常得到两条线,就像它被认为是一个非常薄的区域一样。我想简化我的轮廓,这样我可以把它们画成单线。或者用不同的函数提取它们,直接产生正确的结果会更好。 我查看了OpenCV的文档,但没有找到任何有用的东西,但我想我不是第一个遇到类似问题的人。有什么功

    • 问题内容: 如何将a转换为in ? 我正在使用JAVA包装器(不是 JavaCV )。由于我是新手,因此在理解工作方式方面存在一些问题。 我想做这样的事情。(根据Ted W.的回复): 这行不通。只是一张尺寸正确的黑色图片。 问题答案: 我还试图做同样的事情,因为需要将经过处理的图像与两个库结合在一起。而我一直试图做的是把中,而不是RGB值。而且有效!所以我做的是: 1,转换为字节数组 2.然后,

    • 问题内容: 我正在尝试将代表黑白图像的2D Numpy数组转换为3通道OpenCV数组(即RGB图像)。 基于代码示例和文档,我正尝试通过Python执行此操作,例如: 但是,对CvtColor()的调用将引发以下cpp级异常: 我究竟做错了什么? 问题答案: 您的代码可以固定如下: 简短说明: 数据类型不受OpenCV的支持(它支持,,,,,,) 无法处理numpy数组,因此必须将两个参数都转换

    • 问题内容: 我正在使用python和OpenCV。我有一个(矩形或其他任何东西)内核,并尝试执行一些形态转换。我的问题是图像边界如何? 例如,openCV如何确定边界外的内核元素以进行扩展?它会忽略它们还是使用其邻居的值? 问题答案: 如OpenCV文档所报告的morphologyEx: C ++:void morphologyEx(InputArray src,OutputArray dst,i