形态学处理

发布时间:2023年12月24日

形态学处理的相关内容

(1)基于图像形态进行处理的一般方法

(2)这些处理方法基本是对二进制图像进行处理

(3)卷积核决定着图像处理后的结果

形态学图像处理

(1)腐蚀(简单来说就是黑色图像的部分腐蚀掉白色部分,黑色部分变大)和膨胀(与腐蚀相反,白色部分变大)

(2)开运算:就是先腐蚀后膨胀这样一个组合运算

(3)闭运算:就是先膨胀后腐蚀这样一个组合运算

(4)顶帽,黑帽

图像二值化

为什么要学习二值? 刚刚在上面就提到,我们在对图像进行形态学处理的时候需要对图像处理,而这个图像最好就是二进制图像。

图像二值化相关知识?

(1)二值化就是将图像每个像素变成两种值。如0,255

(2)全局二值化 :就是对整张图片进行操作,超过一定的值就变成255,低于这个值就变成0。不让中间有灰度图像。

(3)局部二值化:就是对图像先分割成很多块,每一块都不一样。

二值化API:threshold(img,thresh,maxVal,type)

img:就是图像,是灰度图

thresh:阈值

maxVal:高于阈值变maxVal,低于阈值变0

type:THRESH_BINARY 高于阈值变最大值低于变最小值? ? THRESH_BINARY_INV与前一种反向高于变最小值,低于变最大值? ?THRESH_TRUNC?? ?THRESH_TPZERO? ? ?THRESH_TOZERO_INV

上图中第一个图像时原图,第二个与第三个是?THRESH_BINARY,THRESH_BINARY_INV。我们可以看出当高于阈值时,BINARY变成设定最大值,BINARY_INV变成设定最小值,低于阈值时,BINARY变成设定最小值,BINARY_INV变成设定最大值。第三个是TRUNC ,它其实就不是二值化图像了,它在低于阈值时不变,高于阈值时全部变为设定的阈值,进行消峰处理。第四个和第五个是THRESH_TPZERO_INV,THRESH_TPZERO,TPZERO_INV在未达到阈值时不变,达到阈值时变为最小值,TPZERO在未达到阈值时变为最小值,达到阈值时不变。

图像二值化实战代码

import cv2
import numpy as np

img = cv2.imread('../MM/fushipzhang.png')
img1 = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# #自己设置阈值大小 thresh
ret, dst = cv2.threshold(img1, 100, 255, cv2.THRESH_BINARY)
# # ret,dst=cv2.threshold(img1,100,255,cv2.THRESH_BINARY_INV) #黑白颜色变换
# print(ret)

cv2.imshow('img', img)
cv2.imshow('gray', img1)
cv2.imshow('dst', dst)

cv2.waitKey(0)

?

最终输出的结果如上,大家可以自己选择不同的阈值进行尝试,看看会出现什么样的区别。

腐蚀

腐蚀的相关知识

腐蚀的原理:其实腐蚀就是一个卷积核去扫描整个图像,只有当卷积核扫描到的全为1的时候,此时卷积核中心才为1,否则只要有0就为0.也就是说,当我扫描图像时,扫描全为白色时,才为白色,否则就是黑色,因此可以想象出来,黑色注定会腐蚀掉原图中旁边有黑色的白色。

这就是进过腐蚀后出现的现象,可以看出,黑色腐蚀了一部分的白色。

腐蚀的API: erode(img,kernel,iterations=1)

img:对哪张图像进行膨胀

kernel:卷积核大小

iterations:卷积的次数

腐蚀实战代码

import cv2
import numpy as np

img = cv2.imread('../MM/erode.png')

# 腐蚀 矩阵中全为1 只有当图像中一块全为1时 才会被腐蚀为1 (一块白才为白) kernel是卷积核
# #手动设置卷积核
kernel=np.ones((9,9),np.uint8)

img1 = cv2.erode(img, kernel, iterations=1)

cv2.imshow('img', img)
cv2.imshow('img1', img1)

cv2.waitKey(0)

我们思考是否和我们原理是相同的,黑色注定会腐蚀掉旁边的白色,所以从第一张图到第二张图,蜘蛛白色的八肢被腐蚀掉,并且黑色的眼睛变大了。大家也可以改变kernel的大小,看看会出现什么情况。

卷积核的类型

卷积核类型相关知识

刚刚我们在腐蚀操作中自己设置了卷积核,但其实opencv有自带的卷积核,我们可以直接调用

获得卷积核API:getStructuringElement(type,size)

type:卷积核类型? MORPH_RACT(矩形)??MORPH_ELLIPSE(椭圆形)???MORPH_CROSS(十字形)

size:卷积核大小(3,3)(5,5)……

卷积核类型实战代码

import cv2
import numpy as np

img = cv2.imread('../MM/erode.png')

# 从opencv中获得卷积核 cv2.getStructuringElement(type,size)
# MORPH_RECT矩形 MORPH_ELLIPSE椭圆形 MORPH_CROSS交叉十字    size值为(3,3).(5,5)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 9))
# kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (9, 9))
# kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (9, 9))
# print(kernel)   #结果是一个全1的九成九的矩阵

img1 = cv2.erode(img, kernel, iterations=1)

cv2.imshow('img', img)
cv2.imshow('img1', img1)

cv2.waitKey(0)

此时我们选取的时?MORPH_RACT(矩形) 这样的卷积核,并且我们设置的大小时(9,9),此时得出的图片与我们腐蚀部分自己设置的kernel最终结果时相同的,因为都是9x9的矩阵。大家也可以尝试不同的type看看结果有什么不同。

膨胀

膨胀的相关知识

膨胀就是把白色膨胀了,在卷积核扫过的区域只要有白色就变成白色。所以可以看出上图经过膨胀后白色变大了。

膨胀API:dilate(img,kernel,iterations=1)

img:对哪个图像进行膨胀

kernel:卷积核大小

iterations:卷积的次数

膨胀实战代码

import cv2
import numpy as np

img = cv2.imread('../MM/erode.png')

# 膨胀 只要矩阵内有1(白)整个区域都会变成白色
# kernel=np.ones((3,3),np.uint8)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7, 7))
dst = cv2.dilate(img, kernel, iterations=1)

cv2.imshow('img', img)
cv2.imshow('dst', dst)
# cv2.imshow('dst1',dst1)

cv2.waitKey(0)

?

原本的小瘦子变成了小胖子。白色的部分进行了膨胀,得到了我们想要的结果。?

大家思考在正常情况下,我先腐蚀,再膨胀,如果其中kernel是相同的,type是相同的,那是否会得到相同的结果?

不一定,如果进行腐蚀,图像每个部分的特征都保留下来了,那进行相反的膨胀结果是相同的,但是如果想我们上面这个图,蜘蛛的眼睛进过膨胀消失了,相反的腐蚀不会出现眼睛了,那结果就不相同了。

开运算

开运算=腐蚀+膨胀

开运算相关知识

开运算有什么用?

上图就是开运算的作用,在保持我需要的图像不变的情况下,消除旁边白色的噪点。

先腐蚀,黑色把白色的小点腐蚀掉后,此时中间的图像也会变瘦,之后进行膨胀,中间图像恢复到原状,但是由于一开始腐蚀已经去掉了白色的小点,那膨胀并不会使消失的小白点出现,所以就完成了保留主要图案,消除白色小点的任务。

开运算API: morphologyEx(img,MORPH_OPEN,kernel)

img:对哪张图片进行开运算

MORPH_OPEN:开运算

kernel:卷积核大小

开运算实战代码

import cv2
import numpy as np

img = cv2.imread('../MM/erode.png')

# 膨胀 只要矩阵内有1(白)整个区域都会变成白色
# kernel=np.ones((3,3),np.uint8)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7, 7))

# #开运算 (先腐蚀后膨胀)(有很多白色的噪点,通过开运算进行消除)
dst = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)

cv2.imshow('img', img)
cv2.imshow('dst', dst)

cv2.waitKey(0)

开运算先腐蚀,把脚都给腐蚀掉了,膨胀也没恢复回来。

闭运算

闭运算=膨胀+腐蚀

闭运算相关知识

闭运算有什么用?

?把不要的黑色小点去掉。

如图中,中心这个人的图像希望保留,但是人里面的黑色小点想要去除。就可以使用闭运算。?

先膨胀,白色把黑色的小点膨胀掉后,此时中间的图像会变胖,之后进行腐蚀,中间图像恢复到原状,但是由于一开始膨胀已经去掉了黑色的小点,那腐蚀并不会使消失的小黑点出现,所以就完成了保留主要图案,消除黑色小点的任务。

闭运算API: morphologyEx(img,MORPH_CLOSE,kernel)

img:对哪张图片进行开运算

MORPH_CLOSE:闭运算

kernel:卷积核大小

闭运算实战代码

import cv2
import numpy as np

img = cv2.imread('../MM/erode.png')

# kernel=np.ones((3,3),np.uint8)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7, 7))

# #闭运算(先膨胀后腐蚀)(有很多黑色的噪点,通过闭运算进行消除)
dst1 = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)

cv2.imshow('img', img)
cv2.imshow('dst1', dst1)

cv2.waitKey(0)

?

开运算先膨胀,把小蜘蛛的小眼睛给膨胀消失了,后腐蚀使蜘蛛大小恢复。?

形态学梯度

梯度=原图—腐蚀

形态学梯度相关知识

腐蚀会使原来的人变小,那用原图减去变小后的图片,就得到了这个人的边沿。?

梯度API:morphologyEx(img,MORPH_GRADIENT,kernel)

形态学梯度实战代码

import cv2
import numpy as np

img = cv2.imread('../MM/erode.png')

# kernel=np.ones((3,3),np.uint8)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))

# #梯度 (原图-腐蚀后的图)
dst = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)

cv2.imshow('img', img)
cv2.imshow('dst', dst)

cv2.waitKey(0)

?

大家思考是不是应该得到上面的图像,首先进行腐蚀四肢变细了,后面使用原图减去腐蚀的图像得到结果。

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7, 7))

我把kernel大小改成7x7,结果会变成下图。

是否是这样的,大家思考?

顶帽运算与黑帽运算

顶帽运算与黑帽运算相关知识

顶帽=原图—开运算

只想要这个小的方块,不想要大的,就可以使用顶帽运算?。

顶帽运算API:morphologyEx(img,MORPH_TOPHAT,kernel)

黑帽=原图—闭运算

得到大块中的黑色的小噪点。

黑帽运算API:morphologyEx(img,MORPH_BLACKHAT,kernel)

顶帽运算与黑帽运算实战代码

顶帽:

import cv2
import numpy as np

img = cv2.imread('../MM/tophat.png')

# kernel=np.ones((3,3),np.uint8)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (19, 19))
# dst = cv2.dilate(img, kernel, iterations=1)

# 顶帽运算(原图-开运算)保留了白色的噪点
dst = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)

cv2.imshow('img', img)
cv2.imshow('dst', dst)

cv2.waitKey(0)

顶帽运算后留下了小的方块,但是在这种操作中需要注意kernel大小的选择,需要进行尝试。

黑帽:

import cv2
import numpy as np

img = cv2.imread('../MM/dotinj.png')

# kernel=np.ones((3,3),np.uint8)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7, 7))

# 黑帽运算(原图-闭运算)保留了黑色的噪点
dst = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)

cv2.imshow('img', img)
cv2.imshow('dst', dst)

cv2.waitKey(0)

?

得到黑色的小噪点。?

文章来源:https://blog.csdn.net/xiongmaowangd/article/details/135179454
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。