十九图像的形态学操作

Posted beyond谚语

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了十九图像的形态学操作相关的知识,希望对你有一定的参考价值。

一、图像形态学

图像形态学是图像处理学科的一个单独分支学科
主要针对的是灰度图和二值图像
是由数学的集合论以及数学中的拓扑几何原理发展而来

二、膨胀操作(dilate)

3×3的卷积核


以3×3为卷积核从左往右(从上往下)开始运行,若这卷积核内存在1,则用1替代中心元素。
最大值取代中心像素
白变多,黑变少

膨胀的作用:

对象大小增加一个像素(3×3)
平滑对象边缘
减少或者填充对象之间的距离

二值图

import cv2 as cv
import numpy as np


def dilate(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, (3, 3))
    dst = cv.dilate(binary, kernel)
    cv.imshow("dilate", dst)

    
src = cv2.imread(r"G:\\Juptyer_workspace\\study\\opencv\\opencv3\\number.jpg")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
dilate(src)

cv.waitKey(0)
cv.destroyAllWindows()

效果图如下:

·彩色图·

import cv2 as cv
import numpy as np


src = cv2.imread(r"G:\\Juptyer_workspace\\study\\opencv\\opencv3\\l.png")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)

kernel = cv.getStructuringElement(cv.MORPH_RECT, (3, 3))
dst = cv.dilate(src, kernel)
cv.imshow("result", dst)

cv.waitKey(0)
cv.destroyAllWindows()

效果图如下:

三、腐蚀操作(erode)

3×3的卷积核


以3×3为卷积核从左往右(从上往下)开始运行,若这卷积核内存在0,则用0替代中心元素。
最小值取代中心像素
黑变多,白变少

二值图

import cv2 as cv
import numpy as np


def erode(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))
    dst = cv.erode(binary, kernel)
    cv.imshow("erode", dst)


src = cv2.imread(r"G:\\Juptyer_workspace\\study\\opencv\\opencv3\\number.jpg")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
erode_demo(src)

cv.waitKey(0)
cv.destroyAllWindows()

效果图如下:


彩色图

import cv2 as cv
import numpy as np


src = cv2.imread(r"G:\\Juptyer_workspace\\study\\opencv\\opencv3\\l.png")
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("erode", dst)

cv.waitKey(0)
cv.destroyAllWindows()

效果图如下:

腐蚀和膨胀针对彩色图像和二值图像

总结:膨胀---白变多黑变少、腐蚀---黑变多白变少

四、开操作(open)

开操作=腐蚀+膨胀
可以消除图像中小的干扰区域
cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU),若出现反转可以将参数设置为cv.THRESH_BINARY_INV

import cv2 as cv
import numpy as np


def open(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))
    binary = cv.morphologyEx(binary, cv.MORPH_OPEN, kernel)
    cv.imshow("open-result", binary)


src = cv2.imread(r"G:\\Juptyer_workspace\\study\\opencv\\opencv3\\test.jpg")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
open(src)

cv.waitKey(0)
cv.destroyAllWindows()

效果图如下:

五、闭操作(close)

闭操作=膨胀+腐蚀
填充小的封闭区域

import cv2 as cv
import numpy as np


def close(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, (5, 5))
    binary = cv.morphologyEx(binary, cv.MORPH_CLOSE, kernel)
    cv.imshow("close_demo", binary)


src = cv2.imread(r"G:\\Juptyer_workspace\\study\\opencv\\opencv3\\test1.jpg")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
close(src)

cv.waitKey(0)
cv.destroyAllWindows()

效果图如下:

开闭操作只针对二值图像
总结:开操作消除白点,闭操作消除黑点

六、顶帽(tophat)

原图像与开操作的差值图像

彩色图像

import cv2 as cv
import numpy as np


def tophat(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)



src = cv2.imread(r"G:\\Juptyer_workspace\\study\\opencv\\opencv3\\l.png")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
tophat(src)
cv.waitKey(0)

cv.destroyAllWindows()

效果图如下:

二值图像

import cv2 as cv
import numpy as np


def tophat_binary(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, (5, 5))
    dst = cv.morphologyEx(binary, cv.MORPH_TOPHAT, kernel)
    cv.imshow("tophat_binary", dst)


src = cv2.imread(r"G:\\Juptyer_workspace\\study\\opencv\\opencv3\\test.jpg")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
tophat_binary(src)
cv.waitKey(0)

cv.destroyAllWindows()

效果图如下:

七、黑帽(blackhat)

闭操作与原图像的差值图像
彩色图像

import cv2 as cv
import numpy as np


def blackhat(image):
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    kernel = cv.getStructuringElement(cv.MORPH_RECT, (15, 15))
    dst = cv.morphologyEx(gray, cv.MORPH_BLACKHAT, kernel)
    """
    若图片不够亮可以对图像进行整体增加亮度
    cimage = np.array(gray.shape, np.uint8)
    cimage = 120;
    dst = cv.add(dst, cimage)
    """
    cv.imshow("blackhat", dst)



src = cv2.imread(r"G:\\Juptyer_workspace\\study\\opencv\\opencv3\\l.png")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
blackhat(src)
cv.waitKey(0)

cv.destroyAllWindows()

效果图如下:

二值图像

import cv2 as cv
import numpy as np


def blackhat_binary(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, (5, 5))
    dst = cv.morphologyEx(binary, cv.MORPH_BLACKHAT, kernel)
    cv.imshow("blackhat_binary", dst)


src = cv2.imread(r"G:\\Juptyer_workspace\\study\\opencv\\opencv3\\test.jpg")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
blackhat_binary(src)
cv.waitKey(0)

cv.destroyAllWindows()

效果图如下:

八、形态学梯度(Gradient)

基本梯度:膨胀后的图像减去腐蚀后的图像得到的差值图像
内部梯度:原图像减去腐蚀之后的图像得到的差值图像
外部梯度:图像膨胀之后减去原来的图像得到的差值图像

基本梯度

import cv2 as cv
import numpy as np


def base_gradient(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("base_gradient", dst)


src = cv2.imread(r"G:\\Juptyer_workspace\\study\\opencv\\opencv3\\test.jpg")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
base_gradient(src)

cv.waitKey(0)
cv.destroyAllWindows()

效果图如下:

内梯度和外梯度

import cv2 as cv
import numpy as np


def ex_in_gradient(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)


src = cv2.imread(r"G:\\Juptyer_workspace\\study\\opencv\\opencv3\\test.jpg")
cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
cv.imshow("input image", src)
ex_in_gradient(src)

cv.waitKey(0)
cv.destroyAllWindows()

效果图如下:

以上代码中,想要获取不同的需求只需要修改这个获取结构元素的方法中的参数即可cv.getStructuringElement(cv.MORPH_RECT, (15, 15))

以上是关于十九图像的形态学操作的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV---其他形态学操作

Python从零到壹丨图像增强的顶帽运算和底帽运算

省选模拟二十九 题解

形态学操作-腐蚀与膨胀

图像形态学操作之顶帽操作(TopHat)与黑帽操作(BlackHat)

Matlab图像形态学处理—开操作和闭操作