zoukankan      html  css  js  c++  java
  • Zhang-Suen 图像细化算法python实现

    算法流程

    首先要反转原图像,因为算法之后所有的操作都将0作为前景,将1作为背景。
    中心像素x_1(x,y)的8-近邻定义如下所示:
    中心像素x_1(x,y)的8-近邻

    考虑以下两个步骤

    • 步骤1:执行光栅扫描并标记满足以下5个条件的所有像素:
      • 这是一个黑色像素;
      • 顺时针查看x2、x3、...、x9、x2时,从0到1的变化次数仅为1;
      • x2、x3、...、x9中1的个数在2个以上6个以下;
      • x2、x4、x6中至少有1个为1;
      • x4、x6、x8中至少有1个为1;
        将满足条件的所有像素标为1
    • 步骤2:执行光栅扫描并标记满足以下5个条件的所有像素:
      • 这是一个黑色像素;
      • 顺时针查看x2、x3、...、x9、x2时,从0到1的变化次数仅为1;
      • x2、x3、...、x9中1的个数在2个以上6个以下;
      • x2、x4、x8中至少有1个为1;
      • x2、x6、x8中至少有1个为1;
        将满足条件的所有像素标为1
    • 反复执行步骤1和步骤2,直到没有点发生变化。
      python实现:
    import cv2
    import numpy as np
    import matplotlib.pyplot as plt
    
    # Zhang Suen thining algorythm
    def Zhang_Suen_thining(img):
        # get shape
        H, W, C = img.shape
    
        # prepare out image
        out = np.zeros((H, W), dtype=np.int)
        out[img[..., 0] > 0] = 1
    
        # inverse
        out = 1 - out
    
        while True:
            s1 = []
            s2 = []
    
            # step 1 ( rasta scan )
            for y in range(1, H-1):
                for x in range(1, W-1):
                    
                    # condition 1
                    if out[y, x] > 0:
                        continue
    
                    # condition 2
                    f1 = 0
                    if (out[y-1, x+1] - out[y-1, x]) == 1:
                        f1 += 1
                    if (out[y, x+1] - out[y-1, x+1]) == 1:
                        f1 += 1
                    if (out[y+1, x+1] - out[y, x+1]) == 1:
                        f1 += 1
                    if (out[y+1, x] - out[y+1,x+1]) == 1:
                        f1 += 1
                    if (out[y+1, x-1] - out[y+1, x]) == 1:
                        f1 += 1
                    if (out[y, x-1] - out[y+1, x-1]) == 1:
                        f1 += 1
                    if (out[y-1, x-1] - out[y, x-1]) == 1:
                        f1 += 1
                    if (out[y-1, x] - out[y-1, x-1]) == 1:
                        f1 += 1
    
                    if f1 != 1:
                        continue
                        
                    # condition 3
                    f2 = np.sum(out[y-1:y+2, x-1:x+2])
                    if f2 < 2 or f2 > 6:
                        continue
                    
                    # condition 4
                    # x2 x4 x6
                    if (out[y-1, x] + out[y, x+1] + out[y+1, x]) < 1 :
                        continue
    
                    # condition 5
                    # x4 x6 x8
                    if (out[y, x+1] + out[y+1, x] + out[y, x-1]) < 1 :
                        continue
                        
                    s1.append([y, x])
    
            for v in s1:
                out[v[0], v[1]] = 1
    
            # step 2 ( rasta scan )
            for y in range(1, H-1):
                for x in range(1, W-1):
                    
                    # condition 1
                    if out[y, x] > 0:
                        continue
    
                    # condition 2
                    f1 = 0
                    if (out[y-1, x+1] - out[y-1, x]) == 1:
                        f1 += 1
                    if (out[y, x+1] - out[y-1, x+1]) == 1:
                        f1 += 1
                    if (out[y+1, x+1] - out[y, x+1]) == 1:
                        f1 += 1
                    if (out[y+1, x] - out[y+1,x+1]) == 1:
                        f1 += 1
                    if (out[y+1, x-1] - out[y+1, x]) == 1:
                        f1 += 1
                    if (out[y, x-1] - out[y+1, x-1]) == 1:
                        f1 += 1
                    if (out[y-1, x-1] - out[y, x-1]) == 1:
                        f1 += 1
                    if (out[y-1, x] - out[y-1, x-1]) == 1:
                        f1 += 1
    
                    if f1 != 1:
                        continue
                        
                    # condition 3
                    f2 = np.sum(out[y-1:y+2, x-1:x+2])
                    if f2 < 2 or f2 > 6:
                        continue
                    
                    # condition 4
                    # x2 x4 x8
                    if (out[y-1, x] + out[y, x+1] + out[y, x-1]) < 1 :
                        continue
    
                    # condition 5
                    # x2 x6 x8
                    if (out[y-1, x] + out[y+1, x] + out[y, x-1]) < 1 :
                        continue
                        
                    s2.append([y, x])
    
            for v in s2:
                out[v[0], v[1]] = 1
    
            # if not any pixel is changed
            if len(s1) < 1 and len(s2) < 1:
                break
    
        out = 1 - out
        out = out.astype(np.uint8) * 255
    
        return out
    
    
    # Read image
    img = cv2.imread("../thin.png").astype(np.float32)
    
    # Zhang Suen thining
    out = Zhang_Suen_thining(img)
    
    
    # Save result
    cv2.imwrite("out.png", out)
    cv2.imshow("result", out)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    

    实验结果:
    原图
    Zhang-Suen细化算法结果

  • 相关阅读:
    前台线程与后台线程的区别
    触发器
    Asp.net AutopostBack 属性
    Spring实战拆书--SpringBean
    侣行APP
    用android去写一个小程序
    java如何使用JUnit进行单元测试
    JDK的安装与配置以及eclipse的使用
    软件工程第一次作业(1)
    软件工程第一次作业(2)
  • 原文地址:https://www.cnblogs.com/wojianxin/p/12558423.html
Copyright © 2011-2022 走看看