美文网首页
二值形态学算法的实现

二值形态学算法的实现

作者: 此间不留白 | 来源:发表于2020-06-14 16:32 被阅读0次

前言

二值形态学的学习过程中,已经学习了二值形态学算法的基本理论知识,本篇文章将会利用Python实现有关二值形态学的基本算法,包括膨胀腐蚀运算,图像的开闭运算等。为了验证形态学的算法的正确性,本篇文章将会利用OpenCV算法库中的二值形态学算法和Python实现的二值形态学算法的结果进行对比学习。

在实现二值形态学之前,首先需要对原始图像进行预处理,这些预处理部分包括图像灰度和图像二值化过程,关于图像的二值化实现,本次实现采用的是OTSU算法,在图像算法处理中,已经对OTSU算法的实现,有过介绍,本篇文章,将会直接使用OpenCV算法库提供的OTSU阈值方法实现灰度图像的二值化。

原始图像

对上述所示的原始图像,实现灰度化与二值化的代码如下所示:

import cv2
import numpy as np
img = cv2.imread("./test.jpg")
#opencv中的图像灰度化方法
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# 灰度化图像显示
cv2.imshow("test image",gray)  #显示图片
cv2.waitKey(0)
//OTSU算法实现图像二值化,dst为二值化的图像,而retval表示利用OTSU算法得到的阈值
retval, dst = cv2.threshold(gray, 0, 255, cv2.THRESH_OTSU)
cv2.imshow("binary image",dst)
cv2.waitKey(0)

灰度化和二值化的图像效果如下所示:


图像膨胀的实现

图像膨胀的实现,可以看作利用结构化元素(类似于卷积运算中的kernel),对图像进行逐像素的或操作。膨胀算法的实现过程中,通过定义一个3×3的结构化元素,逐像素地对原始图像实现或运算,可以看成是在原始图像被结构化元素所覆盖的3×3区域内,寻找该区域内的最大像素值,并用3×3区域内所找到的最大的像素值代替二值化图像的原始像素值,其实现代码如下所示:


def dilated_img(src):
    m,n=src.shape
    max_=0
    result_img = np.zeros(src.shape)
    for r in range(1,m):
        for c in range(1,n):
            result_img[r,c] = np.max(src[r-1:r+2,c-1:c+2])
    return result_img

作为对比,将自定义的膨胀算法与opencv提供的膨胀算法进行对比,其实现效果如下图所示:

# 自定义的膨胀算法
result = dilated_img(dst)  
cv2.imshow("dilated img",result)
cv2.waitKey(0)

#opencv提供的图像膨胀方法
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))  # 3×3的矩形结构化元素
dilation = cv2.dilate(dst, kernel) 
cv2.imshow("dilation img",dilation)
cv2.waitKey(0)

图像腐蚀的实现

二值图像的腐蚀算法实现和膨胀算法的实现基本一样,只不过腐蚀算法中,结构化元素所覆盖的二值化图像中的像素区域执行的与操作,在代码实现中,这一与操作,可以被“翻译”用被结构化元素所覆盖的原始图像中3×3的像素区域中的最小值替换原始图像中的原来的像素点。仍旧将结构化元素定义为3×3的矩形,则图像实现腐蚀的代码和腐蚀后的效果如下图所示:

def erode_img(src):
    m,n=src.shape
    max_=0
    result_img = np.zeros(src.shape)
    for r in range(1,m):
        for c in range(1,n):
            result_img[r,c] = np.min(src[r-1:r+2,c-1:c+2])
    return result_img
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))  # 3×3的矩形结构化元素
erosion = cv2.erode(dst, kernel) 
cv2.imshow("erosion img",erosion)
cv2.waitKey(0)

图像开运算和闭运算的实现

  • 图像开运算的实现

图像的开运算,即使对原始的二值图像先进行一次腐蚀运算,在对腐蚀运算得到的二值图像进行一次膨胀运算的过程,其实现代码和效果如下所示:

#手动实现的开运算方式
def bin_open(src):
    e_result = erode_img(src)
    result = dilated_img(e_result)
    return result
result = bin_open(dst)
cv2.imshow("open img",result)
cv2.waitKey(0)
# opencv实现的开运算
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))  
result = cv2.morphologyEx(dst, cv2.MORPH_OPEN, kernel)
  • 二值闭运算的实现
    二值闭运算的实现与开运算的实现非常相似,只不过,二值闭运算的实现方式是先对原始的二值图像进行一次膨胀运算,再对膨胀运算后的图像进行一次腐蚀运算,其实现代码和效果如下图所示:
# 自定义的闭运算
def bin_close(src):
    e_result = dilated_img(src)
    result = erode_img(e_result)
    return result

result = bin_close(dst)
cv2.imshow("close img",result)
cv2.waitKey(0)
# opencv实现的闭运算
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3)) 
result = cv2.morphologyEx(dst, cv2.MORPH_CLOSE, kernel)

Distance Transform

对一幅图像执行Distance Transform转换可以认为是对一幅原始的二值图像不断进行腐蚀的过程,每次将腐蚀掉的像素置换为腐蚀的次数,从distance transform的过程可以看出,这是一个将二值图像像素为1的像素点进行逐渐替换的过程,执行distance transform过程中,图像的像素值逐渐增大。其详细过程已二值形态学算法中有过详细介绍,
在具体实现代码如下所示:

def distanceTransform(src):

    src_r= src.copy()
    
    c=2
    
    src_r = src_r/255
    while(src.any()==1): # 知道整个图片不存在为1的像素
        src = cv2.erode(src,kernel) # 用3*3 的SE进行腐蚀运算
      
        [x,y] = np.where(src_r==1)
        for i in range(len(x)):
            if(src[x[i],y[i]]==0):
                src_r[x[i],y[i]]=c
                
        c = c+1
        
    src_r = (src_r/src_r.max())*255
    
    return src_r
          

执行此代码之后,图像的效果如下所示:


图像Skeleton实现

为了得到一幅二值图像的Skeleton,整个图像的执行过程可解释为对原始二值图像先进行腐蚀,再对腐蚀后的图像实现开运算,再将腐蚀得到的图像和开运算得到的图像进行相减,最后将相减得到一系列图像进行累加的过程,其公式如下所示:

  • 根据所选SE的大小,得到一系列Skeleton的子集
    S_i(F)=(F \ominus r_iK)-[(F \ominus r_iK) \circ K] \ \ 其中, i=0,1,2…,n
    其中,r_iK表示一系列尺度不同的SE
  • 对得到的一系列SKeleton子集进行求并集:
    S(F) = \bigcup_{i=0}^{n}S_i(F)

def get_skeleton(src,kernel=kernel):
    m,n = src.shape
    img_result = np.zeros((m,n))
    c = 0
    
    while(src.any()==1):
        # 先对原始的二值图像进行腐蚀操作
        # 完成第一次腐蚀操作
       
        src = cv2.erode(src,kernel)
        
        temp_img = src.copy()
        
        #再对图像进行开运算
        temp_img = cv2.morphologyEx(temp_img,cv2.MORPH_OPEN,kernel)
        
        # 腐蚀后的图像与开运算得到的图像相减
        
        img = src - temp_img
        
        img_result = img_result+img
        
        c = c+1
    return img_result,c
        

本次代码实现中,用的是3×3的结构化元素,其实现效果如下所示:


相关文章

  • 二值形态学算法的实现

    前言 在二值形态学的学习过程中,已经学习了二值形态学算法的基本理论知识,本篇文章将会利用Python实现有关二值形...

  • 灰度形态学算法的实现

    前言 灰度形态学算法中介绍了灰度形态学算法的相关原理,本篇文章将会利用python结合numpy和opencv实现...

  • 灰度形态学基本运算

    上海交通大学 医学图像处理 与二值形态学相对应另一种形态学运算是灰度形态学。灰度形态学与二值形态学相比,不仅在图像...

  • OpenCV+Python形态学

    图像的形态学处理主要用于二值图像,白色部分是主体。 Erosion 腐蚀 算法:一个固定大小的kernel,在一个...

  • 形态学算法

    上海交通大学 医学图像处理技术 形态学的二值运算 形态学二值运算包括膨胀,腐蚀,开运算和闭运算基本方法,如下图所示...

  • Android NDK开发:利用OpenCV实现图形验证码的提取

    目录 效果演示 实现原理 首先将图像转换为灰度图像,然后将图像转换为二值图像,然后利用形态学操作的开操作(先膨胀后...

  • matlab|二值形态学处理

    图像的二值形态学处理,是利用集合论的思想,能够简化图像数据,保持基本形状特征,除去不相干的结构,此外还能并行实现。...

  • 二值形态学

    姓名:熊子豪 学号:19011210143 转载自 https://blog.csdn.net/qq_27248...

  • 给定一个数组,判断其实否为二叉搜索树的后序遍历(Java)

    实现的思想 后序遍历的特点:根在最后输出二叉搜索树的特点:根的值大于左子树值,小于右子树值 算法实现:① 后序遍历...

  • 算法题目10:33台阶法

    实现方式(一):递归法 弊端:当n值较大时,算法执行次数过大,会奔溃。 实现方式二: 优点:算法时间几乎为0

网友评论

      本文标题:二值形态学算法的实现

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