• 售前

  • 售后

热门帖子
入门百科

Python图像处置惩罚之膨胀与腐蚀的使用

[复制链接]
123456868 显示全部楼层 发表于 2021-10-25 19:31:51 |阅读模式 打印 上一主题 下一主题
弁言

膨胀与腐蚀是图像处置惩罚中两种最根本的形态学操作,膨胀将目标点融合到配景中,向外部扩展,腐蚀与膨胀意义相反,消除连通的界限,使界限向内紧缩。在本文中我们将了解利用内核的图像膨胀与腐蚀的根本原理。
让我们开始吧,同样我们必要导入必须的库。
  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. from skimage.io import imread, imshow
  4. from skimage.draw import circle
  5. from skimage.morphology import erosion, dilation
复制代码
起首让我们创建一个容易操作的形状--一个简单的圆。
  1. circ_image = np.zeros((100, 100))
  2. circ_image[circle(50, 50, 25)] = 1
  3. imshow(circ_image);
复制代码

如今让我们界说一个内核。
  1. cross = np.array([[0,1,0],
  2.    [1,1,1],
  3.    [0,1,0]])
  4. imshow(cross, cmap = 'gray');
复制代码

将腐蚀函数应用到创建的圆上。
  1. eroded_circle = erosion(circ_image, cross)
  2. imshow(eroded_circle);
复制代码

图像看起来几乎一模一样。要看到那些微小的差别,我们必须细致查看图像。
  1. linecolor = 'red'
  2. fig, ax = plt.subplots(1, 2, figsize=(12, 5))
  3. ax[0].imshow(circ_image, cmap = 'gray');
  4. ax[0].set_title('Original', fontsize = 19)
  5. ax[0].axvline(x = 25, color = linecolor)
  6. ax[0].axvline(x = 75, color = linecolor)
  7. ax[0].axhline(y = 25, color = linecolor)
  8. ax[0].axhline(y = 75, color = linecolor)
  9. ax[1].imshow(eroded_circle, cmap = 'gray');
  10. ax[1].set_title('Eroded', fontsize = 19)
  11. ax[1].axvline(x = 25, color = linecolor)
  12. ax[1].axvline(x = 75, color = linecolor)
  13. ax[1].axhline(y = 25, color = linecolor)
  14. ax[1].axhline(y = 75, color = linecolor)
  15. fig.tight_layout()
复制代码

我们可以看到,被腐蚀的圆已经略微缩小了。这就是腐蚀一个对象的意义。如果我们对腐蚀函数进行迭代,它的效果会变得非常显着。
  1. def multi_erosion(image, kernel, iterations):
  2. for i in range(iterations):
  3. image = erosion(image, kernel)
  4. return image
  5. ites = [2,4,6,8,10,12,14,16,18,20]
  6. fig, ax = plt.subplots(2, 5, figsize=(17, 5))
  7. for n, ax in enumerate(ax.flatten()):
  8. ax.set_title(f'Iterations : {ites[n]}', fontsize = 16)
  9. new_circle = multi_erosion(circ_image, cross, ites[n])
  10. ax.imshow(new_circle, cmap = 'gray');
  11. ax.axis('off')
  12. fig.tight_layout()
复制代码

上图清晰地显示了图像是如何被腐蚀的。如今让我们实行改变内核,如果我们利用水平线和垂直线内核代替交叉内核会怎样呢?
  1. h_line = np.array([[0,0,0],
  2.    [1,1,1],
  3.    [0,0,0]])
  4. v_line = np.array([[0,1,0],
  5.    [0,1,0],
  6.    [0,1,0]])
  7. fig, ax = plt.subplots(1, 2, figsize=(15, 5))
  8. ax[0].imshow(h_line, cmap='gray');
  9. ax[1].imshow(v_line, cmap='gray');
  10. fig.tight_layout()
复制代码
  1. ites = [2,4,6,8,10,12,14,16,18,20]
  2. fig, ax = plt.subplots(2, 5, figsize=(17, 5))
  3. for n, ax in enumerate(ax.flatten()):
  4. ax.set_title(f'Horizontal Iterations : {ites[n]}', fontsize = 12)
  5. new_circle = multi_erosion(circ_image, h_line, ites[n])
  6. ax.imshow(new_circle, cmap = 'gray');
  7. ax.axis('off')
  8. fig.tight_layout()
  9. fig, ax = plt.subplots(2, 5, figsize=(17, 5))
  10. for n, ax in enumerate(ax.flatten()):
  11. ax.set_title(f'Vertical Iterationss : {ites[n]}', fontsize = 12)
  12. new_circle = multi_erosion(circ_image, v_line, ites[n])
  13. ax.imshow(new_circle, cmap = 'gray');
  14. ax.axis('off')
  15. fig.tight_layout()
复制代码

正如我们所看到的,水平和垂直的腐蚀以差别的方式影响着图像。利用水平内核我们得到一个垂直方向细长的圆;而利用垂直内核我们得到一个水平方向细长的圆。
你大概会奇怪,为什么利用垂直内核,会得到一个水平方向细长的圆呢?
因为腐蚀函数是分别寻找垂直和水平的线条,并逐步把它们削掉。膨胀函数将会让我们更清晰的理解这一点。
利用下面的函数设置处置惩罚的图像、膨胀内核以及迭代次数。
  1. def multi_dilation(image, kernel, iterations):
  2. for i in range(iterations):
  3. image = dilation(image, kernel)
  4. return image
复制代码
让我们看一下处置惩罚后的图像有什么差别。
  1. dilated_circle = multi_dilation(circ_image, cross, 1)
  2. linecolor = 'red'
  3. fig, ax = plt.subplots(1, 2, figsize=(12, 5))
  4. ax[0].imshow(circ_image, cmap = 'gray');
  5. ax[0].set_title('Original', fontsize = 19)
  6. ax[0].axvline(x = 25, color = linecolor)
  7. ax[0].axvline(x = 75, color = linecolor)
  8. ax[0].axhline(y = 25, color = linecolor)
  9. ax[0].axhline(y = 75, color = linecolor)
  10. ax[1].imshow(dilated_circle, cmap = 'gray');
  11. ax[1].set_title('Dilated', fontsize = 19)
  12. ax[1].axvline(x = 25, color = linecolor)
  13. ax[1].axvline(x = 75, color = linecolor)
  14. ax[1].axhline(y = 25, color = linecolor)
  15. ax[1].axhline(y = 75, color = linecolor)
  16. fig.tight_layout()
复制代码
可以清晰地看到圆如今已经越过了红线,这清晰地表明它已经扩大了。如今让我们对水平和垂直扩张进行迭代。
  1. ites = [2,4,6,8,10,12,14,16,18,20]
  2. fig, ax = plt.subplots(2, 5, figsize=(17, 5))
  3. for n, ax in enumerate(ax.flatten()):
  4. ax.set_title(f'Horizontal Iterations : {ites[n]}', fontsize =
  5.    12)
  6. new_circle = multi_dilation(circ_image, h_line, ites[n])
  7. ax.imshow(new_circle, cmap = 'gray');
  8. ax.axis('off')
  9. fig.tight_layout()
  10. fig, ax = plt.subplots(2, 5, figsize=(17, 5))
  11. for n, ax in enumerate(ax.flatten()):
  12. ax.set_title(f'Vertical Iterationss : {ites[n]}', fontsize = 12)
  13. new_circle = multi_dilation(circ_image, v_line, ites[n])
  14. ax.imshow(new_circle, cmap = 'gray');
  15. ax.axis('off')
  16. fig.tight_layout()
复制代码
如今可以非常清晰地看到,水平扩张增长了图像宽度,而垂直扩张增长了图像高度。
如今我们已经了解了膨胀与腐蚀的根本原理,下面来看一个相对复杂的图像。
  1. complex_image = imread('complex_image.png')
  2. imshow(complex_image);
复制代码
在上面的图像中,我们看到了水平线、垂直线和圆的混淆物。我们可以利用膨胀和腐蚀函数孤立地观察每一种形状。
为了得到圆,我们可以先腐蚀垂直的线,再腐蚀水平的线。但要记着最后要对图像进行膨胀,因为腐蚀函数同样腐蚀了圆。
  1. step_1 = multi_erosion(complex_image, h_line,3)
  2. step_2 = multi_erosion(step_1, v_line,3)
  3. step_3 = multi_dilation(step_2, h_line,3)
  4. step_4 = multi_dilation(step_3, v_line,3)
  5. steps = [step_1, step_2, step_3, step_4]
  6. names = ['Step 1', 'Step 2', 'Step 3', 'Step 4']
  7. fig, ax = plt.subplots(2, 2, figsize=(10, 10))
  8. for n, ax in enumerate(ax.flatten()):
  9. ax.set_title(f'{names[n]}', fontsize = 22)
  10. ax.imshow(steps[n], cmap = 'gray');
  11. ax.axis('off')
  12. fig.tight_layout()
复制代码
同样,下面的代码将得到水平的线。
  1. step_1 = multi_erosion(complex_image, cross, 20)
  2. step_2 = multi_dilation(step_1, h_line, 20)
  3. step_3 = multi_dilation(step_2, v_line,2)
  4. steps = [step_1, step_2, step_3]
  5. names = ['Step 1', 'Step 2', 'Step 3']
  6. fig, ax = plt.subplots(1, 3, figsize=(10, 10))
  7. for n, ax in enumerate(ax.flatten()):
  8. ax.set_title(f'{names[n]}', fontsize = 22)
  9. ax.imshow(steps[n], cmap = 'gray');
  10. ax.axis('off')
  11. fig.tight_layout()
复制代码
为了得到垂直的线,我们可以创建一个新的内核。
  1. long_v_line = np.array([[0,1,0],
  2.    [0,1,0],
  3.    [0,1,0],
  4.    [0,1,0],
  5.    [0,1,0]])
  6. step_1 = multi_erosion(complex_image, long_v_line, 10)
  7. step_2 = multi_dilation(step_1 ,long_v_line, 10)
  8. steps = [step_1, step_2]
  9. names = ['Step 1', 'Step 2']
  10. fig, ax = plt.subplots(1, 2, figsize=(10, 10))
  11. for n, ax in enumerate(ax.flatten()):
  12. ax.set_title(f'{names[n]}', fontsize = 22)
  13. ax.imshow(steps[n], cmap = 'gray');
  14. ax.axis('off')
  15. fig.tight_layout()
复制代码

注意,内核并不范围于本文中提到的这几种,可以根据差别的需求本身界说合适的内核。
总结

内核腐蚀和膨胀是图像处置惩罚范畴必要理解的根本概念。它们乃至大概是任何图像处置惩罚模块的第一课。直观地理解它们将是你以后在这个范畴成功的关键。
到此这篇关于Python图像处置惩罚之膨胀与腐蚀的操作的文章就介绍到这了,更多相干Python图像膨胀与腐蚀内容请搜刮草根技能分享以前的文章或继承欣赏下面的相干文章渴望大家以后多多支持草根技能分享!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

帖子地址: 

回复

使用道具 举报

分享
推广
火星云矿 | 预约S19Pro,享500抵1000!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

草根技术分享(草根吧)是全球知名中文IT技术交流平台,创建于2021年,包含原创博客、精品问答、职业培训、技术社区、资源下载等产品服务,提供原创、优质、完整内容的专业IT技术开发社区。
  • 官方手机版

  • 微信公众号

  • 商务合作