OpenCV-Python教程:形态学处理

2024-06-11 04:08

本文主要是介绍OpenCV-Python教程:形态学处理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  • 转自: http://blog.csdn.net/sunny2038/article/details/9137759
  • 本文介绍使用OpenCV-Python进行形态学处理
  • 本文不介绍形态学处理的基本概念,所以读者需要预先对其有一定的了解。

定义结构元素

形态学处理的核心就是定义结构元素,在OpenCV-Python中,可以使用其自带的getStructuringElement函数,也可以直接使用NumPy的ndarray来定义一个结构元素。首先来看用getStructuringElement函数定义一个结构元素:

[python]  view plain copy
  1. element = cv2.getStructuringElement(cv2.MORPH_CROSS,(5,5))  
这就定义了一个5×5的十字形结构元素,如下:

也可以用NumPy来定义结构元素,如下:

[python]  view plain copy
  1. NpKernel = np.uint8(np.zeros((5,5)))  
  2. for i in range(5):  
  3.     NpKernel[2, i] = 1 #感谢chenpingjun1990的提醒,现在是正确的  
  4.     NpKernel[i, 2] = 1  
这两者方式定义的结构元素完全一样:
[python]  view plain copy
  1. [[0 0 1 0 0]  
  2.  [0 0 1 0 0]  
  3.  [1 1 1 1 1]  
  4.  [0 0 1 0 0]  
  5.  [0 0 1 0 0]]  

这里可以看出,用OpenCV-Python内置的常量定义椭圆(MORPH_ELLIPSE)和十字形结构(MORPH_CROSS)元素要简单一些,如果定义矩形(MORPH_RECT)和自定义结构元素,则两者差不多。

本篇文章将用参考资料1中的相关章节的图片做测试:


腐蚀和膨胀

下面先以腐蚀图像为例子介绍如何使用结构元素:

[python]  view plain copy
  1. #coding=utf-8  
  2. import cv2  
  3. import numpy as np  
  4.    
  5. img = cv2.imread('D:/binary.bmp',0)  
  6. #OpenCV定义的结构元素  
  7. kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(33))  
  8.   
  9. #腐蚀图像  
  10. eroded = cv2.erode(img,kernel)  
  11. #显示腐蚀后的图像  
  12. cv2.imshow("Eroded Image",eroded);  
  13.   
  14. #膨胀图像  
  15. dilated = cv2.dilate(img,kernel)  
  16. #显示膨胀后的图像  
  17. cv2.imshow("Dilated Image",dilated);  
  18. #原图像  
  19. cv2.imshow("Origin", img)  
  20.   
  21. #NumPy定义的结构元素  
  22. NpKernel = np.uint8(np.ones((3,3)))  
  23. Nperoded = cv2.erode(img,NpKernel)  
  24. #显示腐蚀后的图像  
  25. cv2.imshow("Eroded by NumPy kernel",Nperoded);  
  26.   
  27. cv2.waitKey(0)  
  28. cv2.destroyAllWindows()  

如上所示,腐蚀和膨胀的处理很简单,只需设置好结构元素,然后分别调用cv2.erode(...)和cv2.dilate(...)函数即可,其中第一个参数是需要处理的图像,第二个是结构元素。返回处理好的图像。

结果如下:


开运算和闭运算

了解形态学基本处理的同学都知道,开运算和闭运算就是将腐蚀和膨胀按照一定的次序进行处理。但这两者并不是可逆的,即先开后闭并不能得到原先的图像。代码示例如下:

[python]  view plain copy
  1. #coding=utf-8  
  2. import cv2  
  3. import numpy as np  
  4.    
  5. img = cv2.imread('D:/binary.bmp',0)  
  6. #定义结构元素  
  7. kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(55))  
  8.   
  9. #闭运算  
  10. closed = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)  
  11. #显示腐蚀后的图像  
  12. cv2.imshow("Close",closed);  
  13.   
  14. #开运算  
  15. opened = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)  
  16. #显示腐蚀后的图像  
  17. cv2.imshow("Open", opened);  
  18.   
  19. cv2.waitKey(0)  
  20. cv2.destroyAllWindows()  

闭运算用来连接被误分为许多小块的对象,而开运算用于移除由图像噪音形成的斑点。因此,某些情况下可以连续运用这两种运算。如对一副二值图连续使用闭运算和开运算,将获得图像中的主要对象。同样,如果想消除图像中的噪声(即图像中的“小点”),也可以对图像先用开运算后用闭运算,不过这样也会消除一些破碎的对象。

对原始图像进行开运算和闭运算的结果如下:


用形态学运算检测边和角点

这里通过一个较复杂的例子介绍如何用形态学算子检测图像中的边缘和拐角(这里只是作为介绍形态学处理例子,实际使用时请用Canny或Harris等算法)。

检测边缘

形态学检测边缘的原理很简单,在膨胀时,图像中的物体会想周围“扩张”;腐蚀时,图像中的物体会“收缩”。比较这两幅图像,由于其变化的区域只发生在边缘。所以这时将两幅图像相减,得到的就是图像中物体的边缘。这里用的依然是参考资料1中相关章节的图片:

代码如下:

[python]  view plain copy
  1. #coding=utf-8  
  2. import cv2  
  3. import numpy  
  4.   
  5. image = cv2.imread("D:/building.jpg",0);  
  6. #构造一个3×3的结构元素   
  7. element = cv2.getStructuringElement(cv2.MORPH_RECT,(33))  
  8. dilate = cv2.dilate(image, element)  
  9. erode = cv2.erode(image, element)  
  10.   
  11. #将两幅图像相减获得边,第一个参数是膨胀后的图像,第二个参数是腐蚀后的图像  
  12. result = cv2.absdiff(dilate,erode);  
  13.   
  14. #上面得到的结果是灰度图,将其二值化以便更清楚的观察结果  
  15. retval, result = cv2.threshold(result, 40255, cv2.THRESH_BINARY);   
  16. #反色,即对二值图每个像素取反  
  17. result = cv2.bitwise_not(result);   
  18. #显示图像  
  19. cv2.imshow("result",result);   
  20. cv2.waitKey(0)  
  21. cv2.destroyAllWindows()  
处理结果如下:

检测拐角

与边缘检测不同,拐角的检测的过程稍稍有些复杂。但原理相同,所不同的是先用十字形的结构元素膨胀像素,这种情况下只会在边缘处“扩张”,角点不发生变化。接着用菱形的结构元素腐蚀原图像,导致只有在拐角处才会“收缩”,而直线边缘都未发生变化。

第二步是用X形膨胀原图像,角点膨胀的比边要多。这样第二次用方块腐蚀时,角点恢复原状,而边要腐蚀的更多。所以当两幅图像相减时,只保留了拐角处。示意图如下(示意图来自参考资料1):

代码如下:

[python]  view plain copy
  1. #coding=utf-8  
  2. import cv2  
  3.   
  4. image = cv2.imread("D:/building.jpg"0)  
  5. origin = cv2.imread("D:/building.jpg")  
  6. #构造5×5的结构元素,分别为十字形、菱形、方形和X型  
  7. cross = cv2.getStructuringElement(cv2.MORPH_CROSS,(55))  
  8. #菱形结构元素的定义稍麻烦一些  
  9. diamond = cv2.getStructuringElement(cv2.MORPH_RECT,(55))  
  10. diamond[00] = 0  
  11. diamond[01] = 0  
  12. diamond[10] = 0  
  13. diamond[44] = 0  
  14. diamond[43] = 0  
  15. diamond[34] = 0  
  16. diamond[40] = 0  
  17. diamond[41] = 0  
  18. diamond[30] = 0  
  19. diamond[03] = 0  
  20. diamond[04] = 0  
  21. diamond[14] = 0  
  22. square = cv2.getStructuringElement(cv2.MORPH_RECT,(55))  
  23. x = cv2.getStructuringElement(cv2.MORPH_CROSS,(55))  
  24. #使用cross膨胀图像  
  25. result1 = cv2.dilate(image,cross)  
  26. #使用菱形腐蚀图像  
  27. result1 = cv2.erode(result1, diamond)  
  28.   
  29. #使用X膨胀原图像   
  30. result2 = cv2.dilate(image, x)  
  31. #使用方形腐蚀图像   
  32. result2 = cv2.erode(result2,square)  
  33.   
  34. #result = result1.copy()  
  35. #将两幅闭运算的图像相减获得角   
  36. result = cv2.absdiff(result2, result1)  
  37. #使用阈值获得二值图  
  38. retval, result = cv2.threshold(result, 40255, cv2.THRESH_BINARY)  
  39.   
  40. #在原图上用半径为5的圆圈将点标出。  
  41. for j in range(result.size):  
  42.     y = j / result.shape[0]   
  43.     x = j % result.shape[0]   
  44.   
  45.     if result[x, y] == 255:  
  46.         cv2.circle(image, (y, x), 5, (255,0,0))  
  47.   
  48. cv2.imshow("Result", image)  
  49. cv2.waitKey(0)  
  50. cv2.destroyAllWindows()  
注意,由于封装的缘故,OpenCV中函数参数中使用的坐标系和NumPy的ndarray的坐标系是不同的,在46行可以看出来。 抽空我向OpenCV邮件列表提一下,看我的理解是不是正确的。

大家可以验证一下,比如在代码中插入这两行代码,就能知道结果了:

[python]  view plain copy
  1. cv2.circle(image, (510), 5, (255,0,0))  
  2. image[510] = 0  
通过上面的代码就能检测到图像中的拐角并标出来,效果图如下:



当然,这只是个形态学处理示例,检测结果并不好。

未完待续...

在将来的某一篇文章中将做个总结,介绍下OpenCV中常用的函数,如threshold、bitwise_xxx,以及绘制函数等。

参考资料:

1、《Opencv2 Computer Vision Application Programming Cookbook》

2、《OpenCV References Manule》

如果觉得本文写的还可以的话,请轻点“顶”,方便读者、以及您的支持是我写下去的最大的两个动力。

这篇关于OpenCV-Python教程:形态学处理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1050149

相关文章

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

无人叉车3d激光slam多房间建图定位异常处理方案-墙体画线地图切分方案

墙体画线地图切分方案 针对问题:墙体两侧特征混淆误匹配,导致建图和定位偏差,表现为过门跳变、外月台走歪等 ·解决思路:预期的根治方案IGICP需要较长时间完成上线,先使用切分地图的工程化方案,即墙体两侧切分为不同地图,在某一侧只使用该侧地图进行定位 方案思路 切分原理:切分地图基于关键帧位置,而非点云。 理论基础:光照是直线的,一帧点云必定只能照射到墙的一侧,无法同时照到两侧实践考虑:关

python: 多模块(.py)中全局变量的导入

文章目录 global关键字可变类型和不可变类型数据的内存地址单模块(单个py文件)的全局变量示例总结 多模块(多个py文件)的全局变量from x import x导入全局变量示例 import x导入全局变量示例 总结 global关键字 global 的作用范围是模块(.py)级别: 当你在一个模块(文件)中使用 global 声明变量时,这个变量只在该模块的全局命名空

Makefile简明使用教程

文章目录 规则makefile文件的基本语法:加在命令前的特殊符号:.PHONY伪目标: Makefilev1 直观写法v2 加上中间过程v3 伪目标v4 变量 make 选项-f-n-C Make 是一种流行的构建工具,常用于将源代码转换成可执行文件或者其他形式的输出文件(如库文件、文档等)。Make 可以自动化地执行编译、链接等一系列操作。 规则 makefile文件

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss

【生成模型系列(初级)】嵌入(Embedding)方程——自然语言处理的数学灵魂【通俗理解】

【通俗理解】嵌入(Embedding)方程——自然语言处理的数学灵魂 关键词提炼 #嵌入方程 #自然语言处理 #词向量 #机器学习 #神经网络 #向量空间模型 #Siri #Google翻译 #AlexNet 第一节:嵌入方程的类比与核心概念【尽可能通俗】 嵌入方程可以被看作是自然语言处理中的“翻译机”,它将文本中的单词或短语转换成计算机能够理解的数学形式,即向量。 正如翻译机将一种语言

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

nudepy,一个有趣的 Python 库!

更多资料获取 📚 个人网站:ipengtao.com 大家好,今天为大家分享一个有趣的 Python 库 - nudepy。 Github地址:https://github.com/hhatto/nude.py 在图像处理和计算机视觉应用中,检测图像中的不适当内容(例如裸露图像)是一个重要的任务。nudepy 是一个基于 Python 的库,专门用于检测图像中的不适当内容。该