图像梯度——Sobel算子
dst = cv2.Sobel(src, ddepth, dx, dy, ksize)
- ddepth:图像的深度,一般是-1
- dx和dy分别表示水平和竖直方向
- ksize是Sobel算子的大小
import cv2 as cv import numpy as np img = cv.imread('pie.png', cv.IMREAD_GRAYSCALE) # 可以转换成灰度图 sobelx = cv.Sobel(img, cv.CV_64F, 1, 0, ksize = 3) # 先计算水平方向 res = np.hstack((img, sobelx)) cv.imshow('res', res) cv.waitKey(0) cv.destroyAllWindows()
左边原图,右边是计算过水平方向梯度后的图。
根据Gx可以分析图片,先看左边,白色减去黑色的值还是白色,而黑色减去白色的值是小于零的,所有的负数会被自动截断成0,所以还是黑色。这就造成上上图只有左边一半的情况。
import cv2 as cv import numpy as np img = cv.imread('pie.png', cv.IMREAD_GRAYSCALE) # 可以转换成灰度图 sobelx = cv.Sobel(img, cv.CV_64F, 1, 0, ksize = 3) # 先计算水平方向 sobelx = cv.convertScaleAbs(sobelx) res = np.hstack((img, sobelx)) cv.imshow('res', res) cv.waitKey(0) cv.destroyAllWindows()
针对上面的情况,我们对计算后的值取绝对值 sobelx = cv.convertScaleAbs(sobelx) 。就可以解决上述问题。
import cv2 as cv import numpy as np img = cv.imread('pie.png', cv.IMREAD_GRAYSCALE) # 可以转换成灰度图 sobely = cv.Sobel(img, cv.CV_64F, 0, 1, ksize = 3) # 计算竖直方向 sobely = cv.convertScaleAbs(sobely) # 取绝对值 res = np.hstack((img, sobely)) cv.imshow('res', res) cv.waitKey(0) cv.destroyAllWindows()
import cv2 as cv import numpy as np img = cv.imread('pie.png', cv.IMREAD_GRAYSCALE) # 可以转换成灰度图 sobelx = cv.Sobel(img, cv.CV_64F, 1, 0, ksize = 3) # 先计算水平方向 sobelx = cv.convertScaleAbs(sobelx) sobely = cv.Sobel(img, cv.CV_64F, 0, 1, ksize = 3) sobely = cv.convertScaleAbs(sobely) sobelxy = cv.addWeighted(sobelx, 0.5, sobely, 0.5, 0) # 将二者结合 res = np.hstack((img, sobelxy)) cv.imshow('res', res) cv.waitKey(0) cv.destroyAllWindows()
我们必须先分别计算两个方向的,最后再结合,否则看下图。
import cv2 as cv import numpy as np img = cv.imread('lena.jpg', cv.IMREAD_GRAYSCALE) # 可以转换成灰度图 # 1、先分别计算水平和竖直方向,再结合 sobelx = cv.Sobel(img, cv.CV_64F, 1, 0, ksize = 3) # 先计算水平方向 sobelx = cv.convertScaleAbs(sobelx) sobely = cv.Sobel(img, cv.CV_64F, 0, 1, ksize = 3) sobely = cv.convertScaleAbs(sobely) sobelxy = cv.addWeighted(sobelx, 0.5, sobely, 0.5, 0) # 将二者结合 # 2、直接计算 sobelxy_1 = cv.Sobel(img, cv.CV_64F, 1, 1, ksize = 3) sobelxy_1 = cv.convertScaleAbs(sobelxy_1) res = np.hstack((img, sobelxy, sobelxy_1)) cv.imshow('res', res) cv.waitKey(0) cv.destroyAllWindows()
左边是原图,中间是正确的计算方式,右边的是错误的计算方式。
图像梯度-Scharr算子和Laplacian算子
import cv2 as cv import numpy as np img = cv.imread('lena.jpg', cv.IMREAD_GRAYSCALE) # 可以转换成灰度图 # Sobel算子 sobelx = cv.Sobel(img, cv.CV_64F, 1, 0, ksize = 3) sobely = cv.Sobel(img, cv.CV_64F, 0, 1, ksize = 3) sobelx = cv.convertScaleAbs(sobelx) sobely = cv.convertScaleAbs(sobely) sobelxy = cv.addWeighted(sobelx, 0.5, sobely, 0.5, 0) # Scharr算子 scharrx = cv.Scharr(img, cv.CV_64F, 1, 0) scharry = cv.Scharr(img, cv.CV_64F, 0 ,1) scharrx = cv.convertScaleAbs(scharrx) scharry = cv.convertScaleAbs(scharry) scharrxy = cv.addWeighted(scharrx, 0.5, scharry, 0.5, 0) # laplacian算子 laplacian = cv.Laplacian(img, cv.CV_64F) laplacian = cv.convertScaleAbs(laplacian) res = np.hstack((img, sobelxy, scharrxy, laplacian)) cv.imshow('算子', res) cv.waitKey(0) cv.destroyAllWindows()