(数字图像处理MATLAB+Python)第九章图像形态学运算-第三节:二值图像的形态学处理

news/2024/11/25 2:33:24/

文章目录

  • 一:形态滤波
    • (1)概述
    • (2)程序
  • 二:图像的平滑处理
    • (1)概述
    • (2)程序
  • 三:图像的边缘提取
    • (1)概述
    • (2)程序
  • 四:区域填充
    • (1)概述
    • (2)程序
  • 五:目标探测(击中与否变换)
    • (1)概述
    • (2)程序
  • 六:细化
    • (1)概述
    • (2)程序

一:形态滤波

(1)概述

形态滤波:是一种在数字图像处理中常用的图像处理技术,用于改善图像的质量、提取图像的特定特征或去除图像中的噪声。形态滤波主要基于形态学运算,通过结构元素(也称为模板)对图像进行局部区域的操作,从而改变图像的形状和结构。选择不同形状(如各向同性的圆、十字架、矩形、不同朝向的有向线段等)、不同尺寸的结构元素可以提取图像的不同特征

(2)程序

如下:实现对二值图像的特征提取

在这里插入图片描述


matlab实现

I=imread(‘pattern.jpg’);
BW1=im2bw(I,h);
BW1=1-BW1;
se=strel('square',3); 
BW2=1-imopen(BW1,se);
figure;imshow(BW2);title('矩形块提取');
se45=strel('line',25,45);     
BW3=1-imopen(BW1,se45);
figure;imshow(BW3);title('线段提取');

python实现

import cv2
import numpy as np
import matplotlib.pyplot as plt# 读取图像
I = cv2.imread('pattern.jpg', cv2.IMREAD_GRAYSCALE)# 二值化处理
_, BW1 = cv2.threshold(I, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
BW1 = 255 - BW1# 矩形块提取
se = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
BW2 = cv2.morphologyEx(BW1, cv2.MORPH_OPEN, se)
BW2 = 255 - BW2# 显示矩形块提取结果
plt.imshow(BW2, cmap='gray')
plt.title('矩形块提取')
plt.show()# 线段提取
se45 = cv2.getStructuringElement(cv2.MORPH_RECT, (25, 25))
se45 = cv2.rotate(se45, cv2.ROTATE_90_CLOCKWISE)
BW3 = cv2.morphologyEx(BW1, cv2.MORPH_OPEN, se45)
BW3 = 255 - BW3# 显示线段提取结果
plt.imshow(BW3, cmap='gray')
plt.title('线段提取')
plt.show()

二:图像的平滑处理

(1)概述

图像的平缓处理:是数字图像处理中的一项重要任务,它有助于减少图像中的噪声和细节,并使图像更加平滑和连续。通过结合开运算和闭运算,可以实现图像的更加全面的平滑处理。首先,使用开运算可以消除细小的噪声和不连续区域,平滑边缘,同时保留较大的结构。接着,使用闭运算可以填补空洞,连接区域,消除缺陷和断裂,使图像更加连续和平滑。对二值图像平滑处理的形态学变换为

Y = ( X ∘ S ) ⋅ S Y = ( X ⋅ S ) ∘ S \begin{array}{l}\boldsymbol{Y}=(\boldsymbol{X} \circ \boldsymbol{S}) \cdot \boldsymbol{S} \\\boldsymbol{Y}=(\boldsymbol{X} \cdot \boldsymbol{S}) \circ \boldsymbol{S}\end{array} Y=(XS)SY=(XS)S

例如下图,结构元素 S S S大于所有噪声和噪声块的尺寸

在这里插入图片描述

(2)程序

如下

在这里插入图片描述


matlab实现

Image=imread('A.bmp');
BW=im2bw(Image);
SE=strel('square',3);
result1=imclose(imopen(BW,SE),SE); 
figure,imshow(result1);
result2=imopen(imclose(BW,SE),SE);               
figure,imshow(result2);

Python实现

import cv2
import numpy as np
import matplotlib.pyplot as plt# 读取图像
Image = cv2.imread('A.bmp', cv2.IMREAD_GRAYSCALE)# 二值化处理
_, BW = cv2.threshold(Image, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)# 创建结构元素
SE = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))# 先开运算再闭运算
result1 = cv2.morphologyEx(cv2.morphologyEx(BW, cv2.MORPH_OPEN, SE), cv2.MORPH_CLOSE, SE)# 显示结果1
plt.imshow(result1, cmap='gray')
plt.show()# 先闭运算再开运算
result2 = cv2.morphologyEx(cv2.morphologyEx(BW, cv2.MORPH_CLOSE, SE), cv2.MORPH_OPEN, SE)# 显示结果2
plt.imshow(result2, cmap='gray')
plt.show()

三:图像的边缘提取

(1)概述

图像的边缘提取:是数字图像处理中的一项重要任务,它有助于凸显图像中的边缘和轮廓信息,以便于进一步的分析和处理。结合开运算和闭运算可以实现图像的边缘提取。首先,应用闭运算可以填补图像中的空洞和断裂,连接边缘区域,使边缘更加连续。然后,应用开运算可以平滑边缘、去除细小的孤立点和细线条,突出边缘特征。提取物体的轮廓边缘的形态学变换

  • 内边界 Y = X − ( X ⊖ S ) \boldsymbol{Y}=\boldsymbol{X}-(\boldsymbol{X} \ominus \boldsymbol{S}) Y=X(XS)
  • 外边界 Y = ( X ⊕ S ) − X \boldsymbol{Y}=(\boldsymbol{X} \oplus \boldsymbol{S})-\boldsymbol{X} Y=(XS)X
  • 形态学梯度 Y = ( X ⊕ S ) − ( X ⊖ S ) \boldsymbol{Y}=(\boldsymbol{X} \oplus \boldsymbol{S})-(\boldsymbol{X} \ominus \boldsymbol{S}) Y=(XS)(XS)

例如下图,使用结构元素 S S S对图像 X X X进行边缘提取

在这里插入图片描述

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZwmGF6cR-1685365220132)(image/第九章图像形态学运算-第三节:二值图像的形态学处理/image-20230529202220478.png)]

(2)程序

如下

在这里插入图片描述


matlab实现

Image=imread('menu.bmp');
BW=im2bw(Image);
SE=strel('square',3);
result1=BW-imerode(BW,SE); 
result2=imdilate(BW,SE)-BW; 
result3=imdilate(BW,SE)-imerode(BW,SE);     
figure,imshow(result1);
figure,imshow(result2);
figure,imshow(result3);

python实现

import cv2
import numpy as np
import matplotlib.pyplot as plt# 读取图像
Image = cv2.imread('menu.bmp', cv2.IMREAD_GRAYSCALE)# 二值化处理
_, BW = cv2.threshold(Image, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)# 创建结构元素
SE = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))# 边缘提取结果1
result1 = BW - cv2.erode(BW, SE)# 显示结果1
plt.imshow(result1, cmap='gray')
plt.show()# 边缘提取结果2
result2 = cv2.dilate(BW, SE) - BW# 显示结果2
plt.imshow(result2, cmap='gray')
plt.show()# 边缘提取结果3
result3 = cv2.dilate(BW, SE) - cv2.erode(BW, SE)# 显示结果3
plt.imshow(result3, cmap='gray')
plt.show()

四:区域填充

(1)概述

概述:是数字图像处理中的一项常见任务,它有助于填补图像中的空洞或断裂,并连接相邻的区域,使图像中的区域变得连续和完整。结合开运算和闭运算可以实现图像的区域填充。首先,通过应用开运算,可以去除图像中的小型空洞、断裂和孤立点,使得区域边缘更加连续。接着,再应用闭运算,可以填补空洞、连接区域,使得图像中的区域变得完整和连续

X k = ( X k − 1 ⨁ S ) ∩ A C , k = 1 , 2 , 3 , ⋯ X_{k}=\left(X_{k-1} \bigoplus S\right) \cap A^{C}, \quad k=1,2,3, \cdots Xk=(Xk1S)AC,k=1,2,3,

如下图,边界点用灰色表示,赋值为1;所有非边界点是白色部分,赋值为0

在这里插入图片描述

(2)程序

如下

在这里插入图片描述


matlab实现

Image=imread('coin.bmp');
BW=im2bw(Image);
imshow(BW); title('二值图像');
result1=imfill(BW,'holes');
figure,imshow(result1);title('二值图像的区域填充');

python实现

import cv2
import numpy as np
import matplotlib.pyplot as plt# 读取图像
Image = cv2.imread('coin.bmp', cv2.IMREAD_GRAYSCALE)# 二值化处理
_, BW = cv2.threshold(Image, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)# 显示二值图像
plt.imshow(BW, cmap='gray')
plt.title('二值图像')
plt.show()# 区域填充
result1 = cv2.fillHoles(BW)# 显示区域填充结果
plt.imshow(result1, cmap='gray')
plt.title('二值图像的区域填充')
plt.show()

五:目标探测(击中与否变换)

(1)概述

目标探测(击中与否变换):击中与否变换的原理利用腐蚀特性——腐蚀的过程相当于对可以填入结构元素的位置作标记的过程。目标检测既要检测目标内部,也要检测外部,即在一次运算中要同时捕获内外标记。因此,进行目标探测,需要采用两个结构元素 S 1 S_{1} S1 S 2 S_{2} S2,构成一个结构元素对 S = ( S 1 , S 2 ) S=(S_{1},S_{2}) S=(S1,S2)

  • S 1 S_{1} S1:探测目标内部
  • S 2 S_{2} S2:探测目标外部

则图像 X X X用结构元素 S S S进行击中与否变换,记为

X ∗ S = ( X ⊖ S 1 ) ∩ ( X C ⊖ S 2 ) X ∗ S = ( X ⊖ S 1 ) ∩ ( X C ⨁ S ^ 2 ) X ∗ S = { x ∣ S 1 + x ⊆ X and  S 2 + x ⊆ X C } \begin{array}{l}\boldsymbol{X} * \boldsymbol{S}=\left(\boldsymbol{X} \ominus \boldsymbol{S}_{\mathbf{1}}\right) \cap\left(\boldsymbol{X}^{\boldsymbol{C}} \ominus \boldsymbol{S}_{\mathbf{2}}\right) \\\boldsymbol{X} * \boldsymbol{S}=\left(\boldsymbol{X} \ominus \boldsymbol{S}_{\mathbf{1}}\right) \cap\left(\boldsymbol{X}^{\boldsymbol{C}} \bigoplus \widehat{\boldsymbol{S}}_{\mathbf{2}}\right) \\\boldsymbol{X} * \boldsymbol{S}=\left\{\boldsymbol{x} \mid \boldsymbol{S}_{\mathbf{1}}+\boldsymbol{x} \subseteq \boldsymbol{X} \quad \text { and } \quad \boldsymbol{S}_{\mathbf{2}}+\boldsymbol{x} \subseteq \boldsymbol{X}^{\boldsymbol{C}}\right\}\end{array} XS=(XS1)(XCS2)XS=(XS1)(XCS 2)XS={xS1+xX and S2+xXC}

当且仅当结构元素 S 1 S_{1} S1平移到某一点可填入集合 X X X的内部,结构元素 S 2 S_{2} S2平移到该点可填入集合 的外部时,该点才在击中击不中变换的输出中

例如下图,(a)为由四个物体:矩形、小方形、大方形、带有小凸出部分的大方形组成的图像 X X X;(b)为结构元素对 S = ( S 1 , S 2 ) S=(S_{1},S_{2}) S=(S1,S2)。要求通过击中与否运算,能正确识别方形

在这里插入图片描述

效果如下

在这里插入图片描述

(2)程序

如下

在这里插入图片描述


matlab实现

Image=imread('test.bmp');
BW=im2bw(Image);                 
interval=[-1  -1  -1  -1  -1-1  -1  -1  -1  -1-1  -1  1   1   1-1  -1  1   1   1-1  -1  1   1   1];      %定义结构元素对
result=bwhitmiss(BW,interval);   %击中击不中
figure,imshow(result); title('击中与否变换结果');

python实现

import cv2
import numpy as np
import matplotlib.pyplot as plt# 读取图像
Image = cv2.imread('coin.bmp', cv2.IMREAD_GRAYSCALE)# 二值化处理
_, BW = cv2.threshold(Image, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)# 显示二值图像
plt.imshow(BW, cmap='gray')
plt.title('二值图像')
plt.show()# 区域填充
result1 = cv2.fillHoles(BW)# 显示区域填充结果
plt.imshow(result1, cmap='gray')
plt.title('二值图像的区域填充')
plt.show()

六:细化

(1)概述

细化:骨架化结构是目标图像的重要拓扑描述。对目标图像进行细化处理,就是求图像的中央骨架的过程,是将图像上的文字、曲线、直线等几何元素的线条沿着其中心轴线将其细化成一个像素宽的线条的处理过程。基于数学形态学变换的细化算法为

X ⊙ S = X − ( X ∗ S ) \boldsymbol{X} \odot \boldsymbol{S}=\boldsymbol{X}-(\boldsymbol{X} * \boldsymbol{S}) XS=X(XS)

可见,细化实际上为从集合 X X X中去掉被结构元素 S S S击中的结果。具体采用的细化方法为

X 1 = X ⊙ S , X 2 = X 1 ⊙ S , ⋯ ⋯ X n = X n − 1 ⊙ S \boldsymbol{X}_{\mathbf{1}}=\boldsymbol{X} \odot \boldsymbol{S}, \boldsymbol{X}_{\mathbf{2}}=\boldsymbol{X}_{\mathbf{1}} \odot \boldsymbol{S}, \cdots \cdots \boldsymbol{X}_{n}=\boldsymbol{X}_{n-1} \odot \boldsymbol{S} X1=XS,X2=X1S,⋯⋯Xn=Xn1S

如下示例

在这里插入图片描述

在这里插入图片描述

(2)程序

如下

在这里插入图片描述


matlab实现

Image=imread('menu.bmp');
BW=im2bw(Image); 
result1=bwmorph(BW,'thin',1); 
result2=bwmorph(BW,'thin',Inf); 
figure,imshow(result1);title('细化一次');
figure,imshow(result2);title('细化至只有一个像素宽');

python实现

Image=imread('menu.bmp');
BW=im2bw(Image); 
result1=bwmorph(BW,'thin',1); 
result2=bwmorph(BW,'thin',Inf); 
figure,imshow(result1);title('细化一次');
figure,imshow(result2);title('细化至只有一个像素宽');

http://www.ppmy.cn/news/103684.html

相关文章

python-import request失败

mac电脑 vscode。 !!!踩坑,搞了2天 烦了哦 1:python安装: 下载地址:https://cdn.npmmirror.com/binaries/python/3.12.0/python-3.12.0a7-macos11.pkg 2: python配置PATH terminal指令打which …

java循环结构

文章目录 一、Java 循环结构 - for, while 及 do...while1、while 循环2、do…while 循环3、for循环4、break 关键字5、continue 关键字 总结 一、Java 循环结构 - for, while 及 do…while 顺序结构的程序语句只能被执行一次。 如果您想要同样的操作执行多次,就需…

【java 基础一】 纯语法基础记录

一、基础 1.1 变量 Java 变量是程序中存储数据的容器。 在 Java 中,变量需要先声明再使用,并且必须先声明再赋值。 声明变量:声明变量时需要指定变量的类型、名称和初始值。例如,声明一个整型变量可以如下所示: in…

VS2019 WPF制作OTA上位机(三)串口打开

先在UI上添加控件 首先&#xff0c;改变一下原来的方法&#xff0c; 原来的三个控件是没有布局的&#xff0c;添加一下布局。 布局用简单的行布局&#xff0c;也就是说从&#xff0c;上到下&#xff0c;分成一行一行的&#xff0c;如下图 将上一篇文章的代码修改 <Window …

自定义线程池

自定义线程池原理 线程池中分为核心线程和临时线程&#xff1b;首先创建核心线程使用&#xff0c;创建之后一直存在线程池&#xff0c;核心线程被占用并且队列任务已满&#xff0c;才会创建临时线程&#xff1b;临时线程使用超过自定义临时线程最大数时会触发自定义的任务拒绝策…

Jenkins是什么?以及Jenkins有哪些具体的应用呢?

Jenkins是一个流行的开源持续集成和持续交付&#xff08;CI/CD&#xff09;工具&#xff0c;它可以自动化构建、测试和部署软件项目。以下是Jenkins的一些具体应用场景&#xff1a; 1. 自动化构建和集成&#xff1a;Jenkins可以与代码版本控制系统&#xff08;如Git、SVN&#…

《微服务实战》 第二十六章 Java锁的分类

前言 本章节介绍Java中的几种常见的锁&#xff1a;公平锁和非公平锁、可重入锁、独享锁/共享锁、互斥锁/读写锁、乐观锁/悲观锁、分段锁、偏向锁/轻量级锁/重量级锁、自旋锁。 1、公平锁和非公平锁 公平锁是指多个线程按照申请锁的顺序来获取锁。 非公平锁是指多个线程获取锁…

部署微信小程序-shopro

部署微信小程序 开始之前 注意不要运行模式下的代码提交小程序审核&#xff0c;第一包体积太大&#xff0c;第二性能太差请下载 小程序开发工具正式小程序无法正常使用&#xff0c;而开发版正常&#xff0c;请确保域名都添加到小程序后台&#xff0c;并且配置好了 IP 白名单&a…