sobel算子理论基础
下面计算P5点的x方向的梯度值,用P5所在列的右侧列减去左侧列,如果相差比较大,可以认为P5所在列是边界,否则不是边界。(下面是3*3的,Sobel()函数的ksize参数不传默认也是3,传值的话必须是奇数)

下面计算P5点的y方向的梯度值,用P5所在行的下侧行减去上侧行,如果相差比较大,可以认为P5所在行是边界,否则不是边界。


这就是P5点的sobel算子:

sobel算子及其函数使用

水平方向求梯度(垂直方向类似,略),ddepth=-1的时候(与原图像保持一样深度),出现负数会处理成0(下图左边界消失),可以把ddepth=cv2.CV_64F,保留住负数,再取绝对值并转为8-bit(下图左边界也会出现)。

# -*- coding: utf-8 -*-
import cv2
img = cv2.imread("C:\\imgs\\sobel.bmp", flags = cv2.IMREAD_UNCHANGED)
sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0) # 先求x方向的梯度
# cv2.Sobel(img, -1, 1, 0) 可以看看这个效果,负数自动搞成0
sobelx = cv2.convertScaleAbs(sobelx) # 求绝对值并转为8-bit
sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1) # 再求y方向的梯度
sobely = cv2.convertScaleAbs(sobely) # 求绝对值并转为8-bit
sobelxy = cv2.addWeighted(sobelx, 0.5, sobely, 0.5, 0) # 图像融合
cv2.imshow("img", img)
cv2.imshow("sobelx", sobelx)
cv2.imshow("sobely", sobely)
cv2.imshow("sobelxy", sobelxy)
cv2.waitKey()
cv2.destroyAllWindows()



scharr算子及其函数使用
与sobel算子对比,是对sobel算子的改进,一般就不用sobel算子了,用scharr算子。

# -*- coding: utf-8 -*-
import cv2
img = cv2.imread("C:\\imgs\\sobel.bmp", flags = cv2.IMREAD_UNCHANGED)
scharrx = cv2.Scharr(img, cv2.CV_64F, 1, 0) # 先求x方向的梯度
scharrx = cv2.convertScaleAbs(scharrx) # 求绝对值并转为8-bit
scharry = cv2.Scharr(img, cv2.CV_64F, 0,1) # 再求y方向的梯度
scharry = cv2.convertScaleAbs(scharry) # 求绝对值并转为8-bit
scharrxy = cv2.addWeighted(scharrx, 0.5, scharry, 0.5, 0) # 图像融合
cv2.imshow("img", img)
cv2.imshow("scharrx", scharrx)
cv2.imshow("scharry", scharry)
cv2.imshow("scharrxy", scharrxy)
cv2.waitKey()
cv2.destroyAllWindows()


sobel算子核scharr算子对比
# -*- coding: utf-8 -*-
import cv2
img = cv2.imread("C:\\imgs\\lena256.bmp", flags = cv2.IMREAD_UNCHANGED)
sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0) # 先求x方向的梯度
sobelx = cv2.convertScaleAbs(sobelx) # 求绝对值并转为8-bit
sobely = cv2.Sobel(img, cv2.CV_64F, 0,1) # 再求y方向的梯度
sobely = cv2.convertScaleAbs(sobely) # 求绝对值并转为8-bit
sobelxy = cv2.addWeighted(sobelx, 0.5, sobely, 0.5, 0) # 图像融合
scharrx = cv2.Scharr(img, cv2.CV_64F, 1, 0) # 先求x方向的梯度
scharrx = cv2.convertScaleAbs(scharrx) # 求绝对值并转为8-bit
scharry = cv2.Scharr(img, cv2.CV_64F, 0,1) # 再求y方向的梯度
scharry = cv2.convertScaleAbs(scharry) # 求绝对值并转为8-bit
scharrxy = cv2.addWeighted(scharrx, 0.5, scharry, 0.5, 0) # 图像融合
cv2.imshow("img", img)
cv2.imshow("sobelxy", sobelxy)
cv2.imshow("scharrxy", scharrxy)
cv2.waitKey()
cv2.destroyAllWindows()

Laplacian算子



# -*- coding: utf-8 -*-
import cv2
img = cv2.imread("C:\\imgs\\lena256.bmp", flags = cv2.IMREAD_UNCHANGED)
laplacian = cv2.Laplacian(img, cv2.CV_64F)
laplacian = cv2.convertScaleAbs(laplacian) # 求绝对值并转为8-bit
cv2.imshow("img", img)
cv2.imshow("laplacian", laplacian)
cv2.waitKey()
cv2.destroyAllWindows()

换这张图片测试下,效果很好:

本文通过对比Sobel算子与Scharr算子在图像处理中的应用,详细介绍了两者在边界检测上的区别与联系。Sobel算子是常用的边缘检测算法,而Scharr算子作为其改进版,通常提供更准确的边缘信息。文中提供了具体的Python代码实现,展示了不同算子对图像边界检测的效果。
3251

被折叠的 条评论
为什么被折叠?



