四、图形梯度—(sobel、scharr、laplacian算子)

图形梯度:

  1. sobel

  2. scharr

  3. laplacian


1、sobel算子

具体讲解可以看这个:Sobel算子

sobel算子原理与实现

sobel和scharr对应的参数信息:

src – 输入图像。dst – 输出图像,与输入图像同样大小,拥有同样个数的通道。

ddepth –输出图片深度;下面是输入图像支持深度和输出图像支持深度的关系:

src.depth() = CV_8U, ddepth = -1/CV_16S/CV_32F/CV_64F

src.depth() = CV_16U/CV_16S, ddepth = -1/CV_32F/CV_64F

src.depth() = CV_32F, ddepth = -1/CV_32F/CV_64F

src.depth() = CV_64F, ddepth = -1/CV_64F

当 ddepth为-1时, 输出图像将和输入图像有相同的深度。输入8位图像则会截取顶端的导数。

xorder – x方向导数运算参数。yorder – y方向导数运算参数。

ksize – Sobel内核的大小,可以是:1,3,5,7。  注意:只可以是小于7 的奇数

scale – 可选的缩放导数的比例常数。delta – 可选的增量常数被叠加到导数中。borderType – 用于判断图像边界的模式。

原图:

四、图形梯度—(sobel、scharr、laplacian算子)_第1张图片

 

import cv2
import numpy as np
"""
    案例一
"""
img = cv2.imread('../image/circle.png')
# cv2.imshow('img',img)
# cv2.waitKey(0)
# cv2.destroyAllWindows()

def cv_show(img,name):
    cv2.imshow(name,img)
    cv2.waitKey()
    cv2.destroyAllWindows()

sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)
# cv_show(sobelx,'sobelx')

sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)
# cv_show(sobely,'sobely')

sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0)
sobelxy = cv2.convertScaleAbs(sobelxy)
# cv_show(sobelxy,'sobelxy')

"""
    案例二
"""
img1 = cv2.imread('../image/lena.png')
cv_show(img1,'img1')

img1_sobelx = cv2.Sobel(img1,cv2.CV_64F,1,0,ksize=3)
# cv_show(img1_sobelx,'img1_sobelx')

img1_sobely = cv2.Sobel(img1,cv2.CV_64F,0,1,ksize=3)
# cv_show(img1_sobely,'img1_sobely')

img1_sobelxy = cv2.addWeighted(img1_sobelx,0.5,img1_sobely,0.5,0)
img1_sobelxy = cv2.convertScaleAbs(img1_sobelxy)
# cv_show(img1_sobelxy,'img1_sobelxy')

# res = np.hstack((img1_sobelx,img1_sobely))
# cv_show(res,'res')

结果:

四、图形梯度—(sobel、scharr、laplacian算子)_第2张图片

 2、scharr算子

这个和sobel算子差不多,都是核3的算子,但是效果比sobel算子效果更好!

import cv2
import numpy as np

img1 = cv2.imread('../image/lena.png')
# cv_show(img1,'img1')

img1_sobelx = cv2.Sobel(img1,cv2.CV_64F,1,0,ksize=3)
# cv_show(img1_sobelx,'img1_sobelx')

img1_sobely = cv2.Sobel(img1,cv2.CV_64F,0,1,ksize=3)
# cv_show(img1_sobely,'img1_sobely')

img1_sobelxy = cv2.addWeighted(img1_sobelx,0.5,img1_sobely,0.5,0)
img1_sobelxy = cv2.convertScaleAbs(img1_sobelxy)
#cv_show(img1_sobelxy,'img1_sobelxy')

def cv_show(img,name):
    cv2.imshow(name,img)
    cv2.waitKey()
    cv2.destroyAllWindows()

img = cv2.imread('../image/lena.png')
#cv_show(img,'img')

scharrx = cv2.Scharr(img,cv2.CV_64F,1,0)
scharry = cv2.Scharr(img,cv2.CV_64F,0,1)
scharrx = cv2.convertScaleAbs(scharrx)
scharry = cv2.convertScaleAbs(scharry)
scharrxy = cv2.addWeighted(scharrx,0.5,scharry,0.5,0)
# cv_show(scharrxy,'scharrxy')


#laplacian算子
laplacian = cv2.Laplacian(img,cv2.CV_64F)
laplacian = cv2.convertScaleAbs(laplacian)
res = np.hstack((img1_sobelxy,scharrxy,laplacian))
cv_show(res,'res')

上述从左到右分别为sobelxy,scharr,laplacian的效果图!参考原图即可!

3、laplacian算子

Laplace算子推荐opencv官网

1、Sobel 算子 ,其基础来自于一个事实,即在边缘部分,像素值出现”跳跃“或者较大的变化。如果在此边缘部分求取一阶导数,你会看到极值的出现。正如下图所示:

四、图形梯度—(sobel、scharr、laplacian算子)_第3张图片

2、如果在边缘部分求二阶导数会出现什么情况?

四、图形梯度—(sobel、scharr、laplacian算子)_第4张图片

你会发现在一阶导数的极值位置,二阶导数为0。所以我们也可以用这个特点来作为检测图像边缘的方法。 但是, 二阶导数的0值不仅仅出现在边缘(它们也可能出现在无意义的位置),但是我们可以过滤掉这些点。

  1. 从以上分析中,我们推论二阶导数可以用来 检测边缘 。 因为图像是 “2维”, 我们需要在两个方向求导。使用Laplacian算子将会使求导过程变得简单。
  2. Laplacian 算子 的定义:

Laplace(f) = \dfrac{\partial^{2} f}{\partial x^{2}} + \dfrac{\partial^{2} f}{\partial y^{2}}

#laplacian算子
laplacian = cv2.Laplacian(img,cv2.CV_64F)
laplacian = cv2.convertScaleAbs(laplacian)
res = np.hstack((img1_sobelxy,scharrxy,laplacian))
cv_show(res,'res')

四、图形梯度—(sobel、scharr、laplacian算子)_第5张图片

 

你可能感兴趣的:(opencv)