opencv进阶学习笔记13:图像形态学操作大全(膨胀,腐蚀,开闭,黑帽,顶帽,梯度)python版

基础版学习笔记:
python3+opencv学习笔记汇总目录(适合基础入门学习)
进阶版笔记目录链接:
python+opencv进阶版学习笔记目录(适合有一定基础)

基础版形态学:
opencv学习笔记12:图像腐蚀和图像膨胀
opencv学习笔记13:形态学变换(开运算,闭运算,梯度运算)
opencv学习笔记14:图像礼帽,图像黑帽

图像膨胀

使用卷积核对二值图像进行遍历,卷积核对应的图像像素点只要有一个为1,则值为1,否则为0.
即用卷积核对应的最大元素替换掉当前中心像素。

膨胀作用:对象大小增加一个像素,平滑对象边缘,减少或者填充对象之间的距离。

使用方法:dilate
结果=cv2.dilate(二值图像src,卷积核k,迭代次数itreations)
卷积核 正方形数组:如np.ones((5,5),np.uint8)

import cv2 as cv
import numpy as np


def dilate_demo(image):
    print(image.shape)
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    ret, binary = cv.threshold(gray, 0, 255,cv.THRESH_BINARY_INV | cv.THRESH_OTSU)
    cv.imshow("binary", binary)
    kernel = cv.getStructuringElement(cv.MORPH_RECT, (5, 5))
    #kernel = np.ones((5, 5), np.uint8)
    dst = cv.dilate(binary, kernel)
    cv.imshow("dilate_demo", dst)
print("--------- Python OpenCV Tutorial ---------")
src = cv.imread("fushi.jpg")
src=cv.resize(src,None,fx=0.4,fy=0.4)
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
dilate_demo(src)
cv.waitKey(0)
cv.destroyAllWindows()

解释说明:
在使用opencv的过程中,我们经常需要各种各样的卷积核。如果是正方形的核还好说,可以使用numpy,但是有时候需要定义椭圆形或者十字形的核,我们就需要用到结构化元素
cv2.getStructuringElement()
第一个参数表示核的形状。可以选择三种
矩形:MORPH_RECT;
交叉形:MORPH_CROSS;
椭圆形:MORPH_ELLIPSE;
第二个参数表示核的尺寸。

注意对象要为白色,本文图对象为黑色,所有我在代码里用啦反二值化

图像腐蚀

腐蚀主要针对的是二值图像,如只有0和1两个值,
两个输入对象:1原始二值图像,2卷积核
使用卷积核遍历原始二值图像,如果卷积核对应的元素值均为1,其值才为1,否则为0。
即用卷积核对应的最小元素替换掉当前中心像素。

腐蚀作用:对象大小减少一个像素,平滑对象边缘,弱化或者分割图像之间的半岛性连接。

使用方法:erode 中文翻译:侵蚀
处理结果=cv2.erode(原始图像src,卷积核kernel,迭代次数iterations)
卷积核kernel:一般为正方形数组
如:k=np.ones((5,5),np.uint8)
迭代次数iterations:腐蚀次数,默认1

import cv2 as cv
import numpy as np


def erode_demo(image):
    print(image.shape)
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY_INV | cv.THRESH_OTSU)
    cv.imshow("binary", binary)
    kernel = cv.getStructuringElement(cv.MORPH_RECT, (3, 3))#卷积核
    #kernel = np.ones((3, 3), np.uint8)
    dst = cv.erode(binary, kernel)
    cv.imshow("erode_demo", dst)
print("--------- Python OpenCV Tutorial ---------")
src = cv.imread("fushi.jpg")
src=cv.resize(src,None,fx=0.4,fy=0.4)
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
erode_demo(src)
cv.waitKey(0)
cv.destroyAllWindows()

对彩色图像进行膨胀或腐蚀

import cv2 as cv
print("--------- Python OpenCV Tutorial ---------")
src = cv.imread("limi.jpg")
src=cv.resize(src,None,fx=0.3,fy=0.3)
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
kernel = cv.getStructuringElement(cv.MORPH_RECT, (3, 3))
dst = cv.erode(src, kernel)#腐蚀
cv.imshow("result", dst)
cv.waitKey(0)
cv.destroyAllWindows()

开运算

开运算:对图像先进行腐蚀,然后对腐蚀后的图进行膨胀
开操作=腐蚀+膨胀
主要应用在二值图像,灰度 图像也可以。
可以消除背景噪声
morphologyEx
运算结果=cv2.morphologyEx(源图像img,cv2.MORPH_OPEN,卷积核k)
cv2.MORPH_OPEN:开运算

import cv2 as cv
import numpy as np


def open_demo(image):
    print(image.shape)
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
    cv.imshow("binary", binary)
    kernel = cv.getStructuringElement(cv.MORPH_ELLIPSE, (5, 5))#cv.MORPH_ELLIPSE椭圆形,可以选择其他形状
    binary = cv.morphologyEx(binary, cv.MORPH_OPEN, kernel)
    cv.imshow("open-result", binary)

print("--------- Python OpenCV Tutorial ---------")
src = cv.imread("morph.png")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
open_demo(src)
cv.waitKey(0)
cv.destroyAllWindows()

消除了背景小白点噪声

闭运算

对图像进行先膨胀,再腐蚀。
有助于关闭前景物体上的小孔,或者小黑点。
morphologyEx
运算结果=cv2.morphologyEx(源图像img,cv2.MORPH_CLOSE,卷积核k)
cv2.MORPH_CLOSE:闭运算
合理选择卷积核大小,太小了无法去除前景图的黑点
主要应用在二值图像,灰度 图像也可以。

import cv2 as cv
import numpy as np

def close_demo(image):
    print(image.shape)
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
    cv.imshow("binary", binary)
    kernel = cv.getStructuringElement(cv.MORPH_RECT, (15, 15))
    binary = cv.morphologyEx(binary, cv.MORPH_CLOSE, kernel)
    cv.imshow("close_demo", binary)
print("--------- Python OpenCV Tutorial ---------")
src = cv.imread("morph1.png")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
close_demo(src)
cv.waitKey(0)

消除了前景色小黑点

顶帽

图像礼帽 也叫图像顶帽
礼帽图像=原始图像-开运算图像
得到噪声图像
开运算:先腐蚀再膨胀
使用方法:morphologyEx
cv2.MORPH_TOPHAT
结果=cv2.morphologyEx(原始图像,cv2.MORPH_TOPHAT,卷积核)
卷积核示例:k=np.ones((10,10),np.uint8)

import cv2 as cv
import numpy as np

def hat_gray_demo(image):
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    kernel = cv.getStructuringElement(cv.MORPH_RECT, (15, 15))#卷积核
    dst = cv.morphologyEx(gray, cv.MORPH_TOPHAT, kernel)
    cimage = np.array(gray.shape, np.uint8)
    cimage = 120;
    dst = cv.add(dst, cimage)
    cv.imshow("tophat", dst)
print("--------- Python OpenCV Tutorial ---------")
src = cv.imread("morph.png")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
hat_gray_demo(src)
cv.waitKey(0)
cv.destroyAllWindows()

代码采用了基于灰度度,也可以基于二值图。
采用不同大小的卷积核,得到的噪声小白点也不一样。

黑帽

黑帽图像=闭运算图像-原始图像
得到图像内部的小孔,或前景色的小黑点
闭运算:对图像进行先膨胀,再腐蚀。有助于关闭前景物体上的小孔,或者小黑点。
使用对象:二值图像
使用方法:morphologyEx
cv2.MORPH_BLACKHAT
结果=cv2.morphologyEx(原始图像,cv2.MORPH_BLACKHAT,卷积核)
卷积核示例:k=np.ones((10,10),np.uint8)

import cv2 as cv
import numpy as np

def hat_binary_demo(image):
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
    kernel = cv.getStructuringElement(cv.MORPH_RECT, (15, 15))
    dst = cv.morphologyEx(binary, cv.MORPH_BLACKHAT, kernel)
    cv.imshow("tophat", dst)
print("--------- Python OpenCV Tutorial ---------")
src = cv.imread("morph1.png")

cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
hat_binary_demo(src)
cv.waitKey(0)
cv.destroyAllWindows()

梯度运算

基本梯度运算结果=cv2.morphologyEx(源图像img,cv2.MORPH_GRADIENT,卷积核k)

基本梯度

import cv2 as cv
import numpy as np
def hat_binary_demo(image):
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
    kernel = cv.getStructuringElement(cv.MORPH_RECT, (3, 3))
    dst = cv.morphologyEx(binary, cv.MORPH_GRADIENT, kernel)
    cv.imshow("tophat", dst)
print("--------- Python OpenCV Tutorial ---------")
src = cv.imread("morph1.png")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
hat_binary_demo(src)
cv.waitKey(0)
cv.destroyAllWindows()

外梯度内梯度

import cv2 as cv
import numpy as np

def gradient2_demo(image):
    kernel = cv.getStructuringElement(cv.MORPH_RECT, (3, 3))
    dm = cv.dilate(image, kernel)
    em = cv.erode(image, kernel)
    dst1 = cv.subtract(image, em) # internal gradient
    dst2 = cv.subtract(dm, image) # external gradient
    cv.imshow("internal", dst1)
    cv.imshow("external", dst2)
print("--------- Python OpenCV Tutorial ---------")
src = cv.imread("morph1.png")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
gradient2_demo(src)
cv.waitKey(0)
cv.destroyAllWindows()

电气专业的计算机萌新,写博文不容易。如果你觉得本文对你有用,请点个赞支持下,谢谢。

猜你喜欢

转载自blog.csdn.net/kobeyu652453/article/details/107399855