首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >OpenCV中的方向边缘检测

OpenCV中的方向边缘检测
EN

Stack Overflow用户
提问于 2014-05-29 09:42:20
回答 2查看 3.2K关注 0票数 0

我想检测出有一定角度/方向的边缘。

从一篇文章改编而来,我已经计算出使用OpenCV震级、相位和Sobel函数来过滤掉不需要的边缘点。然后使用幅度图像(以相位图像为条件)输出边缘点。

然而,所得结果与Canny边函数并不相似。有不想要的角度的边缘被过滤掉是很好的,但是检测到的边缘是点的斑点,而不是细的线边。

在使用findContours之后,左侧边缘图像也会被绘制出来,但这几乎没有帮助。

1)模拟Canny处理时还应添加哪些内容?

2)对于方向边缘检测,这种方法是否比使用方向核比使用典型的Sobel核更有鲁棒性?

谢谢!

编辑01:

忘记把我的代码链接

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-05-30 14:47:38

或者,您可以尝试lsd,(http://www.ipol.im/pub/art/2012/gjmr-lsd/)。它以两点对的形式输出线,因此方向滤波也是可能的。

还有另一个行段实现@ http://sourceforge.net/projects/lswms/,尽管上面的lsd链接有更好的结果

如果您想要单个像素边缘,则需要进行骨架化/细化。

编辑

在编译时,将lsd.c重命名为lsd.cpp。我在网址上使用了1.6版。代码和结果如下。您也可以调整阈值以抑制小段。

代码语言:javascript
复制
#include "opencv2/opencv.hpp"
using namespace cv;
#include "lsd.h"
void lsd_call(Mat& im)
{
    Mat gray;
    cvtColor(im,gray,CV_BGR2GRAY);
    Mat imgdouble;
    gray.convertTo(imgdouble,CV_64FC1);
    double * image;
    double * out;
    int x,y,i,j,n;
    out = lsd(&n,(double*)imgdouble.data,imgdouble.cols,imgdouble.rows);
    Mat lines = im.clone();
    Mat lines_binary = Mat::zeros(gray.size(),CV_8UC1);
    for(i=0;i<n;i++)
    {
        double x1,y1,x2,y2,w;
        x1 = out[7*i+0];
        y1 = out[7*i+1];
        x2 = out[7*i+2];
        y2 = out[7*i+3];
        w = out[7*i+4];
        double length = sqrt(pow(x1-x2,2)+pow(y1-y2,2));
        double angle =  atan2(y2 - y1, x2 - x1) * 180 / CV_PI;

        if(angle<180 && angle>90)
        {
            line(lines,Point2d(out[7*i+0],out[7*i+1]),Point2d(out[7*i+2],out[7*i+3]),Scalar    (0,0,255));
            line(lines_binary,Point2d(out[7*i+0],out[7*i+1]),Point2d(out[7*i+2],out[7*i+3])    ,Scalar(255));
        }
        if(length>75)
        {
            //line(todraw,Point2d(out[7*i+0],out[7*i+1]),Point2d(out[7*i+2],out[7*i+3]),    Scalar(0,0,255),out[7*i+4]);
        }
    }
    imshow("lines",lines);
    imshow("lines_binary",lines_binary);
    imwrite("c:/data/lines.jpg",lines);
    imwrite("c:/data/linesbinary.jpg",lines_binary);
    free( (void *) out );

}
int main(int argc,char** argv )
{
    Mat im = imread("c:/data/lines.png");
    lsd_call(im);
    waitKey(0);
}

票数 1
EN

Stack Overflow用户

发布于 2014-05-30 09:38:38

1) Canny边缘检测器由于沿邻域无极大值抑制而产生较薄的边缘。为了模拟这一点,您需要选择沿该方向边缘响应最大的边缘像素。这样就可以防止点状斑点。

正如您可能猜到的,网格中较弱的图像可以通过您定义的阈值被抑制。

2)遗憾的是,我不能给出确切的答案。对于给出的天使来说,核可能受到离散化的限制。因此,对于许多不同的角度,这种方法“应该”更好。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23930321

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档