Opencv图像边缘检测——Roberts算子(手写)、Sobel算子(手写和调包)、Scharr算子、Laplacian算子

一、Roberts算子

Roberts算子即交叉微分算子,是基于交叉差分的梯度算子。此算法通过局部差分来计算检测图像的边缘线条,对噪声敏感。

Roberts交叉微分算子分别为主对角线和副对角线方向的算子,有两个2*2的滤波算子组成:

Opencv图像边缘检测——Roberts算子(手写)、Sobel算子(手写和调包)、Scharr算子、Laplacian算子_第1张图片

对于图像而言,如果im表示图像像素矩阵,则可以如下计算(i,j)点处的特征值:

|im(i,j)-im(i+1,j+1)|+|im(i+1,j)-im(i,j+1)|

完整代码如下: 

import cv2
import numpy as np
def cv_show(name,img):
    cv2.imshow(name,img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
im=cv2.imread('C:/Users/bwy/Desktop/lena.bmp',cv2.IMREAD_GRAYSCALE)
cv_show('im',im)
m,n=im.shape
eIm=np.zeros([m,n])
for i in range(m-1):
    for j in range(n-1):
        eIm[i,j]=abs(im[i,j]-im[i+1,j+1])+abs(im[i+1,j]-im[i,j+1])
eim=eIm.astype(np.uint8)
res=np.hstack((im,eim))
cv_show('res',res)

结果如图所示:

Opencv图像边缘检测——Roberts算子(手写)、Sobel算子(手写和调包)、Scharr算子、Laplacian算子_第2张图片

 二、Sobel算子

        Sobel算子结合了高斯模糊和一阶微分并计算图像明暗程度的近似值,通过比较图像边缘的明暗程度把该区域内超过阈值的特定像素点记为边缘点。Sobel算子具有一定的平滑作用,对噪声不敏感。

Opencv图像边缘检测——Roberts算子(手写)、Sobel算子(手写和调包)、Scharr算子、Laplacian算子_第3张图片

Opencv图像边缘检测——Roberts算子(手写)、Sobel算子(手写和调包)、Scharr算子、Laplacian算子_第4张图片

手写代码如下:

def sobel(image):
    filterX=np.array([[-1,0,1],[-2,0,2],[-1,0,1]])
    filterY=np.array([[-1,-2,-1],[0,0,0],[1,1,2,]])
    w,h=im.shape
    edgeim=np.zeros((w,h))
    theta=np.zeros((w,h))
    half_mF=np.floor(mF/2)
    half_mF1=half_mF.astype(int)
    for i in range(m-1):
        for j in range(n-1):
            localImage=data[i:i+mF,j:j+nF]
            edgeImX=abs(sum(sum(localImage*filterX)))
            edgeImY=abs(sum(sum(localImage*filterY)))
            edgeim[i,j]=max( edgeImX,edgeImY)
            edgeim=edgeim.astype(np.uint8)
            if edgeImX == 0:   
                theta[i, j] = np.pi / 2
            else:
                theta[i, j] = np.arctan(edgeImY/ edgeImX)
    return edgeim,theta

测试:

a,b=sobel(im)
r=np.hstack((im,a))
cv_show('r',r)

结果如图所示:

Opencv图像边缘检测——Roberts算子(手写)、Sobel算子(手写和调包)、Scharr算子、Laplacian算子_第5张图片

 sobel算子 opencv中调包使用(详细介绍)

To begin with,我们看函数:

Dst=cv2.Sobel(im,ddepth,dx,dy,ksize)

参数解释:

Ddepth代表:图像的深度(一般为-1表示输入深度和输出深度一样)

dx,dy代表:水平方向和竖直方向(谁为1代表在哪个方向)

ksize是Sobel算子的大小

Next

Opencv图像边缘检测——Roberts算子(手写)、Sobel算子(手写和调包)、Scharr算子、Laplacian算子_第6张图片对应项相乘Opencv图像边缘检测——Roberts算子(手写)、Sobel算子(手写和调包)、Scharr算子、Laplacian算子_第7张图片在求和=p3+2*p6+p9-p1-2p4-p7(这这里我们会发现在x方向是右减左,那我们运行一下程序看结果如何。

Img=cv2.imread('C:/Users/bwy/Desktop/2.png',cv2.IMREAD_GRAYSCALE)
sobelx=cv2.Sobel(Img,cv2.CV_64F,1,0,ksize=3)
cv_show('sobelx',sobelx)

 解释说明一下cv2.CV_64F:在我们进行计算的时候会出现正数和负数都存在,opencv会自动拦截将负数变成零,因此我们需要强制换成负数形式,这就是它的含义。

 结果如图所示:

Opencv图像边缘检测——Roberts算子(手写)、Sobel算子(手写和调包)、Scharr算子、Laplacian算子_第8张图片Opencv图像边缘检测——Roberts算子(手写)、Sobel算子(手写和调包)、Scharr算子、Laplacian算子_第9张图片

 左图是操作过的图,右图是原图。

看到这个左图像,想大家都会有疑问,咦???右边的呢咋没了呢?是因为我们前面说了,在计算的时候是右减左,大家看原图,当把这个圆2从中间分开,左半部分在进行计算的时候 ,是不是白减黑因此它是大于零的,而右半部分黑减白是小于零的,就没了,因此我们需要取绝对值。我们在实现以下代码。

sobelx1=cv2.Sobel(Img,cv2.CV_64F,1,0,ksize=3)
sobelx1=cv2.convertScaleAbs(sobelx1)
cv_show('sobelx1',sobelx1)

 结果如图所示:

Opencv图像边缘检测——Roberts算子(手写)、Sobel算子(手写和调包)、Scharr算子、Laplacian算子_第10张图片

上下是点点因此我们再看一下Sobel因子,我就不写计算过程了,在y方向上是下减上 。看一下代码吧:

sobely=cv2.Sobel(Img,cv2.CV_64F,0,1,ksize=3)
sobely=cv2.convertScaleAbs(sobely)
cv_show('sobely',sobely)

 结果如图所示:

Opencv图像边缘检测——Roberts算子(手写)、Sobel算子(手写和调包)、Scharr算子、Laplacian算子_第11张图片

 Finished,分别计算x,y之后再求和:

sobelxy=cv2.addWeighted(sobelx1,0.5,sobely,0.5,0)

结果如图所示:

Opencv图像边缘检测——Roberts算子(手写)、Sobel算子(手写和调包)、Scharr算子、Laplacian算子_第12张图片

 三、Scharr算子、Laplacian算子

Opencv图像边缘检测——Roberts算子(手写)、Sobel算子(手写和调包)、Scharr算子、Laplacian算子_第13张图片和上面的很像,但它的数更大,效果就会更详细,后面看区别很容易看出来。 而Laplacian算子是一种具有旋转不变性的各向同性的二阶微分算子。Opencv图像边缘检测——Roberts算子(手写)、Sobel算子(手写和调包)、Scharr算子、Laplacian算子_第14张图片我们观察这个算子是四周减去中间,由于它对噪音很敏感所以很少单独用。

四、Sobel算子、Scharr算子、Laplacian算子的差异

#不同算子的差异
im=cv2.imread('C:/Users/bwy/Desktop/lena.bmp',cv2.IMREAD_GRAYSCALE)
sobelxx=cv2.Sobel(im,cv2.CV_64F,1,0,ksize=3)
sobelyy=cv2.Sobel(im,cv2.CV_64F,0,1,ksize=3)
sobelyy=cv2.convertScaleAbs(sobelyy)
sobelxx=cv2.convertScaleAbs(sobelxx)
sobelxxyy=cv2.addWeighted(sobelxx,0.5,sobelyy,0.5,0)

scharrx=cv2.Scharr(im,cv2.CV_64F,1,0)
scharry=cv2.Scharr(im,cv2.CV_64F,0,1)
scharrx=cv2.convertScaleAbs(scharrx)
scharry=cv2.convertScaleAbs(scharry)
scharrxy=cv2.addWeighted(scharrx,0.5,scharry,0.5,0)

laplacian=cv2.Laplacian(im,cv2.CV_64F)
laplacian=cv2.convertScaleAbs(laplacian)
RR=np.hstack((im,sobelxxyy,scharrxy,laplacian))
cv_show("RR",RR)

 结果如图所示:

Opencv图像边缘检测——Roberts算子(手写)、Sobel算子(手写和调包)、Scharr算子、Laplacian算子_第15张图片神奇吧! 

你可能感兴趣的:(opencv计算机视觉,opencv,计算机视觉,图像处理)