python数字图像处理之高级形态学处理


Posted in Python onApril 27, 2018

形态学处理,除了最基本的膨胀、腐蚀、开/闭运算、黑/白帽处理外,还有一些更高级的运用,如凸包,连通区域标记,删除小块区域等。

1、凸包

凸包是指一个凸多边形,这个凸多边形将图片中所有的白色像素点都包含在内。

函数为:

skimage.morphology.convex_hull_image(image)

输入为二值图像,输出一个逻辑二值图像。在凸包内的点为True, 否则为False

例:

import matplotlib.pyplot as plt
from skimage import data,color,morphology

#生成二值测试图像
img=color.rgb2gray(data.horse())
img=(img<0.5)*1

chull = morphology.convex_hull_image(img)

#绘制轮廓
fig, axes = plt.subplots(1,2,figsize=(8,8))
ax0, ax1= axes.ravel()
ax0.imshow(img,plt.cm.gray)
ax0.set_title('original image')

ax1.imshow(chull,plt.cm.gray)
ax1.set_title('convex_hull image')

python数字图像处理之高级形态学处理

convex_hull_image()是将图片中的所有目标看作一个整体,因此计算出来只有一个最小凸多边形。如果图中有多个目标物体,每一个物体需要计算一个最小凸多边形,则需要使用convex_hull_object()函数。

函数格式:skimage.morphology.convex_hull_object(image,neighbors=8)

输入参数image是一个二值图像,neighbors表示是采用4连通还是8连通,默认为8连通。

例:

import matplotlib.pyplot as plt
from skimage import data,color,morphology,feature

#生成二值测试图像
img=color.rgb2gray(data.coins())
#检测canny边缘,得到二值图片
edgs=feature.canny(img, sigma=3, low_threshold=10, high_threshold=50) 

chull = morphology.convex_hull_object(edgs)

#绘制轮廓
fig, axes = plt.subplots(1,2,figsize=(8,8))
ax0, ax1= axes.ravel()
ax0.imshow(edgs,plt.cm.gray)
ax0.set_title('many objects')
ax1.imshow(chull,plt.cm.gray)
ax1.set_title('convex_hull image')
plt.show()

python数字图像处理之高级形态学处理

2、连通区域标记

在二值图像中,如果两个像素点相邻且值相同(同为0或同为1),那么就认为这两个像素点在一个相互连通的区域内。而同一个连通区域的所有像素点,都用同一个数值来进行标记,这个过程就叫连通区域标记。在判断两个像素是否相邻时,我们通常采用4连通或8连通判断。在图像中,最小的单位是像素,每个像素周围有8个邻接像素,常见的邻接关系有2种:4邻接与8邻接。4邻接一共4个点,即上下左右,如下左图所示。8邻接的点一共有8个,包括了对角线位置的点,如下右图所示。

python数字图像处理之高级形态学处理

在skimage包中,我们采用measure子模块下的label()函数来实现连通区域标记。

函数格式:

skimage.measure.label(image,connectivity=None)

参数中的image表示需要处理的二值图像,connectivity表示连接的模式,1代表4邻接,2代表8邻接。

输出一个标记数组(labels), 从0开始标记。

import numpy as np
import scipy.ndimage as ndi
from skimage import measure,color
import matplotlib.pyplot as plt

#编写一个函数来生成原始二值图像
def microstructure(l=256):
  n = 5
  x, y = np.ogrid[0:l, 0:l] #生成网络
  mask = np.zeros((l, l))
  generator = np.random.RandomState(1) #随机数种子
  points = l * generator.rand(2, n**2)
  mask[(points[0]).astype(np.int), (points[1]).astype(np.int)] = 1
  mask = ndi.gaussian_filter(mask, sigma=l/(4.*n)) #高斯滤波
  return mask > mask.mean()

data = microstructure(l=128)*1 #生成测试图片

labels=measure.label(data,connectivity=2) #8连通区域标记
dst=color.label2rgb(labels) #根据不同的标记显示不同的颜色
print('regions number:',labels.max()+1) #显示连通区域块数(从0开始标记)

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 4))
ax1.imshow(data, plt.cm.gray, interpolation='nearest')
ax1.axis('off')
ax2.imshow(dst,interpolation='nearest')
ax2.axis('off')

fig.tight_layout()
plt.show()

在代码中,有些地方乘以1,则可以将bool数组快速地转换为int数组。

结果如图:有10个连通的区域,标记为0-9

python数字图像处理之高级形态学处理

如果想分别对每一个连通区域进行操作,比如计算面积、外接矩形、凸包面积等,则需要调用measure子模块的regionprops()函数。该函数格式为:

skimage.measure.regionprops(label_image)

返回所有连通区块的属性列表,常用的属性列表如下表:

属性名称 类型 描述
area int 区域内像素点总数
bbox tuple 边界外接框(min_row, min_col, max_row, max_col)
centroid array 质心坐标
convex_area int 凸包内像素点总数
convex_image ndarray 和边界外接框同大小的凸包
coords ndarray 区域内像素点坐标
Eccentricity  float 离心率
equivalent_diameter  float 和区域面积相同的圆的直径
euler_number int 区域欧拉数
extent  float 区域面积和边界外接框面积的比率
filled_area int 区域和外接框之间填充的像素点总数
perimeter  float 区域周长
label int 区域标记

3、删除小块区域

有些时候,我们只需要一些大块区域,那些零散的、小块的区域,我们就需要删除掉,则可以使用morphology子模块的remove_small_objects()函数。

函数格式:skimage.morphology.remove_small_objects(ar,min_size=64,connectivity=1,in_place=False)

参数:

ar: 待操作的bool型数组。

min_size: 最小连通区域尺寸,小于该尺寸的都将被删除。默认为64.

connectivity: 邻接模式,1表示4邻接,2表示8邻接

in_place: bool型值,如果为True,表示直接在输入图像中删除小块区域,否则进行复制后再删除。默认为False.

返回删除了小块区域的二值图像。

import numpy as np
import scipy.ndimage as ndi
from skimage import morphology
import matplotlib.pyplot as plt

#编写一个函数来生成原始二值图像
def microstructure(l=256):
  n = 5
  x, y = np.ogrid[0:l, 0:l] #生成网络
  mask = np.zeros((l, l))
  generator = np.random.RandomState(1) #随机数种子
  points = l * generator.rand(2, n**2)
  mask[(points[0]).astype(np.int), (points[1]).astype(np.int)] = 1
  mask = ndi.gaussian_filter(mask, sigma=l/(4.*n)) #高斯滤波
  return mask > mask.mean()

data = microstructure(l=128) #生成测试图片

dst=morphology.remove_small_objects(data,min_size=300,connectivity=1)

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 4))
ax1.imshow(data, plt.cm.gray, interpolation='nearest')
ax2.imshow(dst,plt.cm.gray,interpolation='nearest')

fig.tight_layout()
plt.show()

在此例中,我们将面积小于300的小块区域删除(由1变为0),结果如下图:

python数字图像处理之高级形态学处理

4、综合示例:阈值分割+闭运算+连通区域标记+删除小区块+分色显示

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
from skimage import data,filter,segmentation,measure,morphology,color

#加载并裁剪硬币图片
image = data.coins()[50:-50, 50:-50]

thresh =filter.threshold_otsu(image) #阈值分割
bw =morphology.closing(image > thresh, morphology.square(3)) #闭运算

cleared = bw.copy() #复制
segmentation.clear_border(cleared) #清除与边界相连的目标物

label_image =measure.label(cleared) #连通区域标记
borders = np.logical_xor(bw, cleared) #异或
label_image[borders] = -1
image_label_overlay =color.label2rgb(label_image, image=image) #不同标记用不同颜色显示

fig,(ax0,ax1)= plt.subplots(1,2, figsize=(8, 6))
ax0.imshow(cleared,plt.cm.gray)
ax1.imshow(image_label_overlay)

for region in measure.regionprops(label_image): #循环得到每一个连通区域属性集
  
  #忽略小区域
  if region.area < 100:
    continue

  #绘制外包矩形
  minr, minc, maxr, maxc = region.bbox
  rect = mpatches.Rectangle((minc, minr), maxc - minc, maxr - minr,
               fill=False, edgecolor='red', linewidth=2)
  ax1.add_patch(rect)
fig.tight_layout()
plt.show()

python数字图像处理之高级形态学处理

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
跟老齐学Python之再深点,更懂list
Sep 20 Python
python中sleep函数用法实例分析
Apr 29 Python
python用模块zlib压缩与解压字符串和文件的方法
Dec 16 Python
numpy.transpose对三维数组的转置方法
Apr 17 Python
Python中pandas模块DataFrame创建方法示例
Jun 20 Python
python3 selenium自动化 下拉框定位的例子
Aug 23 Python
Python数据可视化:顶级绘图库plotly详解
Dec 07 Python
Python实现栈的方法详解【基于数组和单链表两种方法】
Feb 22 Python
django API 中接口的互相调用实例
Apr 01 Python
python3读取autocad图形文件.py实例
Jun 05 Python
Python SMTP发送电子邮件的示例
Sep 23 Python
python 通过 pybind11 使用Eigen加速代码的步骤
Dec 07 Python
python线程池threadpool实现篇
Apr 27 #Python
python数字图像处理之骨架提取与分水岭算法
Apr 27 #Python
python多线程之事件Event的使用详解
Apr 27 #Python
python线程池threadpool使用篇
Apr 27 #Python
Python实现删除时保留特定文件夹和文件的示例
Apr 27 #Python
python中yaml配置文件模块的使用详解
Apr 27 #Python
python 拷贝特定后缀名文件,并保留原始目录结构的实例
Apr 27 #Python
You might like
PHP对象Object的概念 介绍
2012/06/14 PHP
php学习笔记之面向对象编程
2012/12/29 PHP
PHP autoload与spl_autoload自动加载机制的深入理解
2013/06/05 PHP
ThinkPHP关于session的操作方法汇总
2014/07/18 PHP
ThinkPHP中的三大自动简介
2014/08/22 PHP
ioncube_loader_win_5.2.dll的错误解决方法
2015/01/04 PHP
php使用simplexml_load_file加载XML文件并显示XML的方法
2015/03/19 PHP
PHP读MYSQL中文乱码的快速解决方法
2016/10/01 PHP
PHP7多线程搭建教程
2017/04/21 PHP
PHP使用DOM对XML解析处理操作示例
2019/07/04 PHP
讨论javascript(一)工厂方式 js面象对象的定义方法
2009/12/15 Javascript
深入理解JavaScript定时机制
2010/10/29 Javascript
js实现iGoogleDivDrag模块拖动层拖动特效的方法
2015/03/04 Javascript
浅析C/C++,Java,PHP,JavaScript,Json数组、对象赋值时最后一个元素后面是否可以带逗号
2016/03/22 Javascript
基于bootstrap风格的弹框插件
2016/12/28 Javascript
less简单入门(CSS 预处理语言)
2017/03/08 Javascript
详解利用jsx写vue组件的方法示例
2017/07/17 Javascript
JS获取一个表单字段中多条数据并转化为json格式
2017/10/17 Javascript
JS实现的ajax和同源策略(实例讲解)
2017/12/01 Javascript
使用ESLint禁止项目导入特定模块的方法步骤
2019/03/04 Javascript
JavaScript定时器设置、使用与倒计时案例详解
2019/07/08 Javascript
CentOS下Python3的安装及创建虚拟环境的方法
2018/11/28 Python
windows安装TensorFlow和Keras遇到的问题及其解决方法
2019/07/10 Python
用Python将Excel数据导入到SQL Server的例子
2019/08/24 Python
python环境下安装opencv库的方法
2020/03/05 Python
意大利香水和化妆品购物网站:Parfimo.it
2019/10/06 全球购物
优秀团员个人的自我评价
2013/10/02 职场文书
毕业生医学检验求职信
2013/10/16 职场文书
信息系统专业个人求职信范文
2013/12/07 职场文书
党校培训思想汇报
2014/01/03 职场文书
纠纷协议书
2014/04/16 职场文书
预备党员自我批评思想汇报
2014/10/10 职场文书
2014年人力资源工作总结
2014/11/19 职场文书
党校培训学习心得体会
2016/01/06 职场文书
2016年安康杯竞赛活动总结
2016/04/05 职场文书
Python基础之tkinter图形化界面学习
2021/04/29 Python