目标

这一节

  • 我们将学习不同的形态学操作,如腐蚀、膨胀、开、闭......
  • 我们将看到不同的函数,如:cv2.erode()、cv2.dilate()、cv2.morphology()

理论

形态变换是基于图像形状的一些简单操作。它通常在二进制图像上执行。它需要两个输入,一个是我们的原始图像,第二个是称为结构元素或内核,它决定了操作的本质。两个基本的形态学运算符是侵蚀和膨胀。然后它的变体形式如Opening,Closing,Gradient等也发挥作用。我们将在以下图片的帮助下逐一看到它们:

1、腐蚀(Erosion)

腐蚀的基本思想就像土壤侵蚀一样,它会侵蚀前景物体的边界(总是试图保持前景为白色)。那它是做什么的?内核在图像中滑动(如在2D卷积中)。只有当内核下的所有像素都是1时,原始图像中的像素(1或0)才会被视为1,否则它将被侵蚀(变为零)

所以发生的事情是,边界附近的所有像素都将被丢弃,具体取决于内核的大小。因此,前景对象的厚度或大小减小,或者图像中的白色区域减小。它有助于消除小的白噪声(正如我们在色彩空间章节中看到的那样),分离两个连接的对象等。

在这里,作为一个例子,我将使用一个全1的5x5内核,其中包含完整的内核。让我们看看它是如何工作的:

import cv2
import numpy as np img = cv2.imread('j.png',0)
kernel = np.ones((5,5),np.uint8)
erosion = cv2.erode(img,kernel,iterations = 1)

结果:

2、膨胀(Dilation)

它恰好与腐蚀相反。这里,如果内核下的至少一个像素为“1”,则像素元素为“1”。因此它增加了图像中的白色区域或前景对象的大小增加。通常,在去除噪音的情况下,腐蚀之后再膨胀。因为,腐蚀会消除白噪声,但它也会缩小我们的物体,所以我们需要再扩大它。由于噪音消失了,它们不会再回来,但我们的物体区域会增加。它也可用于连接对象的破碎部分。

dilation = cv2.dilate(img,kernel,iterations = 1)

结果:

3、开运算(Opening)

开运算是腐蚀再膨胀的另一种说法。如上所述,它有助于消除噪音。这里我们使用函数cv2.morphologyEx().

opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)

结果:

4. 闭运算(Closing)

开运算与闭运算,腐蚀和膨胀是相反的。闭运算就是先膨胀再腐蚀,它可用于关闭前景对象内的小孔或对象上的小黑点。

closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)

结果:

我们可以通过以下代码观察之间的关系:

import cv2
import numpy as np img = cv2.imread('./Pictures/j.png',0)
kernel = np.ones((5,5),np.uint8)
erosion = cv2.erode(img,kernel,iterations = 1) img2 = ~img
dilation = cv2.dilate(img2,kernel,iterations = 1)
dilation = ~dilation htich = np.hstack((img, erosion, dilation))
cv2.imshow("erosion", htich)
cv2.waitKey(0)

结果:

可见,img开运算等同于反转图闭运算再反转。

5、形态梯度(Morphological Gradient)

它是一张图像膨胀和腐蚀之间的差异,结果看起来像对象的轮廓。

gradient = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)

结果:

其效果等同于膨胀减去腐蚀

import cv2
import numpy as np img = cv2.imread('./Pictures/j.png',0)
kernel = np.ones((5,5),np.uint8)
erosion = cv2.erode(img,kernel,iterations = 1)
dilation = cv2.dilate(img,kernel,iterations = 1)
diff = dilation - erosion gradient = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel) htich = np.hstack((img, gradient, diff))
cv2.imwrite("./Pictures/i.png", htich)
cv2.imshow("erosion", htich)
cv2.waitKey(0)

效果:

6、高帽变换(Top Hat/White Top-Hot)

它是输入图像和图像开运算之间的区别。下面的示例是针对9x9内核完成的。

tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)

结果:

其等同于膨胀后减去原图,例如,该图在使用2x2内核时,两者效果比较接近。

import cv2
import numpy as np img = cv2.imread('./Pictures/j.png',0)
kernel = np.ones((2,2),np.uint8)
erosion = cv2.erode(img,kernel,iterations = 1)
dilation = cv2.dilate(img,kernel,iterations = 1)
diff = img - dilation
diff2 = dilation - img tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel) htich = np.hstack((img, tophat, diff2))
cv2.imwrite("./Pictures/i.png", htich)
cv2.imshow("erosion", htich)
cv2.waitKey(0)

结果:

7、黑帽变换(Black Hat/Black Top-Hot)

它是闭运算与输入图像的差异。

blackhat = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)

结果:

其等同于原图减去闭运算,显然这两个都能用来提取轮廓,有什么区别呢?WTH能使较暗背景中较亮的像素聚集,BTH能使较亮背景中较暗像素的聚集。前者使“峰”更尖,后者使“谷”更深。两者结合$THE(f)=f+WTH(f,b)-BTH(f,b)$,对比更加明显。

结构元素(Structuring Element)

我们在Numpy的帮助下手动创建了前面示例中的结构元素。它是矩形。但在某些情况下,您可能需要椭圆/圆形内核。因此,为此,OpenCV有一个函数cv2.getStructuringElement()。您只需传递内核的形状和大小,即可获得所需的内核。

# Rectangular Kernel
>>> cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))
array([[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1]], dtype=uint8) # Elliptical Kernel
>>> cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))
array([[0, 0, 1, 0, 0],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[0, 0, 1, 0, 0]], dtype=uint8) # Cross-shaped Kernel
>>> cv2.getStructuringElement(cv2.MORPH_CROSS,(5,5))
array([[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]], dtype=uint8)

参考链接:OpenCV-Python Tutorials https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_morphological_ops/py_morphological_ops.html#dilation

Python-OpenCV——Morphological Transformations(形态学转换)的更多相关文章

  1. python opencv入门-形态学转换

    目标: 学习不同的形态操作 例如 腐蚀.膨胀.开运算.闭运算 等. 我们要学习的函数有 cv2.erode(),cv2.dilate(),cv2.morphologyEx() 等. 原理 :一般对二值 ...

  2. python base64 编解码,转换成Opencv,PIL.Image图片格式

    二进制打开图片文件,base64编解码,转成Opencv格式: # coding: utf-8 import base64 import numpy as np import cv2 img_file ...

  3. python+opencv实现车牌定位

    写在前面 HIT大三上学期视听觉信号处理课程中视觉部分的实验三,经过和学长们实验的对比发现每一级实验要求都不一样,因此这里标明了是2019年秋季学期的视觉实验三. 由于时间紧张,代码没有进行任何优化, ...

  4. python opencv识别蓝牌车牌号 之 取出车牌号 (1/3)

    概述 车牌识别是计算机视频图像识别技术在车辆牌照识别中的一种应用,通常来讲如果结合opencv进行车牌识别主要分为四个大步骤,分别为: 图像采集 车牌定位 分割车牌字符 字符识别 当然,如果结合了机器 ...

  5. 【Python | opencv+PIL】常见操作(创建、添加帧、绘图、读取等)的效率对比及其优化

    一.背景 本人准备用python做图像和视频编辑的操作,却发现opencv和PIL的效率并不是很理想,并且同样的需求有多种不同的写法并有着不同的效率.见全网并无较完整的效率对比文档,遂决定自己丰衣足食 ...

  6. Python opencv PIL numpy base64互相转化

    PIL2numpy and numpy2PIL from PIL import Image import numpy image = Image.open('timg.jpeg')# image is ...

  7. 搭建基于python +opencv+Beautifulsoup+Neurolab机器学习平台

    搭建基于python +opencv+Beautifulsoup+Neurolab机器学习平台 By 子敬叔叔 最近在学习麦好的<机器学习实践指南案例应用解析第二版>,在安装学习环境的时候 ...

  8. .NET + OpenCV & Python + OpenCV 配置

    最近需要做一个图像识别的GUI应用,权衡了Opencv+ 1)QT,2)Python GUI,3).NET后选择了.NET... 本文给出C#+Opencv和Python+Opencv的相应参考,节省 ...

  9. RPi 2B python opencv camera demo example

    /************************************************************************************** * RPi 2B pyt ...

随机推荐

  1. HDU - 6201 transaction transaction transaction(树形dp取两点)

    transaction transaction transaction Kelukin is a businessman. Every day, he travels around cities to ...

  2. GPLT天梯赛 L2-022. 重排链表

    L2-022. 重排链表 时间限制 500 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 给定一个单链表 L1→L2→...→Ln-1→Ln,请 ...

  3. tcpkill工作原理分析

    此文已由作者张耕源授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 日常工作生活中大家在维护自己的服务器.VPS有时会碰到这样的情况:服务器上突然出现了许多来自未知ip的网络连 ...

  4. JavaScript 原型的实际应用之实现一个 jQuery

    我们平时使用jQuery大概是这样: let $p = $('p'); $p.css('fontSize', '40px'); 我们生成jQuery实例对象后,就可以使用原型上的css(), html ...

  5. react学习之redux和redux-react用法

    前言 redux和react-redux的关系:   redux就是一个存储数据的对象,并提供了获取/设置store中的属性的解决方案,react-redux是连接react和redux桥梁的封装. ...

  6. 2017 Fzu校赛 [Cloned]

    A - Salty Fish 海边躺着一排咸鱼,一些有梦想的咸鱼成功翻身(然而没有什么卵用),一些则是继续当咸鱼.一个善良的渔夫想要帮这些咸鱼翻身,但是渔夫比较懒,所以只会从某只咸鱼开始,往一个方向, ...

  7. Windows服务器初始配置

    系统状态是否良好 检查ip地址.子网掩码等配置 防火墙是否关闭 是否有攻击,有多大的攻击,什么类型的攻击,攻击流量图 是否中病毒 1.改端口 (1)打开注册表 [HKEY_LOCAL_MACHINE\ ...

  8. windows installer cleanup utility - Windows下卸载神器

    https://windows-installer-cleanup-utility.soft32.com

  9. Codeforces Round #377 (Div. 2) E. Sockets

    http://codeforces.com/contest/732/problem/E 题目说得很清楚,每个电脑去插一个插座,然后要刚好的,电脑的power和sockets的值相同才行. 如果不同,还 ...

  10. Jexus~docker与它产生了暖味

    前段时间写了很多docker for .net core的文章,用来快速部署微服务相当给力,而尝到了香头的我们希望把.net frameworks的程序也使用docker来部署一下,那么接下来我就结果 ...