- 形态学梯度:膨胀减去腐蚀
- 图像梯度:指边缘处产生的,常指二值图像中的黑白处。
dst = cv2.Sobel(src, ddepth, dx, dy, ksize)-----------白减去黑,或者黑减去白
- ddepth:图像的深度,一般会写CV_64F,可以出现负数
- dx和dy分别表示水平和竖直方向,水平:1,0(右边减左边);竖直:0,1(下面减上面);
- ksize是Sobel算子的大小
两个方向的sobel算子如下所示,我们采用模板对原图像进行卷积运算,即某处的像素的8邻域的9个像素值分别与sobel算子进行相乘再加和得到该处的像素值,通过观察可知,Gx就是该像素右边的三个相邻像素减去左边的三个相邻像素,Gy就是上面的三个相邻像素减去下面的三个相邻像素。为什么有的是2,有的是1呢?这是因为sobel算子将与目标像素距离近的相邻像素(横着竖着方向)权值设为2,距离远的(斜着的对角线)设置为1,认为距离远的影响小,距离近的影响大。
原图:
sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)
白到黑是正数,黑到白就是负数了,所有的负数opencv默认会被截断成0,所以要取绝对值
(若不取绝对值,那么黑到白会是负数,opencv默认处理为0,图像此处边缘就无法显示。只显示一边的边缘,如上图)
sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)
sobelx = cv2.convertScaleAbs(sobelx) -------------取绝对值
sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)
sobely = cv2.convertScaleAbs(sobely) -------------取绝对值
分别计算x和y,再求和
sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0)
不建议直接计算,如果像下面直接计算(直接写1,1),产生的梯度会不太连续,不如分开再加和效果好。(如下图)
sobelxy=cv2.Sobel(img,cv2.CV_64F,1,1,ksize=3)
sobelxy = cv2.convertScaleAbs(sobelxy)
完整代码:
import cv2
import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline
def cv_imshow(name,img):
cv2.imshow(name,img)
cv2.waitKey(0)
cv2.destroyAllWindows()
#分开计算再相加
img =cv2.imread('F://from 2to7 notebook//images//lena.jpg')
sobelx=cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)
sobelx=cv2.convertScaleAbs(sobelx)
sobely=cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)
sobely=cv2.convertScaleAbs(sobely)
sobelxy=cv2.addWeighted(sobelx,0.5,sobely,0.5,0)
cv_imshow('sobelxy',sobelxy)
#直接计算水平与竖直方向
sobelxy1=cv2.Sobel(img,cv2.CV_64F,1,1,ksize=3)
sobelxy1=cv2.convertScaleAbs(sobelxy1)
cv_imshow('sobelxy1',sobelxy1)