Opencv 形态学与梯度运算
形态学梯度运算
1.腐蚀操作
import numpy as np
kernel = np.ones((3,3),np.uint8)
erosion=cv2.erode(img,kernel,iterations=3) ##注意腐蚀操作是白色变为黑色,因为白色值为255,黑色为0,是数值变小,注意和膨胀区分
cv2.imshow('erosion',erosion)
cv2.waitKey(0)
cv2.destroyAllWindows()
2.膨胀操作
kernel = np.ones((3,3),np.uint8)
dilate = cv2.dilate(img,kernel,iterations=1)
cv2.imshow('dilate',dilate)
cv2.waitKey(0)
cv2.destroyAllWindows()
3.开运算
# 开运算:先腐蚀,再膨胀
img=cv2.imread(r'C:\learn\MarkDown\anconda\fushi.png')
kernel=np.ones((5,5),np.uint8)
opening=cv2.morphologyEx(img,cv2.MORPH_OPEN,kernel)
cv2.imshow('opening',opening)
cv2.waitKey(0)
cv2.destroyAllWindows()
4.闭运算
# 闭:先膨胀,再腐蚀
img=cv2.imread(r'C:\learn\MarkDown\anconda\fushi.png')
kernel=np.ones((5,5),np.uint8)
opening=cv2.morphologyEx(img,cv2.MORPH_CLOSE,kernel)
cv2.imshow('opening',opening)
cv2.waitKey(0)
cv2.destroyAllWindows()
5. 礼貌操作
### 礼帽=原始图像-开运算结果(先腐蚀再膨胀) 原始图像(带毛刺的)-(先腐蚀再膨胀之后的没毛刺了) 所以只剩下毛刺了
### 黑帽=闭运算 -原始图像
import cv2
import numpy as np
img=cv2.imread(r'C:\learn\MarkDown\anconda\fushi.png')
kernel=np.ones((5,5),np.uint8)
tophat = cv2.morphologyEx(img,cv2.MORPH_TOPHAT,kernel)
cv2.imshow('top',tophat)
cv2.waitKey(0)
cv2.destroyAllWindows()
6.黑帽操作
#黑帽操作=闭运算-原始输入(闭运算先膨胀再腐蚀(有刺)-原始图像(有刺)=剩下的原始图像的轮廓(没刺))
img=cv2.imread(r'C:\learn\MarkDown\anconda\fushi.png')
blackhat=cv2.morphologyEx(img,cv2.MORPH_BLACKHAT,kernel)
cv2.imshow('blackhat',blackhat)
cv2.waitKey(0)
cv2.destroyAllWindows()
7.图像梯度Sobel算子(类似于高斯函数形式)
dst=cv2.Sobel(src,depth,dx,dy,ksize)
- deppth:图像深度
- dx和dy水平和竖直方向
- ksize是Sobel算子的大小
def cv_show(name,img): # 定义函数加:cv2.imshow(name,img)cv2.waitKey(0)cv2.destroyAllWindows()
# 水平方向 是右边-左边(由于圆图的左半部分右边是白色减去黑色就是左半边缘,右半部分黑色-白色是负值所以还是黑色)
sobelX = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)
cv_show('img',sobelX)
白到黑是正数,黑到白就是负数了,所有负数都会被截断为0,所以要取绝对值
# 计算水平方向
sobelx=cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)
sobelx=cv2.convertScaleAbs(sobelx)
cv_show('sobelx',sobelx)
#计算竖直方向
sobely=cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)
sobely=cv2.convertScaleAbs(sobely)
cv_show('sobely',sobely)
#进行x和y方向的求和
sobelxy=cv2.addWeighted(sobelx,0.5,sobely,0.5,0)
cv_show('sobelxy',sobelxy)
OpenCv中不建议建议直接使用Gx和Gy一起使用
sobelxy=cv2.Sobel(img,cv2.CV_64F,1,1,ksize=3) #不建议这么使用,弃用
cv_show('sobelxy',sobelxy)
整体使用lena图片操作使用sobel算子计算边缘
img=cv2.imread(r'C:\learn\MarkDown\anconda\lena.png',cv2.IMREAD_GRAYSCALE)
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_show('sobelxy',sobelxy)
8. Scharry 算子和Laplacian算子
三种算子比较 Scharr算子(相对于sobel算子上下,左右方向差值更大,计算的结果差值更明显)更能捕捉到梯度的细节,laplcaian算子相当于二阶导(相当于变化率),对于噪音点也更敏感。
import numpy as np
from matplotlib import pyplot as plt
img=cv2.imread(r'C:\learn\MarkDown\anconda\lena.png',cv2.IMREAD_GRAYSCALE)
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)#img=cv2.imread(r'C:\learn\MarkDown\anconda\lena.png',cv2.IMREAD_GRAYSCALE)
Scharrx=cv2.Scharr(img,cv2.CV_64F,1,0)
Scharrx=cv2.convertScaleAbs(Scharrx)
Scharry=cv2.Scharr(img,cv2.CV_64F,0,1)
Scharry=cv2.convertScaleAbs(Scharry)
Scharrxy=cv2.addWeighted(sobelx,0.5,sobely,0.5,0)laplacian=cv2.Laplacian(img,cv2.CV_64F)
Laplacian=cv2.convertScaleAbs(laplacian)res=np.hstack((sobelxy,Scharrxy,Laplacian))
cv_show('res',res)