精华内容
下载资源
问答
  • 引言: ...前面已经介绍了Sobel算子,接下来介绍Laplacian算子边缘检测。 Laplacian算子: 在一个二维函数f(x,y)中,x,y两个方向的二阶差分分别为, 所以Laplace算子的差分形式为...

    引言:

    图像的边缘有方向和幅度两个属性,沿边缘方向像素变化平缓,垂直于边缘方向像素变化剧烈.边缘上的这种变化可以用微分算子检测出来,通常用一阶或二阶导数来检测边缘。

    前面已经介绍了Sobel算子,接下来介绍Laplacian算子与边缘检测。

     

    Laplacian算子:

     

    在一个二维函数f(x,y)中,x,y两个方向的二阶差分分别为,

    所以Laplace算子的差分形式为,

     写成filter mask的形式如下:

    API介绍: 

    代码示例:

     

    #include "pch.h"
    #include <iostream>
    #include "opencv2/opencv.hpp"
    
    using namespace std;
    using namespace cv;
    
    
    int main()
    {
    	Mat src = imread("F:\\visual studio\\Image\\building2.jpg");
    	if (src.empty())
    	{
    		cout << "Can't load the image" << endl;
    		return -1;
    	}
    	imshow("src", src);
    	//边缘检测的算法主要是基于图像强度的一阶和二阶导数,但导数通常对噪声很敏感,
    	//因此必须采用滤波器来改善与噪声有关的边缘检测器的性能
    	Mat blursrc;
    	GaussianBlur(src, blursrc, Size(3, 3), 0, 0);
    
    	//转化为灰度图
    	Mat graysrc;
    	cvtColor(blursrc, graysrc, cv::COLOR_BGR2GRAY);
    	imshow("graysrc", graysrc);
    
    	//Laplace变换
    	Mat dst;
    	Laplacian(graysrc, dst, CV_16S, 3);
    	convertScaleAbs(dst, dst);
    
    	imshow("edge", dst);
    	waitKey(0);
    }
    
    

     

     

     

    疑问::

    根据拉普拉斯算子的定义,在图像边缘处二阶导应该为0,在图像中应显示黑色,在过零点附近的波峰波谷应该显示为白色,所以我们得到的边缘实际上是  白黑白 相间的? 中间的黑色才是确切的边缘位置??

    解答:

    白色其实显示的边缘周围的极值点,但是几乎都是围绕在边缘周围。

    展开全文
  • sobel算子的思路就是模拟求一阶导数. sobel算子是一个离散差分算子.它计算图像像素点亮度值的近似梯度. 图像是二维的,即沿着宽度/高度两个方向. 我们使用两个卷积核对原图像进行处理: 水平方向 很好理解,原始...

    sobel算子

              人眼怎么识别图像边缘?

    比如有一幅图,图里面有一条线,左边很亮,右边很暗,那人眼就很容易识别这条线作为边缘.也就是像素的灰度值快速变化的地方.

    对于f(t),其导数f'(t)反映了每一处的变化趋势.在变化最快的位置其导数最大. sobel算子的思路就是模拟求一阶导数.

    sobel算子是一个离散差分算子.它计算图像像素点亮度值的近似梯度.
    图像是二维的,即沿着宽度/高度两个方向.
    我们使用两个卷积核对原图像进行处理:

    • 水平方向

    很好理解,原始像素灰度值-->(右边像素值-左边像素值),反映了水平方向的变化情况.

    • 垂直方向

    这样的话,我们就得到了两个新的矩阵,分别反映了每一点像素在水平方向上的亮度变化情况和在垂直方向上的亮度变换情况.

    综合考虑这两个方向的变化,我们使用

    反映某个像素的梯度变化情况.
    有时候为了简单起见,也直接用绝对值相加替代.

    opencv里可以使用了如下的卷积核,可以"放大像素的变化情况".

     

    可以参考这个函数Scharr

    opencv实现:

    import cv2 as cv
    def test():
        src = cv.imread("/home/sc/disk/keepgoing/opencv_test/sidetest.jpeg")
        src = cv.GaussianBlur(src, (3, 3), 0)
        gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
        grad_x = cv.Sobel(gray, -1, 1, 0, ksize=3)
        grad_y = cv.Sobel(gray, -1, 0, 1, ksize=3)
        
        grad  = cv.addWeighted(grad_x, 0.5, grad_y, 0.5, 0)
        
        cv.imshow("origin",src)
        cv.imshow("grad",grad)
        cv.waitKey()
        
    test()

    首先是高斯模糊去噪.某种意义上说高斯模糊是和sobel相反的过程.高斯模糊平滑了某点像素与周边像素的差异.那为什么还要先高斯去噪呢?

    (噪声就是像素的强度相对于真值有个突变。从时域上讲,通过高斯滤波能让一个像素的强度与周围的点相关,就减小了突变的影响;从频域上讲,突变引入了高频分量,而高斯滤波器可以滤除高频分量。)

    高斯去噪是为了防止把噪点也检测为边缘.

    然后计算grad_x,grad_y.即对原图做水平方向/垂直方向的sobel卷积核卷积

        grad_x = cv.Sobel(gray, -1, 1, 0, ksize=3)
        grad_y = cv.Sobel(gray, -1, 0, 1, ksize=3)

     

    Sobel()
    void cv::Sobel	(	InputArray 	src,
                    OutputArray 	dst,
                    int 	ddepth,
                    int 	dx,
                    int 	dy,
                    int 	ksize = 3,
                    double 	scale = 1,
                    double 	delta = 0,
                    int 	borderType = BORDER_DEFAULT 
    )		
    Python:
    dst	=	cv.Sobel(	src, ddepth, dx, dy[, dst[, ksize[, scale[, delta[, borderType]]]]]	)
    

     

    Parameters

    srcinput image.
    dstoutput image of the same size and the same number of channels as src .
    ddepthoutput image depth, see combinations; in the case of 8-bit input images it will result in truncated derivatives.
    dxorder of the derivative x.
    dyorder of the derivative y.
    ksizesize of the extended Sobel kernel; it must be 1, 3, 5, or 7.
    scaleoptional scale factor for the computed derivative values; by default, no scaling is applied (see getDerivKernels for details).
    deltaoptional delta value that is added to the results prior to storing them in dst.
    borderTypepixel extrapolation method, see BorderTypes

    注意区分c++版本和python版本api. 在上述代码中,第二个参数-1代表我们希望输出的图像矩阵和原图有同样的depth,第3/4个参数分别代表在x/y方向做一阶差分.取值0或1.
    ksize必须为奇数.

    tips:通常我们使用( xorder = 1, yorder = 0, ksize = 3) or ( xorder = 0, yorder = 1, ksize = 3)来计算水平/垂直方向的一阶差分矩阵.ksize=3用的是标准sobel卷积核.如果ksize传入FILTER_SCHARR,则使用的是如下卷积核:

    最后将两个矩阵叠加,综合考虑水平和垂直方向的像素灰度值变化强度.得到边缘.

    grad = cv.addWeighted(grad_x, 0.5, grad_y, 0.5, 0)

    展开全文
  • OpenCV实现更多图像边缘梯度...图像的一阶导数算子除了Sobel边缘检测算子以外,常见的还有Roberts边缘检测算子与Prewitt边缘检测算子。尽管OpenCV中没有这两个算子直接调用的API,我们可以通过自定义滤波器来自行创...

    0.综述

    图像的一阶导数算子除了Sobel边缘检测算子以外,常见的还有Roberts边缘检测算子与Prewitt边缘检测算子。尽管OpenCV中没有这两个算子直接调用的API,我们可以通过自定义滤波器来自行创建Robert算子和Prewitt算子来实现图像的梯度边缘检测。

    关于Sobel算子和图像梯度的内容可以参见下面这篇博客:

    OpenCV自定义滤波器则可以参见下面这篇博客:

    1.Roberts边缘检测算子原理分析

    任意一对相互垂直方向上的差分可以看成是梯度的近似求解,Roberts边缘检测算子就是基于该原理,用对角线上相邻像素之差来代替梯度,从而寻找图像中边缘。所以Roberts边缘检测算子是一个交叉算子,其在点 ( i , j ) (i,j) (i,j)处的梯度幅值表达式为:
    G ( i , j ) = ∣ f ( i , j ) − f ( i + 1 , j + 1 ) ∣ + ∣ f ( i + 1 , j ) − f ( i , j + 1 ) ∣ (1) G(i,j)=|f(i,j)-f(i+1,j+1)|+|f(i+1,j)-f(i,j+1)|\tag{1} G(i,j)=f(i,j)f(i+1,j+1)+f(i+1,j)f(i,j+1)(1)
    其中:
    G x = f ( i , j ) − f ( i + 1 , j + 1 ) G_x=f(i,j)-f(i+1,j+1) Gx=f(i,j)f(i+1,j+1)
    G y = f ( i + 1 , j ) − f ( i , j + 1 ) G_y=f(i+1,j)-f(i,j+1) Gy=f(i+1,j)f(i,j+1)
    所以等式 ( 1 ) (1) (1)可以简化为:
    G ( i , j ) = ∣ G x ∣ + ∣ G y ∣ G(i,j)=|G_x|+|G_y| G(i,j)=Gx+Gy
    G x , G y G_x,G_y Gx,Gy的对于2x2大小卷积核分别为:
    H x = [ 1 0 0 − 1 ] H_x= \left[ \begin{matrix} 1 &0 \\ 0& -1 \end{matrix} \right] Hx=[1001]
    H y = [ 0 − 1 1 0 ] H_y= \left[ \begin{matrix} 0 &-1 \\ 1& 0 \end{matrix} \right] Hy=[0110]

    由于Roberts边缘检测算子是利用图像的两个对角线方向的相邻像素之差进行梯度幅值的检测,所以求得的是在差分点 ( i + 1 / 2 , j + 1 / 2 ) (i+1/2,j+ 1/2) (i+1/2,j+1/2)处梯度幅值的近似值,而不是所预期的点 ( i , j ) (i,j) (ij)处的近似值,为了避免引起混淆,通常采用3X3邻域计算梯度值。

    利用Roberts边缘检测算子进行边缘检测的方法是:分别利用上述两个模板对图像进行逐像素卷积,将2个卷积结果值相加,然后判别该相加结果是否大于或等于某个阈值,如果满足条件,则将其作为结果图像中对应于模板 ( i , j ) (i,j) (i,j)位置的像素值;如果不满足条件,则给结果图像中对应于模板 ( i , j ) (i,j) (i,j)位置的像素赋0值。

    由于Roberts算子模板窗口较小,平滑噪声的作用小,且对噪声较为敏感。该算法仅采用了对角线上相邻像素之差进行梯度幅度检测,并未考虑水平相邻像素和垂直相邻像素的情况,无法消除局部噪声干扰,也会丢失灰度值变化缓慢的局部边缘,从而导致目标的边缘轮廓不连续。

    2.Prewitt边缘检测算子原理分析

    Prewitt边缘检测算子在x方向和y方向的梯度幅值形式与Sobel算子的形式完全相同,只是它的系数均为1。该算子对应的两个方向的3x3卷积核分别为:
    H x = [ − 1 0 1 − 1 0 1 − 1 0 1 ] H_x= \left[ \begin{matrix} -1 &0&1 \\ -1 &0&1 \\ -1 &0&1 \\ \end{matrix} \right] Hx=111000111
    H y = [ 1 1 1 0 0 0 − 1 − 1 − 1 ] H_y= \left[ \begin{matrix} 1&1&1\\ 0&0&0\\ -1&-1&-1\\ \end{matrix} \right] Hy=101101101

    Prewitt边缘检测算子的计算比Sobel算子更为简单,但是在噪声方面Sobel算子更胜一筹。从总体上来说,梯度算子对噪声都有一定的敏感性,所以比较适用于图像边缘灰度值比较尖锐,并且图像噪声比较小的情况下应用。

    3.OpenCV自定义滤波器实现Roberts算子与Prewitt算子

    首先定义两个算子的卷积核:

    	Mat roberts_x = (Mat_<int>(2, 2) << 1, 0, 0, -1);
    	Mat roberts_y = (Mat_<int>(2, 2) << 0, -1, 1, 0);
    
    	Mat pre_kx = (Mat_<char>(3, 3) << -1, 0, 1, -1, 0, 1, -1, 0, 1);
    	Mat pre_ky = (Mat_<char>(3, 3) << 1, 1, 1, 0, 0, 0, -1, -1, -1);
    

    然后使用filter2D函数进行卷积计算:

    Mat rob_x, rob_y, pre_x, pre_y;
    
    filter2D(input, rob_x, CV_16S, roberts_x);
    filter2D(input, rob_y, CV_16S, roberts_y);
    convertScaleAbs(rob_x, rob_x);
    convertScaleAbs(rob_y, rob_y);
    
    filter2D(input, pre_x, CV_32F, pre_kx);
    filter2D(input, pre_y, CV_32F, pre_ky);
    convertScaleAbs(pre_x, pre_x);
    convertScaleAbs(pre_y, pre_y);
    

    最后显示出结果:

    imshow("rob_x", rob_x);
    imshow("rob_y", rob_y);
    imshow("pre_x", pre_x);
    imshow("pre_y", pre_y);
    

    最终结果如下:
    在这里插入图片描述

    通过上面的结果可以看出,垂直算子对垂直方向的边缘梯度具有较强的响应,而水平算子对水平方向上的边缘梯度具有较强的响应。在这三种边缘检测算法中,Roberts算子的检测结果最精细,Prewitt算子比Sobel算子稍精细一些。

    展开全文
  • OpenCV中用Canny算子进行边缘检测

    千次阅读 2017-08-28 18:57:45
    1、Canny原理Canny算子是目前找到的一个最优的边缘检测算子。主要通过以下4个步骤: step1:用高斯滤波器平滑图象; step2:用一阶偏导的有限差分来计算梯度的幅值和方向; step3:对梯度幅值进行非极大值抑制...

    1、Canny原理

    Canny算子是目前找到的一个最优的边缘检测算子。主要通过以下4个步骤:
    step1:用高斯滤波器平滑图象
    step2:用一阶偏导的有限差分来计算梯度的幅值和方向
    step3:对梯度幅值进行非极大值抑制
    step4:用双阈值算法检测和连接边缘
    具体的内容可以参考这篇文章

    2、OpenCV代码

    #include <iostream>
    #include <stdlib.h>
    #include <opencv2/opencv.hpp>
    #include "opencv2/highgui/highgui.hpp"
    #include "opencv2/imgproc/imgproc.hpp"
    using namespace cv;
    using namespace std;
    int main()
    {
        Mat src = imread("1.jpg");
        Mat src1 = src.clone();
    
        // 显示原图
        imshow("【效果图】Canny边缘检测", src);
    
        Mat dst, edge, gray;
    
        // 【1】创建与src同类型和大小的矩阵(dst)
        dst.create(src1.size(), src1.type());
    
        // 【2】将原图转换为灰度图像
        cvtColor(src1, gray, COLOR_BGR2GRAY);
    
        // 【3】先用3×3的内核来降噪
        blur(gray, edge, Size(3, 3));
    
        // 【4】运行Canny算子
        Canny(edge, edge, 3, 9, 3);
    
        // 【5】将dst内的所有元素都置为0
        dst = Scalar::all(0);
    
        // 【6】使用Canny算子输出的边缘图edge作为掩码,来讲原图src1拷贝到目标图dst中
        src1.copyTo(dst, edge);
    
        // 【7】显示效果图
        imshow("【效果图】Canny边缘检测2", dst);
    
        waitKey(0);
    
        system("pause");
        return 0;
    }

    程序运行结果:
    这里写图片描述
    这里写图片描述

    src1.copyTo(dst, edge)函数解释:将掩膜图像(edge)加到原始图像(src1)上,并将结果保存到图像dst中。
    加的方法是这样的:对于灰度图像,掩盖后在图像中掩膜中所有像素值对应为0的点变为黑色(被掩盖),其他点(所有非0值)和原来一致。
    对于三通道彩色图像,某个通道中所有在掩膜中值为0的点在该通道上的像素值变为0,其他所有非0值保持和原来不变。例如当对绿色和蓝色通道加掩膜时会呈现一种图像被盖了一层红色的效果。(因为蓝色和绿色被掩盖了)
    不管是灰度图像还是彩色图像,只有掩膜中像素值为0的点会对图像产生掩盖效果

    展开全文
  • 【C++ OpenCV】Sobel算子边缘检测

    千次阅读 2019-09-20 19:28:11
    边缘指的是像素值发生跃迁的地方,是图像的显著特征之一,在图像特征提取,对象检测,模式识别等方面都有重要的作用。 如何捕捉/提取边缘 ——对图像求一阶导数 delta=f(x)-f(x-1),delta越大,说明像素在x方向变化越...
  • OpenCV 拉普拉斯算子Laplace Operator拉普拉斯算子Laplace Operator目标理论拉普拉斯算子代码解释声明变量加载源图像减少噪音灰阶拉普拉斯算子将输出转换为CV_8U图像结果 拉普拉斯算子Laplace Operator 目标 在本...
  • 边缘检测 边缘检测是图像处理和计算机视觉中的基本问题,边缘检测的目的是标识数字图像像中亮度变化明显的点。图像属性中 的显著变化通常反映了属性的重要事件和变化。 本文主要介绍Roberts cross算子,prewitt算子...
  • 经典的边缘检测方法,是通过对原始图像中像素的某小邻域构造边缘检测算子来达到检测边缘的目的。 一旦计算出导数之后,下一步要做的就是给出一个阈值来确定哪里是边缘位置。阈值越低,能够检测出的边线越多,结果也....
  • Sobel算子:用于边缘检测的离散微分算子。 梯度公式: 对于图像而言,它是离散的,所以h的最小值只能是1了,那么这意味着,图像中某个像素位置的梯度(以x方向为例)等于它左右两个像素点的像素之差除以2。 ...
  • opencv sobel算子

    2019-09-23 22:56:00
    l边缘是什么 – 是像素值发生跃迁的地方,是图像的显著特征之一,在图像特征提取、对象检测、模式识别等方面都有重要的作用。 l如何捕捉/提取边缘 – 对图像求它的一阶导数 delta = f(x) – f(x-1), delta越大,...
  • Opencv Laplacian算子

    千次阅读 2017-12-03 20:19:35
    Laplacian算子
  • 卷积应用-图像边缘提取: 边缘是像素值发生跃迁的地方,是图像的显著特征之一,在图像特征提取、对象检测、模式识别等方面都有重要的作用。...Sobel 算子是一个主要用作边缘检测的离散微分算子 (discrete ...
  • 引言: 图像边缘信息主要集中在高频段,通常说图像...图像处理中有多种边缘检测(梯度)算子,常用的包括普通一阶差分,Robert算子(交叉差分),Sobel算子等等,是基于寻找梯度强度。拉普拉斯算子(二阶差分)是基...
  • opencv sobel算子的理解

    2020-12-11 11:35:46
    索贝尔算子(Sobeloperator)主要用于获得数字图像的一阶梯度,是一种离散性差分算子。它是prewitt算子的改进形式,改进之处在于sobel算子认为,邻域的像素对当前像素产生的影响不是等价的,所以距离不同的像素具有...
  • 日萌社 人工智能AI:Keras PyTorch MXNet TensorFlow PaddlePaddle 深度学习...边缘检测是图像处理和计算机视觉中的基本问题,边缘检测的目的是标识数字图像中亮度变化明显的点。图像属性中的显著变化通常反映了...
  • OpenCv--canny算子提取边缘

    千次阅读 2018-08-27 21:08:04
    利用坎尼边缘检测算子进行边缘检测的原理及OpenCV的代码实现 Canny算子是John Canny在1986年发表的论文中首次提出的边缘检测算子,该算子检测性能比较好,应用广泛。 最优边缘检测的三个主要评价标准是: 低错误率...
  • 边缘检测的算法主要是基于图像强度的一阶和二阶微分操作,但导数通常对噪声很敏感,边缘检测算法常常需要根据图像源的数据进行预处理操作,因此采用滤波器来改善与噪声有关的边缘检测性能,比如在进行边缘检测前,...
  • sober算子边缘检测opencv实现
  • 算子边缘检测 先用高斯滤波器进行平滑处理 一幅图像中的边缘可能在方向上各有所异,所以Canny算法用四个滤波器分别检测图像中的水平、垂直和对角线边缘 Canny算子先利用高斯平滑滤波器来平滑图像以除去噪声,Canny...
  • 梯度算子可以用于增强图像,本质上是通过增强边缘轮廓来实现的,也就是说是可以检测边缘的。但是,它们受噪声的影响都很大。那么我们就要先去除噪声,因为噪声就是灰度变化很大的地方,容易被识别为伪边缘。 第二...
  • 定义:sobel算子是一种基于一阶导数的边缘检测算子。 原理:该算子的主要原理是使用两个3x3的矩阵对原图进行卷积运算,从而计算出该图在水平和垂直方向上的灰度偏差估计值。如下图所示,Gx,Gy分别是对原图A在水平和...
  • OpenCV入门教程之十二】OpenCV边缘检测 Canny算子 Sobel算子 Laplace算子 Scharr滤波
  • 图像处理算法中,边缘检测是非常有用的。。对提取目标区域特别有用。所研究的数字图像的边缘,一般都在像素值较为剧烈的区域 。利用边缘检测算法可在大幅降低图像的... 边缘检测的算法主要是基于图像强度的一阶和...
  • Laplacian算子边缘检测的来源 在边缘部分求取一阶导数,你会看到极值的出现: 如果在边缘部分求二阶导数会出现什么情况? 从上例中我们可以推论检测边缘可以通过定位梯度值大于邻域的相素的方法找到(或者推广到大 ...
  • 首先讲一下我对边缘检测原理的理解。一共分4步进行理解 图像数据检测数据形成数据展示数据 图像数据 想要处理图像,首先要了解图像在内存中是如何存储的。图像是以矩阵的形式进行存储,类似一个表格,图像大小代表...
  • OpenCV-边缘检测算子Marr-Hildreth实现

    千次阅读 2018-02-12 19:54:40
    二阶微分算子典型的是Laplace算子,LoG可以看成是一个高斯模板的拉普拉斯变换。...由于噪声点对边缘有一定的影响,所以更好的边缘检测器是LoG算子,它把高斯平滑滤波器和拉普拉斯锐化滤波器结合起来,先...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,222
精华内容 888
关键字:

opencv一阶算子检测边缘