OpenCV中的图像基本操作--B站视频教程笔记(五)

在学习B站教学视频的时候记录的笔记

OpenCV+TensorFlow】迪哥带你做项目!深度学习+计算机视觉实战 纯实战教学 技能点加满


5.1图像梯度-Sobel算子

如何理解梯度,以圆形pie.png为例,如果以圆形内部一点为例。画意竖线,很明显竖线两边都是白色没有变化也就没有梯度。如图:

OpenCV中的图像基本操作--B站视频教程笔记(五)_第1张图片

那么梯度会出现在哪呢?很显然是边界附近,如图:

OpenCV中的图像基本操作--B站视频教程笔记(五)_第2张图片

红线左边是黑色,右边是白色,梯度变化肯定是最大的。那么随便点一个点,如果找到此点的梯度呢?其实这就是边缘检测了。

如果计算目标点左边是什么,右边又是什么呢?参考之前的形态学操作,都是创建一个特点的矩阵然后与目标点进行运算。

OpenCV中的图像基本操作--B站视频教程笔记(五)_第3张图片

上面的公式就是计算过程Gx水平方向的梯度计算核矩阵,Gy是竖直方向的梯度计算核矩阵,A为目标点。

实际操作可以调用cv2.Sobel(src,)ddepth,dx,dy,ksize)

  • ddepth 图像深度(一般为-1表示输入深度和输出深度是一样的)

  • dx和dy分别表示水平和竖直方向

  • ksize是Sobel算子的大小

    sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)
    cv2.imshow('sobelx',sobelx)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

    ddepth = cv2.CV_64F 表示支持负数。dx=1,dy=0表示计算是水平方向。ksize=3为Sobel算子大小为3.

  • OpenCV中的图像基本操作--B站视频教程笔记(五)_第4张图片

从图像来看,只有边界有梯度。但为什么左侧边界有,右侧却没有呢,原因是计算过程为右侧-左侧。

圆形左侧边界的左侧是黑色0,右侧是白色255,计算结果255-0=255。同理圆形右侧计算是0-255=0(小于0归零)。如果需要圆形右侧也显示可以把计算过程的归零改成取绝对值。代码如下:

sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)
sobelx = cv2.convertScaleAbs(sobelx)

OpenCV中的图像基本操作--B站视频教程笔记(五)_第5张图片

注意:从结果来看,sobelx本身是带负数的,只是显示的时候会进行归零操作。

再计算竖直方向,代码如下:

#竖直方向
sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)
sobely = cv2.convertScaleAbs(sobely)
cv2.imshow('sobely',sobely)
cv2.waitKey(0)
cv2.destroyAllWindows()

OpenCV中的图像基本操作--B站视频教程笔记(五)_第6张图片

分别计算x和y,再修改

sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0)
cv2.imshow('sobelxy',sobelxy)
cv2.waitKey(0)
cv2.destroyAllWindows()

OpenCV中的图像基本操作--B站视频教程笔记(五)_第7张图片

同时计算x和y

sobelxy = cv2.Sobel(img,cv2.CV_64F,1,1,ksize=3)
sobelxy = cv2.convertScaleAbs(sobelxy)
cv2.imshow('sobelxy',sobelxy)
cv2.waitKey(0)
cv2.destroyAllWindows()

OpenCV中的图像基本操作--B站视频教程笔记(五)_第8张图片

从效果来看,直接计算不如分别计算再求和效果好。

再次使用lena进行测试

img = cv2.imread('H:\Peronal\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)
cv2.imshow('sobelxy',sobelxy)
cv2.waitKey(0)
cv2.destroyAllWindows()

OpenCV中的图像基本操作--B站视频教程笔记(五)_第9张图片

可以看出来,图像的轮廓已经被标识出来了。

再测试下直接计算的效果。

sobelxy = cv2.Sobel(img,cv2.CV_64F,1,1,ksize=3)
sobelxy = cv2.convertScaleAbs(sobelxy)
cv2.imshow('sobelxy',sobelxy)
cv2.waitKey(0)
cv2.destroyAllWindows()

OpenCV中的图像基本操作--B站视频教程笔记(五)_第10张图片

可以看出来,直接计算不如分别计算再求和。

5.2 图像梯度-Scharr算子

整体计算方式与sobel一致,只是算子数值不同。

OpenCV中的图像基本操作--B站视频教程笔记(五)_第11张图片

5.3 图像梯度-laplacian算子

laplacian算子涉及到二次导数,因此对噪音点比较敏感,使用的时候效果不是很好。需要与其他处理搭配使用。

OpenCV中的图像基本操作--B站视频教程笔记(五)_第12张图片

计算过程如下:

三种算子对比代码如下:

img = cv2.imread('H:\Peronal\lena.jpg',cv2.IMREAD_GRAYSCALE)
sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)
sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)
sobelx = cv2.convertScaleAbs(sobelx)
sobely = cv2.convertScaleAbs(sobely)
sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0)
​
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)
​
laplacian = cv2.Laplacian(img,cv2.CV_64F)
laplacian = cv2.convertScaleAbs(laplacian)
​
res = np.hstack((sobelxy,scharrxy,laplacian))
cv2.imshow('res',res)
cv2.waitKey(0)
cv2.destroyAllWindows()
 
  

你可能感兴趣的:(opencv,opencv,计算机视觉,python)