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()
换这张图片测试下,效果很好: