##一 卷积
###1 卷积定义
卷积是两个变量在某范围内相乘后求和的结果。如果卷积的变量是序列x(n)和h(n),则卷积的结果
y ( n ) = ∑ i = − ∞ ∞ x ( i ) h ( n − i ) = x ( n ) ∗ h ( n ) y(n)=\sum_{i= -\infty}^{\infty}x(i)h(n-i)=x(n)*h(n) y(n)=i=−∞∑∞x(i)h(n−i)=x(n)∗h(n)
####一维卷积
【例】
X = [10, 1, 2, 3, 0, 3]
H= [0.4, 1, 0.5, 2] (卷积核Kernel
)
Y=X * H
。。。。。。
。。。。
import numpy as np
from scipy import signal
X = np.array([10, 1, 2, 3, 0, 3])
H = np.array([2, 0.5, 1, 0.4])
S = signal.convolve(X, H)
print(S)
output:
[ 20. 7. 14.5 12. 3.9 9.8 2.7 3. 1.2]
####二维卷积
y [ i , j ] = ∑ u = − k k ∑ v = − k k x [ u , v ] h [ i − u , i − v ] y [ i , j ]=\sum_{u= -k}^{k}\sum_{v= -k}^{k}x[u,v]h[i-u,i-v] y[i,j]=u=−k∑kv=−k∑kx[u,v]h[i−u,i−v]
【例】
import numpy as np
from scipy import signal
F = np.array([
[1, 2, 0, 7, 0, 3],
[8, 7, 3, 4, 1, 0],
[0, 3, 5, 3, 0, 1],
[1, 2, 1, 7, 1, 0],
[0, 0, 0, 0, 0, 1]])
H = np.array([
[-2, 1, 3],
[-2, 0, 2],
[1, 0, -1]])
S = signal.convolve2d(F, H, boundary='wrap',mode='valid')
print(S)
output:
[[ 2 19 22 11]
[-12 -10 16 22]
[ 5 -10 -5 10]]
H、X的顺序是不影响结果的,S = H * X = X * H
###2 图像的卷积运算
可看做是加权求和的过程,使用到的图像区域中每个像素分别与卷积核(权矩阵)的每个元素相乘,所有乘积只和作为区域中心像素的新值
#####滤波器(卷积核)的一般要求
#####边界处理
当处理图像边界像素时,卷积核与图像区域不能匹配,卷积核中心与边界元素点对应,卷积运算出现问题,此时有以下几种处理方式:
1)想象I是无限长的图像的一部分,除了我们给定值的部分,其他部分的像素值都是0。
2)第二种方法也是想象I是无限图像的一部分。但没有指定的部分是用图像边界的值进行拓展。
3)第三种情况就是认为图像是周期性的。也就是I不断的重复。周期就是I的长度。在我们这里,I(0)和I(8)的值就是一样的,I(9)的值和I(1)的值也是一样的。
4)忽略边界像素(处理后的图像丢掉这些像素)
###3 卷积在图像处理中的应用
####实例0
下面这个滤波器,只有中心点的值是1,邻域点的权值都是0。
相当于未对图片进行变化
import cv2
import numpy as np
img =cv2.imread("pp1.jpg")
fil = np.array([[ 1/9,1/9, 1/9],
[ 1/9, 1/9, 1/9],
[ 1/9, 1/9, 1/9]])
res = cv2.filter2D(img,-1,fil)
cv2.imshow('win',res)
key_pressed=cv2.waitKey(0)
import cv2
import numpy as np
img =cv2.imread("pp1.jpg")
fil = np.array([[ -1,-1, -1],
[ -1, 9, -1],
[ -1, 1, -1]])
res = cv2.filter2D(img,-1,fil)
cv2.imshow('win',res)
key_pressed=cv2.waitKey(0)
##二 数学形态学(Mathematical morphology)
是一门建立在格论和拓扑学基础之上的图像分析学科,是数学形态学图像处理的基本理论。其基本的运算包括:二值腐蚀和膨胀、二值开闭运算、骨架抽取、极限腐蚀、击中击不中变换、形态学梯度、Top-hat变换、颗粒分析、流域变换、灰值腐蚀和膨胀、灰值开闭运算、灰值形态学梯度等。
###1 腐蚀 (erode)
先确定一个核kernel
例如确定好核的尺寸为3*3 .
在opencv中核又被称之为结构元素。
用结构元素与其覆盖的二值图像做与 (and)操作 ,如果都为1,结果图像的该像素为1。否则为0。
也就是说, 如果一个点周边所有点与其本身, 只要这里面有一个0, 它就会被视作为0.
核取的越大, 腐蚀效果越强.
kernel = np.ones((5,5), np.uint8) #新建一个核
erorsion_img = cv2.erode(img, kernel, iterations=1) #将核传入erode函数
iterations
为迭代次数
下图分别为 原图 、 1次迭代 、 2次迭代
import cv2
import numpy as np
img = cv2.imread("d1.png", flags=cv2.IMREAD_GRAYSCALE)# 读入灰度图
#print(img)
kernel = np.ones((5,5), np.uint8)
erorsion_img = cv2.erode(img, kernel, iterations=1)
cv2.imshow('win',erorsion_img )
key_pressed=cv2.waitKey(0)
###2 膨胀 (dilate)
假如使用的是3*3 的核(结构元素).
用核与其覆盖的二值图像做或or
操作
如果周边与其自身任意一个点为1,结果图像的该像素为1, 否则为0
kernel = np.ones((5,5), np.uint8) #新建一个核
dilation_img = cv2.dilate(img, kernel, iterations=1) #将核传入dilate函数
下图分别为 原图 、 1次迭代 、 2次迭代
###3 开运算 (opening )
开运算(opening) 等于对图像先进行腐蚀(erode) 然后进行膨胀(dilate).
通常用于去除小粒噪声
opening_img = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
import cv2
import numpy as np
img = cv2.imread("dd.png", flags=cv2.IMREAD_GRAYSCALE)# 读入灰度图
kernel = np.ones((5,5), np.uint8)
opening_img = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel,iterations=1)
cv2.imshow('win',opening_img )
key_pressed=cv2.waitKey(0)
###4 闭运算 (closing )
闭运算(opening) 等于对图像先进行膨胀(dilate)然后进行腐蚀(erode) .
通常用于消除内部细小空洞的部分
closing_img = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel,iterations=1)
import cv2
import numpy as np
img = cv2.imread("p.png", flags=cv2.IMREAD_GRAYSCALE)# 读入灰度图
kernel = np.ones((5,5), np.uint8)
closing_img = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel,iterations=1)
cv2.imshow('win',closing_img)
key_pressed=cv2.waitKey(0)
###5 数学形态学梯度 (gradient)
数学形态学梯度 = 图像膨胀 - 图像腐蚀
获取到图像的边缘.
gradient_img = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)
erode = cv2.erode(img, kernel)
dilate = cv2.dilate(img,kernel)
gradient = cv2.bitwise_xor(dilate, erode)
###6 顶帽运算(Top Hat)
顶帽运算为原图像与它的开运算值之差,
因为开运算带来的结果是放大了裂缝或者局部低亮度的区域,因此得到的图突出了比原图轮廓周围的区域更明亮的区域,且这一操作和选择的核的大小相关。
顶帽运算往往用来分离比邻近点亮一些的斑块。
###7 黑帽运算(black-tophat)
黑帽运算为原图像与它的闭运算值之差,
黑帽运算后的效果图突出了比原图轮廓周围的区域更暗的区域,且这一操作和选择的核的大小相关。
黑帽运算用来分离比邻近点暗一些的斑块。