美文网首页
形态学操作

形态学操作

作者: Lonelyroots | 来源:发表于2021-11-14 22:02 被阅读0次

    想学习机器视觉和图像处理的朋友看过来!
    数学形态学提供了一组有用的方法,能够用来调整分割区域的形状以获得比较理想的结果,它最初是从数学中的集合论发展而来并用于处理二值图的,虽然运算很简单,但是往往可以产生很好的效果,后来这些方法推广到普通的灰度级图像处理中。常用的形态学处理方法包括:腐蚀、膨胀、开运算、闭运算、礼帽运算、黑帽运算,其中膨胀与腐蚀是图像处理中最常用的形态学操作手段,其他方法是两者相互组合而产生的。

    膨胀:

    取每个位置领域内最大值,所以膨胀后输出图像的总体亮度的平均值比起原图会有所升高,图像中比较亮的区域的面积会变大,而较暗物体的尺寸会减小甚至消失。

    # encoding = 'utf8'
    import cv2
    import numpy as np
    img = cv2.imread('8-3.jpg',0)
    
    kernel = np.ones((10,10),np.uint8)
    t,rst = cv2.threshold(img,127,255,cv2.THRESH_BINARY)
    dilation = cv2.dilate(rst,kernel)
    
    cv2.imshow('image',rst)
    cv2.imshow('dilation',dilation)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    腐蚀:

    腐蚀操作与膨胀操作类似,只是它取每个位置领域内最小值,所以腐蚀后输出图像的总体亮度的平均值比起原图会有所降低,图像中比较亮的区域的面积会变小甚至消失,而较暗物体的尺寸会扩大。

    # encoding = 'utf8'
    import cv2
    import numpy as np
    img = cv2.imread('8-2.jpg',0)
    
    kernel = np.ones((10,10),np.uint8)
    t,rst = cv2.threshold(img,127,255,cv2.THRESH_BINARY)        # 二值化
    erosion = cv2.erode(rst,kernel)     # 腐蚀
    
    cv2.imshow('image',img)
    cv2.imshow('imagel',rst)
    cv2.imshow('erosion',erosion)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    开运算:

    先腐蚀后膨胀的操作
    可以去除噪声,消除小物体
    在纤细点处分离物体
    平滑较大物体的边界的同时并不明显改变其面积

    # encoding = 'utf8'
    import cv2
    import numpy as np
    img = cv2.imread('8-4.jpg',0)
    
    kernel = np.ones((10,10),np.uint8)
    t,rst = cv2.threshold(img,127,255,cv2.THRESH_BINARY)
    r1 = cv2.morphologyEx(rst,cv2.MORPH_OPEN,kernel)
    
    cv2.imshow('image',rst)
    cv2.imshow('r1',r1)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    闭运算:

    先膨胀后腐蚀
    可排除小型空洞(指黑色区域)
    平滑物体轮廓
    弥合(连接)窄的间断点,沟壑
    填补轮廓线断裂

    # encoding = 'utf8'
    import cv2
    import numpy as np
    img1 = cv2.imread('8-5.jpg',0)
    img2 = cv2.imread('8-6.jpg',0)
    
    kernel = np.ones((10,10),np.uint8)
    t1,rst1 = cv2.threshold(img1,127,255,cv2.THRESH_BINARY)
    t2,rst2 = cv2.threshold(img2,127,255,cv2.THRESH_BINARY)
    r1 = cv2.morphologyEx(rst1,cv2.MORPH_CLOSE,kernel)
    r2 = cv2.morphologyEx(rst2,cv2.MORPH_CLOSE,kernel)
    
    cv2.imshow('image1',rst1)
    cv2.imshow('image2',rst2)
    cv2.imshow('r1',r1)
    cv2.imshow('r2',r2)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    形态梯度学运算:

    对二值图进行这一操作可以将边缘突出出来,我们可以用形态学梯度来保留物体的边缘轮廓

    # encoding = 'utf8'
    import cv2
    import numpy as np
    img = cv2.imread('8-7.jpg',0)
    
    kernel = np.ones((10,10),np.uint8)
    t,rst = cv2.threshold(img,127,255,cv2.THRESH_BINARY)
    r1 = cv2.morphologyEx(rst,cv2.MORPH_GRADIENT,kernel)
    
    cv2.imshow('image',rst)
    cv2.imshow('r1',r1)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    形态学练习:

    import cv2
    import numpy as np
    
    img1 = cv2.imread('11.jpg')
    img2 = cv2.imread('12.jpg')
    img3 = cv2.imread('13.jpg')
    img4 = cv2.imread('14.jpg')
    img5 = cv2.imread('22.jpg')
    img6 = cv2.imread('22.jpg',0)
    
    a,b = img6.shape
    print("22文件的面积是",a*b)
    print("22文件的周长是",(a+b)*2)
    
    kernel = np.ones((10,10),np.uint8)
    t1,rst1 = cv2.threshold(img1,127,255,cv2.THRESH_BINARY)
    t2,rst2 = cv2.threshold(img2,127,255,cv2.THRESH_BINARY)
    t3,rst3 = cv2.threshold(img3,127,255,cv2.THRESH_BINARY)
    t4,rst4 = cv2.threshold(img4,127,255,cv2.THRESH_BINARY)
    t5,rst5 = cv2.threshold(img5,127,255,cv2.THRESH_BINARY)     #二值化,大于127阈值的被置为255,小于127的被置为0
    
    r1 = cv2.morphologyEx(rst1,cv2.MORPH_CLOSE,kernel)
    r2 = cv2.morphologyEx(rst2,cv2.MORPH_OPEN,kernel)
    r3 = cv2.morphologyEx(rst3,cv2.MORPH_OPEN,kernel)
    r4 = cv2.morphologyEx(rst4,cv2.MORPH_OPEN,kernel)
    r5 = cv2.morphologyEx(rst5,cv2.MORPH_GRADIENT,kernel)
    
    def dHash(img):
        # 差值哈希算法
        # 缩放8*8
        img = cv2.resize(img,(9,8))
        # 转换灰度图
        gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
        hash_str = ''
        # 每行前一个像素大于后一个像素为1,相反为0,生成哈希
        for i in range(8):
            for j in range(8):
                if gray[i,j] > gray[i,j+1]:
                    hash_str = hash_str+'1'
                else:
                    hash_str = hash_str+'0'
        return hash_str
    
    def cmpHash(hash1, hash2):
        # Hash值对比
        # 算法中1和0顺序组合起来的即是图片的指纹hash。顺序不固定,但是比较的时候必须是相同的顺序。
        # 对比两幅图的指纹,计算汉明距离,即两个64位的hash值有多少是不一样的,不同的位数越小,图片越相似
        # 汉明距离:一组二进制数据变成另一组数据所需要的步骤,可以衡量两图的差异,汉明距离越小,则相似度越高。汉明距离为0,即两张图片完全一样
        n = 0
        # hash长度不同则返回-1代表传参出错
        if len(hash1) != len(hash2):
            return -1
        # 遍历判断
        for i in range(len(hash1)):
            # 不相等则n计数+1,n最终为相似度
            if hash1[i] != hash2[i]:
                n = n + 1
        return n
    
    li1 = [img1,img2,img3,img4]
    li2=[]
    max_n = 0
    for i in range(len(li1)):
        hash1 = dHash(li1[i])
        hash2 = dHash(img5)
        n = cmpHash(hash1, hash2)
        print(n)
        li2.append(n)
        for j in li2:
            if j > max_n:
                max_n = j
            else:
                max_n = max_n
    for i in range(len(li1)):
        if max_n==li2[i]:
            t1, rst6 = cv2.threshold(li1[i], 127, 255, cv2.THRESH_BINARY)
            r6 = cv2.morphologyEx(rst6, cv2.MORPH_CLOSE, kernel)
            cv2.imshow('r6', r6)
    
    cv2.imshow('r1',r1)
    cv2.imshow('r2',r2)
    cv2.imshow('r3',r3)
    cv2.imshow('r4',r4)
    cv2.imshow('r5',r5)
    
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    运行结果:

    文章到这里就结束了!希望大家能多多支持机器视觉(系列)!私聊我,可以问关于本文章的问题!以后每天都会发布新的文章,喜欢的点点关注!一个陪伴你学习的新青年!不管多忙都会更新下去,一起加油!

    相关文章

      网友评论

          本文标题:形态学操作

          本文链接:https://www.haomeiwen.com/subject/dncctrtx.html