opencv学习笔记15: 梯度运算之sobel算子及其函数使用

python+opencv

sobel算子理论

从不同方向计算梯度
如图从x轴计算p5的梯度。左边是卷积核系数
如果右边这一列和左边这一列相差很大,则计算出来的P5x很大,可以认为在边界上。否则不在边界上。用于求出图像边界
opencv学习笔记15: 梯度运算之sobel算子及其函数使用_第1张图片
也可以从y轴计算梯度
如果上下相差很大,则计算出来的值很大,则认为是边界,否则不是
opencv学习笔记15: 梯度运算之sobel算子及其函数使用_第2张图片
整个图像梯度
opencv学习笔记15: 梯度运算之sobel算子及其函数使用_第3张图片
opencv学习笔记15: 梯度运算之sobel算子及其函数使用_第4张图片
opencv学习笔记15: 梯度运算之sobel算子及其函数使用_第5张图片

sobel函数使用

dst=cv2.Sobel(src,ddepth,dx,dy,[kszie])
dst:处理结果
src:原始图像
ddpepth:处理图像的深度.-1表示与原始图像一样
dx:x轴方向,计算x轴方向,dx=1,dy=0
dy:y轴方向,计算y轴,dx=0,dy=1
[ksize]:核大小,默认3
opencv学习笔记15: 梯度运算之sobel算子及其函数使用_第6张图片
不使用绝对值时,负值会被截断为0
opencv学习笔记15: 梯度运算之sobel算子及其函数使用_第7张图片
实际操作中,计算梯度值可能会出现负值而被截断。通常处理的图像类型为np.unit8,处理后的结果也是该类型,所有负数截断为0,发生信息丢失。
所以,在计算时,使用更高的数据类型cv2.CV_64F,取绝对值后再转换成np.unit8(cv2.CV_8U)。所以深度ddepth不写-1,改cv2.CV_64F

cv2.convertScaleAbs(imgsrc)
取绝对值,并将梯度图像转换成256色位图,转换为unit8类型

计算方法
第一种:同时计算xy梯度,第一种有缺陷。
第二种:分别计算.然和相加
使用:处理结果dst = cv2.addWeighted(图像1src1,系数1,图像2src2,系数2,修正系数gamma)
opencv学习笔记15: 梯度运算之sobel算子及其函数使用_第8张图片

sobel函数代码

深度ddepth=-1时

import cv2
import numpy as np
o = cv2.imread('sobel4.bmp',cv2.IMREAD_GRAYSCALE)
sobelx = cv2.Sobel(o,-1,1,0,ksize=3)
cv2.imshow("original",o)
cv2.imshow("x",sobelx)
cv2.waitKey()
cv2.destroyAllWindows()

可以发现x轴的左边边界部分没有取到
opencv学习笔记15: 梯度运算之sobel算子及其函数使用_第9张图片
深度ddepth=cv2.CV_64F时,不添加cv2.convertScaleAbs(imgsrc)

import cv2
import numpy as np
o = cv2.imread('sobel4.bmp',cv2.IMREAD_GRAYSCALE)
sobelx = cv2.Sobel(o,cv2.CV_64F,1,0,ksize=3)
cv2.imshow("original",o)
cv2.imshow("x",sobelx)
cv2.waitKey()
cv2.destroyAllWindows()

可以发现x轴的左边边界部分没有取到
这是因为绝对值未取
需要添加cv2.convertScaleAbs(imgsrc)
里面有个abs绝对值
opencv学习笔记15: 梯度运算之sobel算子及其函数使用_第10张图片
深度ddepth=cv2.CV_64F时。添加cv2.convertScaleAbs(imgsrc),

import cv2
import numpy as np
o = cv2.imread('sobel4.bmp',cv2.IMREAD_GRAYSCALE)
sobelx = cv2.Sobel(o,cv2.CV_64F,1,0,ksize=3)
sobelx = cv2.convertScaleAbs(sobelx)   # 转回uint8  
cv2.imshow("original",o)
cv2.imshow("x",sobelx)
cv2.waitKey()
cv2.destroyAllWindows()

完美取到边界
opencv学习笔记15: 梯度运算之sobel算子及其函数使用_第11张图片
x和y梯度系数相加

import cv2
import numpy as np
o = cv2.imread('sobel4.bmp',cv2.IMREAD_GRAYSCALE)
sobelx = cv2.Sobel(o,cv2.CV_64F,1,0,ksize=3)
sobely = cv2.Sobel(o,cv2.CV_64F,0,1,ksize=3)
sobelx = cv2.convertScaleAbs(sobelx)   # 转回uint8
sobely = cv2.convertScaleAbs(sobely)
sobelxy =  cv2.addWeighted(sobelx,0.5,sobely,0.5,0)
cv2.imshow("original",o)
cv2.imshow("x",sobelx)
cv2.imshow("y",sobely)
cv2.imshow("xy",sobelxy)
cv2.waitKey()
cv2.destroyAllWindows()

opencv学习笔记15: 梯度运算之sobel算子及其函数使用_第12张图片
同时计算x,y梯度。即dx=1,dy=1

import cv2
import numpy as np
o = cv2.imread('sobel4.bmp',cv2.IMREAD_GRAYSCALE)
sobelxy11=cv2.Sobel(o,cv2.CV_64F,1,1,ksize=3)
cv2.imshow("original",o)
cv2.imshow("xy11",sobelxy11)
cv2.waitKey()
cv2.destroyAllWindows()

效果不行。舍弃这一方法。
opencv学习笔记15: 梯度运算之sobel算子及其函数使用_第13张图片

电气专业的计算机小白,写博文不容易。如果你觉得本文对你有用,请点个赞支持下,谢谢。

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