文章目录
一、图像梯度概念
图像像素之间相减,得到的差值组成的图像就是图像的梯度图像。注意算子内元素和为1
1.1 一阶导数与soble算子
通过一阶导数可以提取图像边缘,图像边缘地方,像素差异大,一阶导数也大。
(左)原图,中(原图的像素变化),(右)原图一阶导数的变化
soble算子:
最终一阶梯度:
1.2 二阶导数与拉普拉斯算子
二阶导数在图像最大变化处(既边缘)值为零,既边缘的二阶导数为0.通过二阶导数的计算也可以提取边缘。
(左)原图的像素变化,(中)原图一阶导数的变化、(右)原图二阶导数的变化
拉普拉斯算子:
最终二阶梯度:
二、实践
2.1 一阶导数
2.1.1 soble算子cv.Sobel
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
'''soble算子与一阶导数'''
def soble_demo(image):
grad_x=cv.Sobel(image,cv.CV_32F,1,0)#求dx
grad_y = cv.Sobel(image, cv.CV_32F, 0, 1) # 求dy
gradx=cv.convertScaleAbs(grad_x)#导数有正有负,所以取绝对值,使的值在8位
grady = cv.convertScaleAbs(grad_y)
cv.imshow('gradx',gradx)
cv.imshow('grady', grady)
grad_final=cv.addWeighted(gradx,0.5,grady,0.5,0)
cv.imshow('grad_final', grad_final)
img=cv.imread(r'D:\Project\Opencv\Learning01\fang.png')
cv.imshow('origin',img)
soble_demo(img)
cv.waitKey(0)
2.1.2 scharr算子cv.Scharr
soble算子的增强版本,但受噪声影响严重。
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
'''soble算子与一阶导数'''
def soble_demo(image):
# grad_x=cv.Sobel(image,cv.CV_32F,1,0)#求dx
# grad_y = cv.Sobel(image, cv.CV_32F, 0, 1) # 求dy
grad_x=cv.Scharr(image,cv.CV_32F,1,0)#求dx
grad_y = cv.Scharr(image, cv.CV_32F, 0, 1) # 求dy
gradx=cv.convertScaleAbs(grad_x)#导数有正有负,所以取绝对值,使的值在8位
grady = cv.convertScaleAbs(grad_y)
cv.imshow('gradx',gradx)
cv.imshow('grady', grady)
grad_final=cv.addWeighted(gradx,0.5,grady,0.5,0)
cv.imshow('grad_final', grad_final)
img=cv.imread(r'D:\Project\Opencv\Learning01\fang.png')
cv.imshow('origin',img)
soble_demo(img)
cv.waitKey(0)
2.2 二阶导数
2.2.1 API计算
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
'''Laplacian算子,二阶导数'''
def Laplacian_demo(image):
dst=cv.Laplacian(image,cv.CV_32F)#求二阶导
grad= cv.convertScaleAbs(dst)#取绝对值,使得能在图像中显示
cv.imshow('Laplacian',grad)
img=cv.imread(r'D:\Project\Opencv\Learning01\fang.png')
cv.imshow('origin',img)
Laplacian_demo(img)
cv.waitKey(0)
2.2.2 自定义
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
'''拉普拉斯二阶导数,自定义核'''
# def Laplacian_demo(image):
# dst=cv.Laplacian(image,cv.CV_32F)#求二阶导
# grad= cv.convertScaleAbs(dst)#取绝对值,使得能在图像中显示
# cv.imshow('Laplacian',grad)
def Laplacian_custom_demo(image):
kernel=np.array([[0,1,0],[1,-4,1],[0,1,0]])
dst=cv.filter2D(image,cv.CV_32F,kernel=kernel)
grad= cv.convertScaleAbs(dst)#取绝对值,使得能在图像中显示
cv.imshow('Laplacian_custom',grad)
img=cv.imread(r'D:\Project\Opencv\Learning01\fang.png')
cv.imshow('origin',img)
Laplacian_custom_demo(img)
cv.waitKey(0)