【cv笔记】卷积 + 数学形态学(膨胀腐蚀、开闭运算等)

一 卷积

1 卷积定义

卷积是两个变量在某范围内相乘后求和的结果。如果卷积的变量是序列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 ]

【例】
这里写图片描述

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 图像的卷积运算

可看做是加权求和的过程,使用到的图像区域中每个像素分别与卷积核(权矩阵)的每个元素相乘,所有乘积只和作为区域中心像素的新值

滤波器(卷积核)的一般要求
  • 2D卷积需要四个循环嵌套,比较耗时,所以我们一般采用较小的卷积核,如3*3、5*5
  • 滤波器的大小应该为奇数,如5*5 、7*7 ,这样才会有中心,7*7的核半径为3
  • 滤波器矩阵所有的元素之和等于1,滤波前后图像的亮度保持不变。大于1,图像变亮,小于1,图像变暗
  • 对于滤波后的结构,可能会出现0~255以外的数值。对这种情况,直接截断到0和255之间即可
边界处理

当处理图像边界像素时,卷积核与图像区域不能匹配,卷积核中心与边界元素点对应,卷积运算出现问题,此时有以下几种处理方式:
这里写图片描述
1)想象I是无限长的图像的一部分,除了我们给定值的部分,其他部分的像素值都是0。
这里写图片描述
2)第二种方法也是想象I是无限图像的一部分。但没有指定的部分是用图像边界的值进行拓展。
这里写图片描述
3)第三种情况就是认为图像是周期性的。也就是I不断的重复。周期就是I的长度。在我们这里,I(0)和I(8)的值就是一样的,I(9)的值和I(1)的值也是一样的。
这里写图片描述
4)忽略边界像素(处理后的图像丢掉这些像素)

扫描二维码关注公众号,回复: 2920558 查看本文章

3 卷积在图像处理中的应用

  • 均值模糊 高斯模糊
  • 高通滤波 低通滤波
  • 图像锐化 浮雕
  • 边缘检测
  • 。。。

实例0

下面这个滤波器,只有中心点的值是1,邻域点的权值都是0。
相当于未对图片进行变化

这里写图片描述

实例1 均值模糊

这里写图片描述

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)

实例2 图像锐化

这里写图片描述

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)

实例3 边缘检测

这里写图片描述

其他效果

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

二 数学形态学(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)

这里写图片描述
用二进制逻辑运算也可以得到 gradient :

erode = cv2.erode(img, kernel)
dilate = cv2.dilate(img,kernel)
gradient = cv2.bitwise_xor(dilate, erode)

6 顶帽运算(Top Hat)

顶帽运算为原图像与它的开运算值之差,
因为开运算带来的结果是放大了裂缝或者局部低亮度的区域,因此得到的图突出了比原图轮廓周围的区域更明亮的区域,且这一操作和选择的核的大小相关。
顶帽运算往往用来分离比邻近点亮一些的斑块。

7 黑帽运算(black-tophat)

黑帽运算为原图像与它的闭运算值之差,
黑帽运算后的效果图突出了比原图轮廓周围的区域更暗的区域,且这一操作和选择的核的大小相关。
黑帽运算用来分离比邻近点暗一些的斑块。

猜你喜欢

转载自blog.csdn.net/afeiererer/article/details/79489150