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

作者:Warmer_Sweeter 时间:2022-10-07 19:47:06 

引言

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

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


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图像处理之膨胀与腐蚀的操作

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

来源:https://blog.csdn.net/weixin_38739735/article/details/111940442

标签:Python,图像膨胀,腐蚀,图像处理
0
投稿

猜你喜欢

  • Python实现信息管理系统

    2022-10-08 22:28:39
  • python实现随机漫步算法

    2022-07-23 19:08:05
  • Python全栈之进程和守护进程

    2021-11-25 18:05:44
  • 如何取消pyecharts绘制地图时默认显示小圆点标识

    2021-05-06 19:43:35
  • Python基于pyecharts实现关联图绘制

    2021-04-08 12:05:45
  • python输出小数精度控制的方法

    2021-07-18 16:35:26
  • 优化 SQL Server 索引的小技巧

    2012-10-07 11:00:07
  • 用于打印的页面设计

    2009-07-06 12:47:00
  • windows中安装Python3.8.0的实现方法

    2022-11-22 00:18:09
  • python使用两种发邮件的方式smtp和outlook示例

    2021-02-12 13:31:54
  • mysql limit 分页的用法及注意要点

    2024-01-21 06:44:50
  • python编程实现希尔排序

    2022-11-05 22:21:57
  • 在Python 中同一个类两个函数间变量的调用方法

    2022-07-02 04:53:57
  • 详解python UDP 编程

    2023-06-11 22:31:44
  • python 中文编码乱码问题的解决

    2021-03-06 16:43:58
  • python logging 日志的级别调整方式

    2021-09-15 10:08:29
  • 用Python实现将一张图片分成9宫格的示例

    2022-08-12 12:26:27
  • Keras 多次加载model出错的解决方案

    2023-11-01 20:52:35
  • python爬虫-模拟微博登录功能

    2021-12-13 21:54:08
  • python制作抽奖程序代码详解

    2022-05-04 08:51:18
  • asp之家 网络编程 m.aspxhome.com