python 开运算_OpenCV-Python系列之开运算与闭运算

图像的腐蚀与膨胀是本次教程的核心——开运算与闭运算的基础,如果结构元素为圆形, 则膨胀操作可填充图像中比结构元素小的孔洞以及图像边缘处小的凹陷部分。 而腐蚀可以消除图像中的毛刺及细小连接成分, 并将图像缩小, 从而使其补集扩大。 但是, 膨胀和腐蚀并非互为逆运算, 所以它们可以结合使用。 在腐蚀和膨胀两个基本运算的基础上, 可以构造出形态学运算簇, 它由膨胀和腐蚀两个运算的复合与集合操作(并、 交、 补等)组合成的所有运算构成。 例如, 可使用同一结构元素, 先对图像进行腐蚀然后膨胀其结果, 该运算称为开运算; 或先对图像进行膨胀然后腐蚀其结果, 称其为闭运算。 开运算和闭运算是形态学运算族中两种最为重要的运算。

对于图像X及结构元素S, 用符号

表示S对图像X作开运算, 用符号

表示S对图像X作闭运算, 它们的定义为:

首先需要来了解一个函数:

cv2.morphologyEx(src, op, kernel)

参数说明:

src传入的图片

op进行变化的方式

kernel表示定义的卷积核的大小以及形状

op =  cv2.MORPH_OPEN 进行开运算,指的是先进行腐蚀操作,再进行膨胀操作

op = cv2.MORPH_CLOSE 进行闭运算, 指的是先进行膨胀操作,再进行腐蚀操作

开运算

开运算指的就是对图像先进行腐蚀操作,然后再进行膨胀操作,而通常情况下,它是对图像的明亮的区域进行操作,可以消除图像中的白噪声,现在我们来看例子,先看一幅图像:

现在我们想要消除图像中的黑色的毛刺,但是如果直接对图像进行开运算是不行的,因为开运算是对图像的明亮区域进行操作,看一下直接进行开运算会有什么效果:import cv2

import numpy as np

img = cv2.imread('open.jpg',0)

kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(3,3))

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

cv2.imshow("img",img)

cv2.imshow("result", open)

cv2.waitKey(0)

cv2.destroyAllWindows()

可以看到,图像的毛刺没有被去除,现在我们需要将原图进行阈值化翻转,也就是黑白颠倒,这样才方便进行形态学的处理,我们在前面阈值部分讲过,这里就不再讲述了,直接看代码:import cv2

import numpy as np

img = cv2.imread('open.jpg',0)

threshold = cv2.threshold(img,0,255,cv2.THRESH_BINARY_INV|

cv2.THRESH_OTSU)[1]

cv2.imshow("img",img)

cv2.imshow("thres",threshold)

cv2.waitKey(0)

cv2.destroyAllWindows()

现在图像已经被黑白颠倒了过来,现在我们可以开始进行开运算了,当然首先也是需要定义一个卷积核的,这在上个教程中已经谈到,在这里我们定义一个3*3的矩形卷积核:import cv2

import numpy as np

img = cv2.imread('open.jpg',0)

threshold = cv2.threshold(img,0,255,cv2.THRESH_BINARY_INV|

cv2.THRESH_OTSU)[1]

kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(3,3))

open =cv2.morphologyEx(threshold,cv2.MORPH_OPEN,kernel)

cv2.imshow("img",img)

cv2.imshow("thres",threshold)

cv2.imshow("result", open)

cv2.waitKey(0)

cv2.destroyAllWindows()

这样效果就显而易见了,如果我们将卷积核改成5*5的呢:import cv2

import numpy as np

img = cv2.imread('open.jpg',0)

threshold = cv2.threshold(img,0,255,cv2.THRESH_BINARY_INV|

cv2.THRESH_OTSU)[1]

kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))

open =cv2.morphologyEx(threshold,cv2.MORPH_OPEN,kernel)

cv2.imshow("thres",threshold)

cv2.imshow("result", open)

cv2.waitKey(0)

cv2.destroyAllWindows()

这就说明操作过度了,所以对于形态学处理卷积核的适当选取是非常重要的,现在我们对处理之后的图像进行还原:import cv2

import numpy as np

img = cv2.imread('open.jpg',0)

threshold = cv2.threshold(img,0,255,cv2.THRESH_BINARY_INV|

cv2.THRESH_OTSU)[1]

kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(3,3))

open =cv2.morphologyEx(threshold,cv2.MORPH_OPEN,kernel)

result = cv2.threshold(open,0,255,cv2.THRESH_BINARY_INV|

cv2.THRESH_OTSU)[1]

cv2.imshow("img",img)

cv2.imshow("thres",threshold)

cv2.imshow("open", open)

cv2.imshow("result",result)

cv2.waitKey(0)

cv2.destroyAllWindows()

看一下最终还原的结果:

事实上,卷积核的灵活运用将会极大的方便图像的形态学处理,我们来进行一个实战,比如现在给出一幅图像:

我们将用开运算分别提炼出横线和竖线,我们使用13*1的卷积核进行实验:import cv2

import numpy as np

img = cv2.imread('hengshu.jpg',0)

kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(13,1))

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

cv2.imshow("img",img)

cv2.imshow("open", open)

cv2.waitKey(0)

cv2.destroyAllWindows()

是不是很神奇,现在我们使用1*13的卷积核进行实验:import cv2

import numpy as np

img = cv2.imread('hengshu.jpg',0)

kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(1,13))

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

cv2.imshow("img",img)

cv2.imshow("open", open)

cv2.waitKey(0)

cv2.destroyAllWindows()

竖线也被完美的提取出来了,在以后的项目实战中,我们将会用到这些知识,合理的过滤掉图像中多余的信息,事实上,我们还发现,处理之后的图像偏暗,没有原图那么明亮,这在下次教程中的顶帽——黑帽操作中可以进行处理。

闭运算

我们折腾了半天的开运算,现在我们来玩玩闭运算,闭运算跟开运算相反,是先膨胀再腐蚀,它通常被用来去除图像明亮区域内部的噪声。我们来看一幅图像:

现在我们将要用闭运算去除图像明亮区域内部的黑点,定义一个7*7的卷积核,我们看代码:import cv2

import numpy as np

img = cv2.  imread('close.jpg',0)

kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(7,7))

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

cv2.imshow("img",img)

cv2.imshow("open", open)

cv2.waitKey(0)

cv2.destroyAllWindows()

可以看到,效果很好,现在我们来进行另一个具有实战意义的实验,先看图片:

我们需要将这些字轮廓提炼出来,并且用方框标定出来,每一行字用一个方框标定出来,当然,这个涉及到以后将要讲解的轮廓提取以及轮廓近似,但是在这里我们先进行一个实验,如果我们想将每一行字用一个方框标定出来,那么首先需要满足的条件就是每一行的字必须连在一块,形成一个整体,这样的话才可以用OpenCV提取他们整体的轮廓,进而标定出来,但现在我们看到这些字都是独立的,它们并没有连在一起,这个时候我们就可以采用闭运算了。我们来看代码:import cv2

import numpy as np

img = cv2.imread('text1.jpg',0)

kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(21,5))

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

cv2.imshow("img",img)

cv2.imshow("open", open)

cv2.waitKey(0)

cv2.destroyAllWindows()

这样的话所有的字体连在一起,这也方便了后期的轮廓提取。

我在这里给出综合代码,大家可以玩玩:import cv2

import numpy as np

img = cv2.imread('text1.jpg')

test = img.copy()

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (19, 5))

close = cv2.morphologyEx(gray, cv2.MORPH_CLOSE, kernel)

contour, _ = cv2.findContours(close, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

cv2.drawContours(test, contour, -1, (0, 0, 255), 2)

for c in contour:

x, y, w, h = cv2.boundingRect(c)

cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 2)

cv2.imshow("result", img)

cv2.imshow("test",test)

cv2.imshow("close", close)

cv2.waitKey(0)

cv2.destroyAllWindows()

第一个图是对图像的轮廓进行提取,第二个则是提取轮廓的外接矩形,是不是很有意思,这在以后都会慢慢讲述。

闭运算一般则被用于处理内部噪声情况,开运算处理外部噪声情况,所以合理的运用它们是非常重要的。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
OpenCV-Python,开运算是形态学处理的两个基本操作之一。开运算通过先进行腐蚀操作,然后再进行膨胀操作来实现。它的作用包括填充物体空洞、消除噪声、连接邻近物体、平滑边界等。\[2\] 在代码,使用cv2.morphologyEx函数来进行开运算。参数cv2.MORPH_OPEN表示进行开运算。通过定义一个核(kernel)来指定腐蚀和膨胀的形状和大小。在给定的示例代码,使用了一个10x10的全1矩阵作为核。\[1\] 具体实现时,先读取原始图像,然后使用cv2.morphologyEx函数进行开运算操作,得到处理后的图像。最后可以通过cv2.imshow函数显示原始图像和处理后的图像,并通过cv2.imwrite函数保存处理后的图像。\[1\] 总结来说,开运算是一种常用的形态学处理方法,可以用于填充物体空洞、消除噪声、连接邻近物体、平滑边界等。在OpenCV-Python,可以使用cv2.morphologyEx函数来实现开运算操作。\[2\] #### 引用[.reference_title] - *1* *2* *3* [【OpenCV-Python】:形态学操作之开运算运算](https://blog.csdn.net/qq_42856191/article/details/123670455)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值