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

OpenCV中的方向性边缘检测

司马耘豪
2023-03-14

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

根据SO中的帖子改编,我想出了使用OpenCV幅值、相位和Sobel函数来过滤不需要的边缘点。然后使用幅值图像(以相位图像为条件)输出边缘点。

然而,结果与Canny边缘函数不相似。最好是过滤掉带有不需要的角度的边缘,但检测到的边缘是点的斑点,而不是细线边缘

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

1) 为了模仿精明的处理,还应该添加什么?

2) 至于方向边缘检测,这种方法是否比使用除典型Sobel核之外的方向核更鲁棒?

谢谢你!

编辑01:

忘了把我的代码链接

共有2个答案

夏建木
2023-03-14

1) Canny边缘检测器由于邻域的非最大值抑制而产生薄边缘。为了模拟这种情况,需要选择沿该方向具有最大边缘响应的边缘像素。因此,点的斑点可以通过这种方式防止。

正如您可能猜到的,网格中较弱的图像可以使用您定义的阈值进行抑制。

2)很遗憾,我不能给出一个明确的答案。对于给定的天使,内核可能会受到离散化的限制。所以对于许多不同的角度,这种方法“应该”更好。

萧星火
2023-03-14

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

还有另一个线段实现@http://sourceforge.net/projects/lswms/虽然上面的lsd链接效果更好

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

重命名lsd。c进入lsd。编译时使用cpp。我使用了url中附带的1.6版。代码和结果如下。也可以调整阈值以抑制小线段。

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

  • 我试图使用opencv通过可视c提取图像的轮廓。我能够做到这一点,使用opencv教程的findcontoursfindcontoursworks工作在两个步骤 使用canny边缘检测器检测边缘 将canny的输出馈送给findcontours 我想用“结构化森林边缘检测”(Zitnick等人)来尝试同样的方法。我能够提取边缘并显示它们,但当我尝试将输出馈送给FindOntours时。我收到一个“

  • 本文向大家介绍Python中使用OpenCV(CV2)对图像进行边缘检测,包括了Python中使用OpenCV(CV2)对图像进行边缘检测的使用技巧和注意事项,需要的朋友参考一下 使用的模块: 为此,我们将使用opencv-python模块,该模块为我们提供了处理图像的各种功能。 下载opencv-python opencv-python模块: opencv-python是一个python库,它将

  • 我正试图从彩色背景图像中提取文本。我正在尝试的一种方法是边缘检测。用它我把原始图像转换成我可以处理的图像。这将消除图像中的所有颜色,只留下边缘。 我使用此代码获取边缘图像 我的问题是,在我得到这些图像后,我如何才能追踪这些图像中的字母?任何帮助都会很好。谢谢你们 这些是原始图像和边缘检测图像。 原始图像 边缘检测图像

  • 我几乎没有图像处理和识别的背景知识。我试图检测灰度图像(如肖像)上的主边缘/灰度变换。问题是在某些部分,边缘模糊(因为焦点)。我使用的是具有多个阈值的Canny边缘检测器,但我永远无法检测到这些边缘(下巴、衣服、耳朵、脸部侧面等) 边缘检测是正确的工具吗?谢谢

  • 目标 在这一章中,我们将学习 Canny 边缘检测的概念 OpenCV 的 Canny 边缘检测函数:cv2.Canny() 理论基础 Canny边缘检测是一种流行的边缘检测算法。它是由 John F. Canny 于 1986 年开发的。它是一个多阶段算法,我们将学习每个阶段做了什么。 降噪 由于边缘检测容易受到图像中的噪声影响,因此首先要用5x5高斯滤波器去除图像中的噪声。我们在前面的章节已经