欢迎关注 “小白玩转Python”,发现更多 “有趣”

引言

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

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

import numpy as npimport matplotlib.pyplot as pltfrom skimage.io import imread, imshowfrom skimage.draw import circlefrom skimage.morphology import erosion, dilation

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

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

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

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

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

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

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

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()

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

def multi_erosion(image, kernel, iterations):    for i in range(iterations):        image = erosion(image, kernel)    return imageites = [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()

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

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()

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()

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

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

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

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

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()

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

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()

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

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

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

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

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

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()

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

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()

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

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()

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

总结

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

·  END  ·HAPPY LIFE

什么叫做形态学图像处理_Python图像处理膨胀与腐蚀相关推荐

  1. OpenCV——图像处理入门:膨胀与腐蚀、图像模糊、边缘检测

    全部外部依赖项: 1 opencv_aruco341d.lib 2 opencv_bgsegm341d.lib 3 opencv_calib3d341d.lib 4 opencv_bioinspire ...

  2. opencv进阶学习笔记13:图像形态学操作大全(膨胀,腐蚀,开闭,黑帽,顶帽,梯度)python版

    基础版学习笔记: python3+opencv学习笔记汇总目录(适合基础入门学习) 进阶版笔记目录链接: python+opencv进阶版学习笔记目录(适合有一定基础) 基础版形态学: opencv学 ...

  3. pythonopencv图像形态_python+opencv图像形态学处理详细解释(膨胀、腐蚀、开闭运算、礼帽和黑猫)...

    python+opencv图像形态学处理 本篇博客主要是关于形态学中的腐蚀.膨胀.开运算.闭运算.礼帽和黑帽的函数用法. 内容会比较,为方便查阅.代码的解释会写在代码中. 用于测试的图像原图: 一.腐 ...

  4. python批量图像处理_python图像处理(4)之图像批量处理

    当对一批图片进行处理时,有如下方法: 循环进行处理 调用程序自带的图片集合来处理 图片集合函数为: skimage.io.ImageCollection(load_pattern, load_func ...

  5. 膨胀和腐蚀 (形态学操作简介)

    一.形态学操作简介 简单来说,形态学操作就是基于形状的一系列图像处理操作,通过将 结构元素 作用于输入图像来产生输出图像.(主要是基于集合论基础上的形态学数学) 基本的形态学操作包括:膨胀.腐蚀.开. ...

  6. 《OpenCV3编程入门》学习笔记6 图像处理(三)形态学滤波(1):腐蚀与膨胀

    第6章 图像处理 6.3 形态学滤波(1):腐蚀与膨胀 6.3.1 形态学概述 1.数学形态学(Mathematical morphology):建立在格论和拓扑学基础上的图像分析学科,是数学形态学图 ...

  7. 什么叫做形态学图像处理_图像形态学处理中的膨胀与腐蚀介绍

    重要:本文最后更新于2020-03-04 10:40:53,某些文章具有时效性,若有错误或已失效,请在下方留言或联系代码狗. 本文主要是对图像形态学处理中的膨胀.腐蚀运算方法介绍及在图像中实现的理论基 ...

  8. 图像算法七:【形态学图像处理】二值运算、膨胀、腐蚀

    二值图像腐蚀函数 [算法说明]:二值图像腐蚀操作属于图像形态学的范畴,形态学运算是只针对二值图像进行,并依据数学形态学(Mathermatical Morphogy)集合论方法发展起来的数字图像处理方 ...

  9. 图像处理一:形态学膨胀和腐蚀

    一.形态学概述 形态学(morphology)一词通常表示生物学的一个分支,该分支主要研究动植物的形态和结构,而图像处理中的形态学主要是指数学形态学. 数学形态学(Mathematical morph ...

最新文章

  1. python字符串类库_Python 常用类库
  2. java 庖丁解牛api_Java Restful API Best Practices
  3. 32 墨水屏股票显示器_炒股护眼新选择 | 电子墨水显示器amp;平板盯盘效果(附视频)...
  4. 强!chrome彻底关闭自动升级新方法实例演示,终于解决了chrome自动升级的烦恼
  5. JAVA中indexOf函数和lastindexOf函数
  6. ABAP Authorization trace工具
  7. SQL Server2008 表旋转(pivot)技术
  8. 小程序 显示细线_精心设计:高密度显示器上的细线
  9. Linux常用命令(知道啦就赶紧收藏吧)
  10. AndroidStudio Git 更改gitlab 地址
  11. c语言设计底层,【学习小总结】C语言的底层开发
  12. T7315 yyy矩阵折叠(长)
  13. MySQL索引详细介绍
  14. javascript中的弹框
  15. Base64编码流程
  16. Eclipse主题设置
  17. 反欺诈模型常用开发工具
  18. 如何随意切换Python版本
  19. 游侠随笔:关于业务型数据库审计 有图有真相
  20. 虚拟机更新升级,原来的GuestAdditions versions版本不匹配

热门文章

  1. Ubuntu18.04编译pulseaudio14.x(八)
  2. got、plt表介绍
  3. 音频audio/sound声卡驱动分析
  4. Android NDK开发从0到1
  5. Anroid camera + mediacodec
  6. Vue之安装Google开发插件
  7. linux学习笔记:yum命令的常见用法
  8. 独立的定义有多重等价表述方式
  9. 进阶04 4 Collection集合类+Iterator迭代器+增强for+泛型
  10. python客户端与服务器端_Python实现的FTP通信客户端与服务器端功能示例