Python OpenCV 形态学 (六)
形态学的操作包括:腐蚀、膨胀、细化、开运算、闭运算
数字图像处理中的形态学处理是指将数字形态学作为工具从图像中提取对于表达和描绘区域形状有用处的图像分量,
比如:边界、骨架、以及凸壳,还包括用于预处理或后处理的形态学过滤、细化和修剪等。图像形态学处理中主要是
二值图像。
一 基本概念:
1. 二值图像:
二值图像是每个像素只有两个可能值的数字图像。常用黑白、B&W、单色图像表示二值图像,但是也可以用来表示
每个像素只有一个采样值的任何图像,例如灰度图像等。
二值图像经常出现在数字图像处理中作为图像掩码或者在图像分割、二值化和dithering的结果中出现。二值图像经常
使用位图格式存储。所以可以解释为二维整数格 Z2 ,
1. 二值图像的逻辑运算
在图像处理中主要用到的逻辑运算有: 与、或、非(求补)。
2. 膨胀
膨胀和腐蚀是形态学处理的基础。
是以得到B的相对与它自身原点的映像并且由Z对映像进行移位为基础的。A被B膨胀是所有位移Z的集合,这样,和A至少
有一个元素是重叠的。
过程:1. 用结构元素B,扫描图像A的每一个像素
2. 用结构元素与其覆盖的二值图像做 “与” 操作
3. 如果都为0,结果图像的该像素为0;否则为1
3. 腐蚀
对Z中的集合A和B,B对A进行腐蚀的整个过程如下:
1. 用结构元素B,扫描图像A的每一个像素
2. 用结构元素与其覆盖的二值图像做 “与”操作
3. 如果都为1,结果图像的该像素为1. 否则为0
腐蚀处理的结果是使原来的二值图像减小一圈
4. 匹配
5. 开闭运算
开运算:是先腐蚀,后膨胀处理。
闭运算:是先膨胀,后腐蚀处理。
6. 细化
图像细化一般作为一种图像预处理技术出现,目的是提取源图像的骨架,即将原图像中线条宽度大于1个像素的线条细化成
只有一个像素宽,形成“骨架”,形成骨架后能比较容易的分析图像,如提取图像的特征。
细化基本思想是“层层剥夺”,即从线条边缘开始一层一层向里剥夺,直到线条剩下一个像素的为止:图像细化大大地压缩了
原始图像的数据量,并保持其形状的基本拓扑结构不变,
细化算法应满足以下条件:
1.) 将条形区域变成一条薄线;
2.)薄线应位于原条形区域的中心:
3.) 薄线应保持原图像的拓扑特性.
细化分成串行细化和并行细化,串行细化即是一边检测满足细化条件的点,一边删除细化点;并行细化即是检测细化点的时候
不进行点的删除只进行标记,而在检测完整幅图像后一次性去除要细化的点。
常用的图像细化算法有 hilditch 算法, pavlidis 算法和 rosenfeld 算法等。
注: 进行细化算法前要先对图像进行二值化,即图像中只包含 (黑)和 (白)两种颜色。
二: 定义结构元素
形态学处理的核心就是定义结构元素,在 Opencv python 中,使用自带的 getStructuringElement 函数,也可以使用
Numpy 的 ndarray 来定义一个结构元素。
1. 使用getStructuringElement 定义一个结构元素。
element = cv2.getStructuringElement(cv2.MORPH_CROSS,(5,5)) # MORPH_CROSS 十字形结构
这里定义了一个 5 * 5 的十字形结构元素
2. 使用NumPy 的 ndarray 来定义结构元素
element = np.uint8(np.zeros((5,5)))
getStructuringElement 与 Numpy 定义的元素结构是完全一样的
[[0 0 1 0 0] [0 0 1 0 0] [1 1 1 1 1] [0 0 1 0 0] [0 0 1 0 0]]
三: 腐蚀 膨胀
效果示例代码:
#!/usr/bin/env python
# encoding: utf-8 import cv2
import numpy as np img = cv2.imread('2.jpg',0)
#OpenCV定义的结构元素
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(3, 3)) #显示原始二值图像
cv2.imshow("original",img)#腐蚀图像
eroded = cv2.erode(img,kernel)
#显示腐蚀后的图像
cv2.imshow("Eroded Image",eroded); #膨胀图像
dilated = cv2.dilate(img,kernel)
#显示膨胀后的图像
cv2.imshow("Dilated Image",dilated);
#原图像
cv2.imshow("Origin", img) #NumPy定义的结构元素
NpKernel = np.uint8(np.ones((3,3)))
Nperoded = cv2.erode(img,NpKernel)
#显示腐蚀后的图像
cv2.imshow("Eroded by NumPy kernel",Nperoded); cv2.waitKey(0)
cv2.destroyAllWindows()
效果图:
注意:
腐蚀和膨胀,表面看上去好像是一对互逆的操作,实际上,这两种操作不具有互逆的关系。
四: 开运算 闭运算
开运算和闭运算正是依据腐蚀和膨胀的不可逆性演变而来。
开运算和闭运算是将腐蚀和膨胀照一定的次序进行处理,两者也是不可逆的,即先开后闭运算并不能得到原先的图像。
使用示例代码:
#!/usr/bin/env python
# encoding: utf-8 import cv2
import numpy as np img = cv2.imread('2.jpg',0)
#定义结构元素
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(5, 5)) #闭运算
closed = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
#显示腐蚀后的图像
cv2.imshow("Close",closed); #开运算
opened = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
#显示腐蚀后的图像
cv2.imshow("Open", opened); cv2.waitKey(0)
cv2.destroyAllWindows()
效果图:
闭运算用来连接被误分为许多小块的对象,而开运算用于移除由图像噪音形成的斑点。因此,某些情况下可以连续运用这两种运算。
如对一副二值图连续使用闭运算和开运算,将获得图像中的主要对象。同样,如果想消除图像中的噪声(图像中的小点),也可以对
图像先用开运算后用闭运算,不过这样也会消除一些破碎的对象。
五:用形态学运算检测边和角点
这里只作为介绍使用,实际使用时使用 Canny 或 Harris 等算法。
1.)检测边缘
膨胀时,图像中的物体会向周围“扩张”;腐蚀时,图像中的物体会“收缩”。由于变化区域只发生在边缘,所以这时将两幅图像相减,
得到的就是图像中物体的边缘。
示例:
#!/usr/bin/env python
# encoding: utf-8 import cv2
import numpy as np image = cv2.imread("2.jpg",0);
#构造一个3×3的结构元素
element = cv2.getStructuringElement(cv2.MORPH_RECT,(3, 3))
dilate = cv2.dilate(image, element)
erode = cv2.erode(image, element) #将两幅图像相减获得边,第一个参数是膨胀后的图像,第二个参数是腐蚀后的图像
result = cv2.absdiff(dilate,erode); #上面得到的结果是灰度图,将其二值化以便更清楚的观察结果
retval, result = cv2.threshold(result, 40, 255, cv2.THRESH_BINARY);
#反色,即对二值图每个像素取反
result = cv2.bitwise_not(result);
#显示图像
cv2.imshow("result",result);
cv2.waitKey(0)
cv2.destroyAllWindows()
图像效果:
2.)检测拐角
第一步:与边缘检测不同,拐角的检测过程有些复杂,但原理相同,不同的是先用十字形的结构元素膨胀像素,
这种情况下只会在边缘处“扩张”,角点不发生变化。接着用菱形的结构元素腐蚀原图像,导致只有在拐角
处才会“收缩”,而直线边缘都发生变化。
第二步:用X形膨胀原图像,角点膨胀的比边要多。这样第二次用方块腐蚀时,角点恢复原状,而边要腐蚀
的更多,所以当两幅图像相减时,只保留了拐角处。
示例:
#!/usr/bin/env python
# encoding: utf-8 import cv2
import numpy as np image = cv2.imread("mini.jpg", 0)
origin = cv2.imread("mini.jpg")
#构造5×5的结构元素,分别为十字形、菱形、方形和X型
cross = cv2.getStructuringElement(cv2.MORPH_CROSS,(5, 5))
#菱形结构元素的定义稍麻烦一些
diamond = cv2.getStructuringElement(cv2.MORPH_RECT,(5, 5))
diamond[0, 0] = 0
diamond[0, 1] = 0
diamond[1, 0] = 0
diamond[4, 4] = 0
diamond[4, 3] = 0
diamond[3, 4] = 0
diamond[4, 0] = 0
diamond[4, 1] = 0
diamond[3, 0] = 0
diamond[0, 3] = 0
diamond[0, 4] = 0
diamond[1, 4] = 0
square = cv2.getStructuringElement(cv2.MORPH_RECT,(5, 5))
x = cv2.getStructuringElement(cv2.MORPH_CROSS,(5, 5))
#使用cross膨胀图像
result1 = cv2.dilate(image,cross)
#使用菱形腐蚀图像
result1 = cv2.erode(result1, diamond) #使用X膨胀原图像
result2 = cv2.dilate(image, x)
#使用方形腐蚀图像
result2 = cv2.erode(result2,square) #result = result1.copy()
#将两幅闭运算的图像相减获得角
result = cv2.absdiff(result2, result1)
#使用阈值获得二值图
retval, result = cv2.threshold(result, 40, 255, cv2.THRESH_BINARY) #在原图上用半径为5的圆圈将点标出。
for j in range(result.size): y = j / result.shape[0] x = j % result.shape[0] if result[x, y] == 255: cv2.circle(image, (y, x), 5, (255,0,0)) cv2.imshow("Result", image)
cv2.waitKey(0)
cv2.destroyAllWindows()
效果图:
提示:
sunny2038 在博客中提出OpenCV 中函数参数中使用的坐标系和 NumPy 的 ndarray 的坐标系是不同的,
本文参考和转载:
http://blog.csdn.net/sunny2038/article/details/9137759
http://blog.csdn.net/rocky_shared_image/article/details/7821823
http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/imgproc/opening_closing_hats/opening_closing_hats.html
Python OpenCV 形态学 (六)相关推荐
- Python——OpenCV形态学处理(膨胀与腐蚀)
定义结构元素 形态学处理的核心就是定义结构元素,在OpenCV-Python中,可以使用其自带的getStructuringElement函数,也可以直接使用NumPy的ndarray来定义一个结构元 ...
- Python OpenCV第六课:播放AVI文件
OpenCV既可以读取连接电脑的摄像头视频,也可以读取本地视频文件.读取视频文件的第一步是要创建一个 VideoCapture 对象.它的参数可以是设备索引,也可以是要读取的视频文件名.在大多数情况下 ...
- 【新星计划】Python OpenCV 形态学应用—图像开运算与闭运算
开运算 开运算=先腐蚀运算,再膨胀运算(看上去把细微连在一起的两块目标分开了) 开运算的效果图如下图所示: 开运算总结: (1)开运算能够除去孤立的小点,毛刺和小桥,而总的位置和形状不便. (2)开 ...
- 《OpenCv视觉之眼》Python图像处理十六:Opencv图像处理实战一之图像中的硬币检测
本专栏主要介绍如果通过OpenCv-Python进行图像处理,通过原理理解OpenCv-Python的函数处理原型,在具体情况中,针对不同的图像进行不同等级的.不同方法的处理,以达到对图像进行去噪.锐 ...
- OpenCV(六)形态学操作1--基础:膨胀与腐蚀(回调函数)
目录 形态学通用API:morphologyEx 一.基础理论 1.邻接关系 (1)四邻接: (2)D邻接: (3) 八邻接: 2.连通性 (1)四连通: (2)八连通: (3)m连通: 3.形态学基 ...
- Python+Opencv简易车牌识别(二):形态学运算,HSV颜色空间筛选与图像分割
注:这是依然一个简单的车牌识别demo 1.前言 在上一篇Python+Opencv简易车牌识别(一):基于HSV颜色空间的图像分割中,我们讲了如何仅基于颜色来进行简单粗暴的车牌分割.今天我们考虑对图 ...
- Python+OpenCV:形态学变换
Python+OpenCV:形态学变换 理论 形态学变换是基于图像形状的一些简单操作. 它通常在二值图像上执行.它需要两个输入,一个是我们的原始图像,另一个是结构元素(structuring elem ...
- [python opencv 计算机视觉零基础到实战] 六、图像运算
一.学习目标 了解opencv中图像运算的方法 了解opencv中图像运算的运用 如有错误欢迎指出~ 二.了解OpenCV中图像运算的运用 目录 [python opencv 计算机视觉零基础到实战] ...
- python+opencv实现机器视觉基础技术(2)(宽度测量,缺陷检测,医学检测
本篇博客接着讲解机器视觉的有关技术和知识.包括宽度测量,缺陷检测,医学处理. 一:宽度测量 在传统的自动化生产中,对于尺寸的测量,典型的方法就是千分尺.游标卡尺.塞尺等.而这些测量手段测量精度低 ...
最新文章
- git工作区、暂存区和仓库区
- java触发器如何创建表_在java 中执行触发器代码、创表语句
- 【晒出你的第83行代码】踌躇满志的三位高中生,以敬畏之心踏上了代码征程...
- gitlab 无法git clone 的一个小点
- golang println与printf区别
- LLVM 与 Clang 介绍 — LinuxTOY
- iOS8开发~UI布局(二)storyboard中autolayout和size class的使用详解
- php修改文件上传大小限制
- Frequency 频率统计
- vue中v-html指令的使用之Vue知识点归纳(三)
- mysql8.0root连接失败_mac 下jdbc连接mysql 8.0 失败
- pip 错误:ModuleNotFoundError: No module named pip
- 下岗职工能不能提前退休?怎样才能提前退休?
- scala类型匹配注意事项
- Idea Debug多线程不进断点问题处理
- 数据统计学习的5个基本流程
- PHP IE下载时提示”无法复制 无法读取源文件或磁盘”的解决办法
- 基于C#和SQL SERVER的企业进销存管理系统的设计和实现
- asterisk的sip.conf配置
- python怎么连接linux服务器,python连接linux服务器