zoukankan      html  css  js  c++  java
  • 【python-opencv】17-形态学操作-腐蚀与膨胀

    形态学操作其实就是改变物体的形状,比如腐蚀就是"变瘦",膨胀就是"变胖",看下图就明白了:

    形态学操作一般作用于二值化图(也可直接作用于原图),来连接相邻的元素或分离成独立的元素。腐蚀和膨胀是针对图片中的白色部分

    腐蚀

    腐蚀的效果是把图片"变瘦",其原理是在原图的小区域内取局部最小值。因为是二值化图,只有0和255,所以小区域内有一个是0该像素点就为0:

    这样原图中边缘地方就会变成0,达到了瘦身目的

     OpenCV中用cv2.erode()函数进行腐蚀,只需要指定核的大小就行:

    img = cv2.imread('j.bmp', 0)
    kernel = np.ones((5, 5), np.uint8)
    erosion = cv2.erode(img, kernel)  # 腐蚀

    这个核也叫结构元素,因为形态学操作其实也是应用卷积来实现的。

    结构元素可以是矩形/椭圆/十字形,可以用cv2.getStructuringElement()来生成不同形状的结构元素,比如:

    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))  # 矩形结构
    kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))  # 椭圆结构
    kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (5, 5))  # 十字形结构

    膨胀

    膨胀与腐蚀相反,取的是局部最大值,效果是把图片"变胖":

    dilation = cv2.dilate(img, kernel)  # 膨胀

    开/闭运算

    先腐蚀(瘦)后膨胀(胖)叫开运算(因为先腐蚀会分开物体,这样容易记住),其作用是:分离物体,消除小区域。这类形态学操作用cv2.morphologyEx()函数实现:

    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))  # 定义结构元素
    
    img = cv2.imread('j_noise_out.bmp', 0)
    opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)  # 开运算

    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)
        # kernel = np.ones((5,5),np.uint16)
        kernel = cv.getStructuringElement(cv.MORPH_RECT,(5,5))
        dst = cv.morphologyEx(binary,cv.MORPH_OPEN,kernel)
        cv.imshow("open_demo",dst)

    闭运算则相反:先膨胀后腐蚀先膨胀会使白色的部分扩张,以至于消除/"闭合"物体里面的小黑洞,所以叫闭运算

    img = cv2.imread('j_noise_in.bmp', 0)
    closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)  # 闭运算

    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 = np.ones((5,5),np.uint16)
        kernel = cv.getStructuringElement(cv.MORPH_RECT,(5,5))
        dst = cv.morphologyEx(binary,cv.MORPH_CLOSE,kernel)
        cv.imshow("close_demo",dst)

    经验之谈很多人对开闭运算的作用不是很清楚,看上图↑:
    如果我们的目标物体外面有很多无关的小区域,就用开运算去除掉;
    如果物体内部有很多小黑洞,就用闭运算填充掉。
    开操作去掉外部小的干扰,用腐蚀也能做到,二者的区别在于开操作只去掉外部小的干扰而保留了其他部分不变

    其他形态学操作

    • 形态学梯度:膨胀图减去腐蚀图,dilation - erosion,这样会得到物体的轮廓:
    img = cv2.imread('school.bmp', 0)
    gradient = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)

    • 顶帽(tophat)原图减去开操作后的图:src - opening
    tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)
    • 黑帽(blackhat):闭运算图像与原图像差值:closing - src
    blackhat = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)

     

    def tophat_demo(image):
        gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
        ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY_INV | cv.THRESH_OTSU)
        # kernel = np.ones((5,5),np.uint16)
        kernel = cv.getStructuringElement(cv.MORPH_RECT, (5, 5))
        dst = cv.morphologyEx(gray, cv.MORPH_GRADIENT, kernel)
        # dst = cv.morphologyEx(binary, cv.MORPH_BLACKHAT, kernel)
        """给dst图像添加亮度"""
        # cimage = np.array(gray.shape,np.uint8)
        # cimage = 120
        # dst = cv.add(dst,cimage)
        cv.imshow("MORPH_GRADIENT_demo", dst)

    Binary二值图进行腐蚀 膨胀等形态学操作

    def erode_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)
        # kernel = np.ones((5,5),np.uint16)
        kernel = cv.getStructuringElement(cv.MORPH_RECT,(5,5))
        dst = cv.erode(binary,kernel=kernel)
        cv.imshow("erode_demo",dst)
    
    def dilate_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 = np.ones((5,5),np.uint16)
        kernel = cv.getStructuringElement(cv.MORPH_RECT,(5,5))
        dst = cv.dilate(binary,kernel=kernel)
        cv.imshow("dilate_demo",dst)

    BGR原图直接进行腐蚀 膨胀等形态学操作

    """BGR图像直接进行腐蚀 膨胀"""
    src0 = cv.imread('beauty1.jpg')
    cv.imshow('input_image',src0)
    kernel = cv.getStructuringElement(cv.MORPH_RECT,(5,5))
    dilate_dst = cv.dilate(src0,kernel=kernel)
    cv.imshow("dilate_dst",dilate_dst)
    erode_dst = cv.erode(src0,kernel=kernel)
    cv.imshow("erode_dst",erode_dst)

     参考:

    https://docs.opencv.org/3.0-beta/doc/py_tutorials/py_imgproc/py_morphological_ops/py_morphological_ops.html#morphological-ops

    https://www.jianshu.com/p/05ef50ac89ac

  • 相关阅读:
    asp.net编程基础
    http://blog.csdn.net/pjw100/article/details/5261582
    英雄无敌3版的仙剑奇侠传
    另类DATAGRID数据编辑修改
    使用INDY组件发送邮件,DEMO程序没有讲到的一些内容.如邮件格式定议
    .net 简单实现MD5
    VB.NET 对于类型的传递按值或者按引用
    Start with Database Connection Pool 连接管理
    ASP页面之间传值
    正则表达式
  • 原文地址:https://www.cnblogs.com/XJT2018/p/9958895.html
Copyright © 2011-2022 走看看