OpenCV-Python实现通用形态学函数

通用形态学函数

上篇博文,我们介绍了形态学的基础腐蚀与膨胀操作,而将腐蚀与膨胀结合起来进行组合,我们就能实现开运算,闭运算等复杂的形态学运算。

在OpenCV中,它给我们提供的通用形态学函数为cv2.morphologyEx(),其完整定义如下:

def morphologyEx(src, op, kernel, dst=None, anchor=None, iterations=None, borderType=None, borderValue=None):

这些参数基本前面都介绍过,不过有一点需要说明,src原始图像必须是CV_8U,CV_16U,CV_16S,CV_32F,CV_64F中的一种。

当然,这里面还有一个陌生的参数就是op,它就是各种形态学的类别,具体类别如表所示:

类型 说明 意义 操作
cv2.MORPH_ERODE 腐蚀 腐蚀 erode()
cv2.MORPH_DILATE 膨胀 膨胀 dilate()
cv2.MORPH_OPEN 开运算 先腐蚀后膨胀 dilate(erode())
cv2.MORPH_CLOSE 闭运算 先膨胀后腐蚀 erode(dilate())
cv2.MORPH_GRADIENT 形态学梯度运算 膨胀图减腐蚀图 dilate()-erode()
cv2.MORPH_TOPHAT 顶帽运算 原始图像减开运算所得图像 src-open()
cv2.MORPH_BLACKHAT 黑帽运算 闭运算所得图像减原始图像 close()-src
cv2.MORPH_HITMISS 击中击不中 前景背景腐蚀运算的交集。仅仅支持CV8UC1二进制图像 intersection(erode(src),erode(src1))

开运算

如上表所示,开运算是将原图像腐蚀,再对其进行膨胀操作。主要用于去噪,计数等。去噪我们已经通过上面的腐蚀操作就可以完成,下面我们来实现有趣的计数操作。

import cv2
import numpy as np

img = cv2.imread("open.jpg",cv2.IMREAD_UNCHANGED)
kernel = np.ones((9,9), np.float32)
result = cv2.morphologyEx(img,cv2.MORPH_OPEN,kernel,iterations=5)
cv2.imshow("img", img)
cv2.imshow("result", result)
cv2.waitKey()
cv2.destroyAllWindows()

运行之后,我们能将不同区域划分开来,效果如下:

闭运算

闭运算是先膨胀后腐蚀的运算,它有助于关闭前景物体内部的小孔,或去除物体上的小黑点,还可以将不同的前景图像进行连接。下面,我们就将上图进行连接。

import cv2
import numpy as np

img = cv2.imread("close.jpg", cv2.IMREAD_UNCHANGED)
kernel = np.ones((10, 10), np.float32)
result = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel, iterations=7)
cv2.imshow("img", img)
cv2.imshow("result", result)
cv2.waitKey()
cv2.destroyAllWindows()

运行之后,两个方块就连接为一个整体了,效果如下所示:

形态学梯度运算

形态学梯度运算是用图像膨胀后的图像减去腐蚀图像的运算,该操作可以获取原始图像中的前景图像的边缘。我们还是用上篇膨胀的图来测试,代码如下:

import cv2
import numpy as np

img = cv2.imread("8.jpg", cv2.IMREAD_UNCHANGED)
kernel = np.ones((5, 5), np.float32)
result = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel,iterations=2)
cv2.imshow("img", img)
cv2.imshow("result", result)
cv2.waitKey()
cv2.destroyAllWindows()

运行之后,我们的图像就中空了,效果如下:

顶帽运算

顶帽运算是用原始图像减去其开运算图像的操作。它能够获取图像的噪声信息,或者得到比原图像的边缘更亮的边缘信息。也就是获取上图中的白色线条,具体代码如下:

import cv2
import numpy as np

img = cv2.imread("8.jpg", cv2.IMREAD_UNCHANGED)
kernel = np.ones((5, 5), np.float32)
result = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel,iterations=2)
cv2.imshow("img", img)
cv2.imshow("result", result)
cv2.waitKey()
cv2.destroyAllWindows()

运行之后,效果如下:

黑帽运算

黑帽运算是用闭运算图像减去原始图像的操作。它能够获取内部的小孔,或前景色中的小黑点,亦或者得到比原始图像的边缘更暗的边缘部分。这里,我们用前面的人物图像,代码如下:

import cv2
import numpy as np

img = cv2.imread("4.jpg", cv2.IMREAD_UNCHANGED)
kernel = np.ones((5, 5), np.float32)
result = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel,iterations=2)
cv2.imshow("img", img)
cv2.imshow("result", result)
cv2.waitKey()
cv2.destroyAllWindows()

运行之后,效果如下:

结构元函数

前面我们介绍过,结构元可以自定义,也可以通过cv2.getStructuringElement()函数生成。这里,我们来看看其完整的定义:

def getStructuringElement(shape, ksize, anchor=None):

shape:形状类型,取值如下表:

类型 意义
cv2.MORPH_RECT 矩形结构元,所有元素值为1
cv2.MORPH_CROSS 十字形结构元,对角线元素值为1
cv2.MORPH_ELLIPSE 椭圆形结构元素

ksize:结构元的大小

anchor:结构元的锚点位置,默认值(-1,1),是形状的中心。只有十字星型的形状与锚点位置紧密联系。在其他情况下,锚点位置仅用于形态学运算结果的调整。

下面,我们将这三种形状类型都实现一遍,具体代码如下:

import cv2

img = cv2.imread("open.jpg", cv2.IMREAD_UNCHANGED)
kernel1 = cv2.getStructuringElement(cv2.MORPH_RECT,(50,50))
kernel2 = cv2.getStructuringElement(cv2.MORPH_CROSS,(50,50))
kernel3 = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(50,50))
result1 = cv2.dilate(img,kernel1)
result2 = cv2.dilate(img,kernel2)
result3 = cv2.dilate(img,kernel3)
cv2.imshow("img", img)
cv2.imshow("result1", result1)
cv2.imshow("result2", result2)
cv2.imshow("result3", result3)
cv2.waitKey()
cv2.destroyAllWindows()

运行之后,效果如下所示:

到此这篇关于OpenCV-Python实现通用形态学函数的文章就介绍到这了,更多相关OpenCV 通用形态学函数内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

时间: 2021-06-10

opencv 形态学变换(开运算,闭运算,梯度运算)

形态学里把腐蚀和膨胀单独拿了出来,其他操作(保括膨胀和腐蚀的组合操作)都叫形态学变换. opencv里有包:cv2.morphologyEx() morphology :译文 形态学 使用python +opencv讲解 开运算 开运算:对图像先进行腐蚀,然后对腐蚀后的图进行膨胀 morphologyEx 运算结果=cv2.morphologyEx(源图像img,cv2.MORPH_OPEN,卷积核k) cv2.MORPH_OPEN:开运算 import cv2 import numpy as

opencv检测直线方法之形态学方法

在阅读文献中,偶然发现使用使用形态学方法也可以检测直线,故做实验并记录. 使用该方法,需要定义一个长度为L的结构元素element,其大小应足够大以保留图像中的字符笔划,然而又恰好能检测出图像中最短的表格线. 定义如下两个结构element用以检测图中水平.竖直的表格线: Mat element1 = getStructuringElement(MORPH_RECT, Size(70, 1));// size的width应大于图像中的横向笔划 Mat element3 = getStructur

opencv检测直线方法之投影法

本文实例为大家分享了opencv检测直线之投影法的具体代码,供大家参考,具体内容如下 以下是我对投影法的一点认识和实验: 投影法就是数字图像在某个方向上进行像素累加.通过水平和垂直方向的投影,可以得到表格图像投影的几个特点: (1)表格区域的水平与竖直投影分布通常出现周期性的尖峰 (2)在文字投影的行与行之间或列与列之间常会出现明显的空白区 因此,求图像水平以及竖直投影,根据特点分别设以阈值就可以将横线以及竖直线所在位置确定. 第一步:求图像的水平投影.竖直投影 第二步:设定合理阈值,求取大于阈

go语言检测文件是否存在的方法

本文实例讲述了go语言检测文件是否存在的方法.分享给大家供大家参考.具体分析如下: go语言检测文件是否存在,首先创建一个FileInfo,如果不报错,再通过 IsDir()检查是否是目录 复制代码 代码如下: finfo, err := os.Stat("filename.txt") if err != nil {     // no such file or dir     return } if finfo.IsDir() {     // it's a file } else

JavaScript检测上传文件大小的方法

本文实例讲述了JavaScript检测上传文件大小的方法.分享给大家供大家参考.具体如下: 通过JS客户端代码限制用户上传文件的大小,但是客户端的验证只是辅助的,服务器端一定还要再做验证 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http

PHP检测数据类型的几种方法(总结)

在JavaScript中,使用typeof可以检测基本数据类型,使用instanceof可以检测引用数据类型.在PHP中,也有检测数据类型的方法,具体如下: 1.输出变量的数据类型(gettype) <?php $arry = array('a','b','c'); echo gettype($arry);//array ?> 2.输出变量的数据类型.包含的数量以及具体内容(var_dump) 查看源码打印代码帮助 <?php $str = 'hello world'; var_dump

php在linux下检测mysql同步状态的方法

本文实例讲述了php在linux下检测mysql同步状态的方法.分享给大家供大家参考.具体分析如下: 这里通过两个实例来介绍mysql同步状态检测实现方法.代码如下: 复制代码 代码如下: #!/bin/sh     #check MySQL_Slave Status  #crontab time 00:10  MYSQL_USER="root" MYSQL_PWD="123456" MYSQL_SLAVE_LOG="/tmp/check_mysql_sl

PHP使用finfo_file()函数检测上传图片类型的实现方法

本文实例讲述了PHP使用finfo_file()函数检测上传图片类型的实现方法.分享给大家供大家参考,具体如下: 在输入输出中,文件的交互必不可少,比如文件的上传什么的.这里我们来解决一个小问题,就是如何判断用户上传文件的文件类型. 举一个应用场面:在我们的Web应用中,比如用户上传头像,要求是png,jpg,gif格式,接收到图片后会根据图片格式类型做不同的头像切割处理,但个别用户会传一些只更改过文件后缀的非标准图片,比如nowamagic.jpg 强行修改成 nowamagic.png,这样

php检测图片主要颜色的方法

本文实例讲述了php检测图片主要颜色的方法.分享给大家供大家参考.具体实现方法如下: $i = imagecreatefromjpeg("image.jpg"); for ($x=0;$x<imagesx($i);$x++) { for ($y=0;$y<imagesy($i);$y++) { $rgb = imagecolorat($i,$x,$y); $r = ($rgb >> 16) & 0xFF; $g = ($rgb >> &

使用Python脚本实现批量网站存活检测遇到问题及解决方法

做渗透测试的时候,有个比较大的项目,里面有几百个网站,这样你必须首先确定哪些网站是正常,哪些网站是不正常的.所以自己就编了一个小脚本,为以后方便使用. 具体实现的代码如下: #!/usr/bin/python # -*- coding: UTF-8 -*- ''' @Author:joy_nick @博客:http://byd.dropsec.xyz/ ''' import requests import sys f = open('url.txt', 'r') url = f.readline

Android编程实现检测当前电源状态的方法

本文实例讲述了Android编程实现检测当前电源状态的方法.分享给大家供大家参考,具体如下: 检测到现在在电源状态: IntentFilter mIntentFilter = new IntentFilter(); mIntentFilter.addAction(Intent.ACTION_BATTERY_CHANGED); registerReceiver(mIntentReceiver, mIntentFilter); //声明消息处理过程 private BroadcastReceiver