Python图像处理之膨胀与腐蚀的操作


Posted in Python onFebruary 07, 2021

引言

膨胀与腐蚀是图像处理中两种最基本的形态学操作,膨胀将目标点融合到背景中,向外部扩展,腐蚀与膨胀意义相反,消除连通的边界,使边界向内收缩。在本文中我们将了解使用内核的图像膨胀与腐蚀的基本原理。

让我们开始吧,同样我们需要导入必需的库。

import numpy as np
import matplotlib.pyplot as plt
from skimage.io import imread, imshow
from skimage.draw import circle
from skimage.morphology import erosion, dilation

首先让我们创建一个容易操作的形状--一个简单的圆。

circ_image = np.zeros((100, 100))
circ_image[circle(50, 50, 25)] = 1
imshow(circ_image);

Python图像处理之膨胀与腐蚀的操作

现在让我们定义一个内核。

cross = np.array([[0,1,0],
   [1,1,1],
   [0,1,0]])
imshow(cross, cmap = 'gray');

Python图像处理之膨胀与腐蚀的操作

将腐蚀函数应用到创建的圆上。

eroded_circle = erosion(circ_image, cross)
imshow(eroded_circle);

Python图像处理之膨胀与腐蚀的操作

图像看起来几乎一模一样。要看到那些微小的差异,我们必须仔细查看图像。

linecolor = 'red'
fig, ax = plt.subplots(1, 2, figsize=(12, 5))
ax[0].imshow(circ_image, cmap = 'gray');
ax[0].set_title('Original', fontsize = 19)
ax[0].axvline(x = 25, color = linecolor)
ax[0].axvline(x = 75, color = linecolor)
ax[0].axhline(y = 25, color = linecolor)
ax[0].axhline(y = 75, color = linecolor)
ax[1].imshow(eroded_circle, cmap = 'gray');
ax[1].set_title('Eroded', fontsize = 19)
ax[1].axvline(x = 25, color = linecolor)
ax[1].axvline(x = 75, color = linecolor)
ax[1].axhline(y = 25, color = linecolor)
ax[1].axhline(y = 75, color = linecolor)
fig.tight_layout()

Python图像处理之膨胀与腐蚀的操作

我们可以看到,被腐蚀的圆已经略微缩小了。这就是腐蚀一个对象的意义。如果我们对腐蚀函数进行迭代,它的效果会变得非常明显。

def multi_erosion(image, kernel, iterations):
 for i in range(iterations):
 image = erosion(image, kernel)
 return image
ites = [2,4,6,8,10,12,14,16,18,20]
fig, ax = plt.subplots(2, 5, figsize=(17, 5))
for n, ax in enumerate(ax.flatten()):
 ax.set_title(f'Iterations : {ites[n]}', fontsize = 16)
 new_circle = multi_erosion(circ_image, cross, ites[n])
 ax.imshow(new_circle, cmap = 'gray');
 ax.axis('off')
fig.tight_layout()

Python图像处理之膨胀与腐蚀的操作

上图清楚地显示了图像是如何被腐蚀的。现在让我们尝试改变内核,如果我们使用水平线和垂直线内核代替交叉内核会怎样呢?

h_line = np.array([[0,0,0],
   [1,1,1],
   [0,0,0]])
v_line = np.array([[0,1,0],
   [0,1,0],
   [0,1,0]])
fig, ax = plt.subplots(1, 2, figsize=(15, 5))
ax[0].imshow(h_line, cmap='gray');
ax[1].imshow(v_line, cmap='gray');
fig.tight_layout()

Python图像处理之膨胀与腐蚀的操作

ites = [2,4,6,8,10,12,14,16,18,20]
fig, ax = plt.subplots(2, 5, figsize=(17, 5))
for n, ax in enumerate(ax.flatten()):
 ax.set_title(f'Horizontal Iterations : {ites[n]}', fontsize = 12)
 new_circle = multi_erosion(circ_image, h_line, ites[n])
 ax.imshow(new_circle, cmap = 'gray');
 ax.axis('off')
fig.tight_layout()
fig, ax = plt.subplots(2, 5, figsize=(17, 5))
for n, ax in enumerate(ax.flatten()):
 ax.set_title(f'Vertical Iterationss : {ites[n]}', fontsize = 12)
 new_circle = multi_erosion(circ_image, v_line, ites[n])
 ax.imshow(new_circle, cmap = 'gray');
 ax.axis('off')
fig.tight_layout()

Python图像处理之膨胀与腐蚀的操作

正如我们所看到的,水平和垂直的腐蚀以不同的方式影响着图像。使用水平内核我们得到一个垂直方向细长的圆;而使用垂直内核我们得到一个水平方向细长的圆。

你可能会奇怪,为什么使用垂直内核,会得到一个水平方向细长的圆呢?

因为腐蚀函数是分别寻找垂直和水平的线条,并慢慢把它们削掉。膨胀函数将会让我们更清晰的理解这一点。

使用下面的函数设置处理的图像、膨胀内核以及迭代次数。

def multi_dilation(image, kernel, iterations):
 for i in range(iterations):
 image = dilation(image, kernel)
 return image

让我们看一下处理后的图像有什么不同。

dilated_circle = multi_dilation(circ_image, cross, 1)
linecolor = 'red'
fig, ax = plt.subplots(1, 2, figsize=(12, 5))
ax[0].imshow(circ_image, cmap = 'gray');
ax[0].set_title('Original', fontsize = 19)
ax[0].axvline(x = 25, color = linecolor)
ax[0].axvline(x = 75, color = linecolor)
ax[0].axhline(y = 25, color = linecolor)
ax[0].axhline(y = 75, color = linecolor)
ax[1].imshow(dilated_circle, cmap = 'gray');
ax[1].set_title('Dilated', fontsize = 19)
ax[1].axvline(x = 25, color = linecolor)
ax[1].axvline(x = 75, color = linecolor)
ax[1].axhline(y = 25, color = linecolor)
ax[1].axhline(y = 75, color = linecolor)
fig.tight_layout()

Python图像处理之膨胀与腐蚀的操作

可以清楚地看到圆现在已经越过了红线,这清楚地表明它已经扩大了。现在让我们对水平和垂直扩张进行迭代。

ites = [2,4,6,8,10,12,14,16,18,20]
fig, ax = plt.subplots(2, 5, figsize=(17, 5))
for n, ax in enumerate(ax.flatten()):
 ax.set_title(f'Horizontal Iterations : {ites[n]}', fontsize = 
   12)
 new_circle = multi_dilation(circ_image, h_line, ites[n])
 ax.imshow(new_circle, cmap = 'gray');
 ax.axis('off')
fig.tight_layout()
fig, ax = plt.subplots(2, 5, figsize=(17, 5))
for n, ax in enumerate(ax.flatten()):
 ax.set_title(f'Vertical Iterationss : {ites[n]}', fontsize = 12)
 new_circle = multi_dilation(circ_image, v_line, ites[n])
 ax.imshow(new_circle, cmap = 'gray');
 ax.axis('off')
fig.tight_layout()

Python图像处理之膨胀与腐蚀的操作

现在可以非常清楚地看到,水平扩张增加了图像宽度,而垂直扩张增加了图像高度。

现在我们已经了解了膨胀与腐蚀的基本原理,下面来看一个相对复杂的图像。

complex_image = imread('complex_image.png')
imshow(complex_image);

Python图像处理之膨胀与腐蚀的操作

在上面的图像中,我们看到了水平线、垂直线和圆的混合物。我们可以使用膨胀和腐蚀函数孤立地观察每一种形状。

为了得到圆,我们可以先腐蚀垂直的线,再腐蚀水平的线。但要记住最后要对图像进行膨胀,因为腐蚀函数同样腐蚀了圆。

step_1 = multi_erosion(complex_image, h_line,3)
step_2 = multi_erosion(step_1, v_line,3)
step_3 = multi_dilation(step_2, h_line,3)
step_4 = multi_dilation(step_3, v_line,3)
steps = [step_1, step_2, step_3, step_4]
names = ['Step 1', 'Step 2', 'Step 3', 'Step 4']
fig, ax = plt.subplots(2, 2, figsize=(10, 10))
for n, ax in enumerate(ax.flatten()):
 ax.set_title(f'{names[n]}', fontsize = 22)
 ax.imshow(steps[n], cmap = 'gray');
 ax.axis('off')
fig.tight_layout()

Python图像处理之膨胀与腐蚀的操作

同样,下面的代码将得到水平的线。

step_1 = multi_erosion(complex_image, cross, 20)
step_2 = multi_dilation(step_1, h_line, 20)
step_3 = multi_dilation(step_2, v_line,2)
steps = [step_1, step_2, step_3]
names = ['Step 1', 'Step 2', 'Step 3']
fig, ax = plt.subplots(1, 3, figsize=(10, 10))
for n, ax in enumerate(ax.flatten()):
 ax.set_title(f'{names[n]}', fontsize = 22)
 ax.imshow(steps[n], cmap = 'gray');
 ax.axis('off')
fig.tight_layout()

Python图像处理之膨胀与腐蚀的操作

为了得到垂直的线,我们可以创建一个新的内核。

long_v_line = np.array([[0,1,0],
   [0,1,0],
   [0,1,0],
   [0,1,0],
   [0,1,0]])
step_1 = multi_erosion(complex_image, long_v_line, 10)
step_2 = multi_dilation(step_1 ,long_v_line, 10)
steps = [step_1, step_2]
names = ['Step 1', 'Step 2']
fig, ax = plt.subplots(1, 2, figsize=(10, 10))
for n, ax in enumerate(ax.flatten()):
 ax.set_title(f'{names[n]}', fontsize = 22)
 ax.imshow(steps[n], cmap = 'gray');
 ax.axis('off')
fig.tight_layout()

Python图像处理之膨胀与腐蚀的操作

注意,内核并不局限于本文中提到的这几种,可以根据不同的需求自己定义合适的内核。

总结

内核腐蚀和膨胀是图像处理领域需要理解的基本概念。它们甚至可能是任何图像处理模块的第一课。直观地理解它们将是你以后在这个领域成功的关键。

到此这篇关于Python图像处理之膨胀与腐蚀的操作的文章就介绍到这了,更多相关Python图像膨胀与腐蚀内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
python使用pil生成缩略图的方法
Mar 26 Python
python中字典(Dictionary)用法实例详解
May 30 Python
Python 由字符串函数名得到对应的函数(实例讲解)
Aug 10 Python
浅谈Python中带_的变量或函数命名
Dec 04 Python
终端命令查看TensorFlow版本号及路径的方法
Jun 13 Python
详解爬虫被封的问题
Apr 23 Python
python使用pandas处理excel文件转为csv文件的方法示例
Jul 18 Python
python实现高斯判别分析算法的例子
Dec 09 Python
Python常用模块sys,os,time,random功能与用法实例分析
Jan 07 Python
Python操作Excel把数据分给sheet
May 20 Python
opencv 实现特定颜色线条提取与定位操作
Jun 02 Python
Python使用struct处理二进制(pack和unpack用法)
Nov 12 Python
django inspectdb 操作已有数据库数据的使用步骤
Feb 07 #Python
python数据抓取3种方法总结
Feb 07 #Python
python 批量将中文名转换为拼音
Feb 07 #Python
如何用用Python将地址标记在地图上
Feb 07 #Python
python 三种方法提取pdf中的图片
Feb 07 #Python
Python 转移文件至云对象存储的方法
Feb 07 #Python
Python调用SMTP服务自动发送Email的实现步骤
Feb 07 #Python
You might like
php使用explode()函数将字符串拆分成数组的方法
2015/02/17 PHP
PHP实现根据银行卡号判断银行
2015/04/29 PHP
ThinkPHP数据操作方法总结
2015/09/28 PHP
PHP实现基于mysqli的Model基类完整实例
2016/04/08 PHP
jquery ajax 检测用户注册时用户名是否存在
2009/11/03 Javascript
javascript instanceof 内部机制探析
2010/10/15 Javascript
window.addEventListener来解决让一个js事件执行多个函数
2012/12/26 Javascript
探讨js中的双感叹号判断
2013/11/11 Javascript
Bootstrap轮播插件简单使用方法介绍
2016/06/21 Javascript
js事件驱动机制 浏览器兼容处理方法
2016/07/23 Javascript
详解JS中定时器setInterval和setTImeout的this指向问题
2017/01/06 Javascript
JavaScript定时器制作弹窗小广告
2017/02/05 Javascript
xmlplus组件设计系列之下拉刷新(PullRefresh)(6)
2017/05/03 Javascript
学习Vue组件实例
2018/04/28 Javascript
使用mpvue搭建一个初始小程序及项目配置方法
2018/12/03 Javascript
layui-table表复选框勾选的所有行数据获取的例子
2019/09/13 Javascript
[01:13]这,就是刀塔
2014/07/16 DOTA
[00:49]完美世界DOTA2联赛10月28日开团时刻:随便打
2020/10/29 DOTA
python基础教程之分支、循环简单用法
2016/06/16 Python
Tensorflow 训练自己的数据集将数据直接导入到内存
2018/06/19 Python
django drf框架中的user验证以及JWT拓展的介绍
2019/08/12 Python
WxPython实现无边框界面
2019/11/18 Python
python切片作为占位符使用实例讲解
2021/02/17 Python
CSS3轻松实现圆角效果
2017/11/09 HTML / CSS
英国最好的包装供应商:Priory Direct
2019/12/17 全球购物
JMS中Topic和Queue有什么区别
2013/05/15 面试题
医学生求职自荐信
2013/10/25 职场文书
应届生保险求职信
2013/11/11 职场文书
幼儿教师演讲稿
2014/05/06 职场文书
调研座谈会发言材料
2014/08/23 职场文书
质监局领导班子践行群众路线整改方案
2014/10/26 职场文书
乡镇群众路线整改落实情况汇报
2014/10/28 职场文书
影视后期实训报告
2014/11/05 职场文书
养成教育工作总结
2015/08/13 职场文书
创作书写之导游词实用技巧分享(干货)
2019/12/20 职场文书
python实现手机推送 代码也就10行左右
2022/04/12 Python