Opencv Zhang-Suen细化算法

gazo.png进行Zhang-Suen细化算法处理吧!

但是,请注意,有必要反转gazo.png的值,因为以下所有操作都将0作为线,将1作为背景。

对于中心像素x_1(x,y)8-近邻定义如下:
\begin{matrix}
x_9&x_2&x_3\\
x_8&x_1&x_4\\
x_7&x_6&x_5
\end{matrix}

考虑以下两个步骤:

  • 步骤一:执行光栅扫描并标记满足以下5个条件的所有像素:
    1. 这是一个黑色像素;

    2. 顺时针查看x_2x_3\cdotsx_9x_2时,从01的变化次数仅为1

    3. $$x_2$$、$$x_3$$、$$\cdots$$、$$x_9$$中$$1$$的个数在$$2$$个以上$$6$$个以下;

    4. $$x_2$$、$$x_4$$、$$x_6$$中的一个为1;

    5. $$x_4$$、$$x_6$$、$$x_8$$中的一个为1;

    将标记的像素全部变为1

  • 步骤二:执行光栅扫描并标记满足以下5个条件的所有像素:

    1. 这是一个黑色像素;
    2. 顺时针查看x_2x_3\cdotsx_9x_2时,从0到1的变化次数仅为1;
    3. $$x_2$$、$$x_3$$、$$\cdots$$、$$x_9$$中$$1$$的个数在$$2$$个以上$$6$$个以下;
    4. $$x_2$$、$$x_4$$、$$x_6$$中的一个为1;
    5. $$x_2$$、$$x_6$$、$$x_8$$中的一个为1;

    将标记的像素全部变为1

反复执行步骤一和步骤二直到没有点变化。

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
                if out[y-1, x] + out[y, x+1] + out[y+1, x] < 1:
                    continue

                # condition 5
                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
                if out[y-1, x] + out[y, x+1] + out[y, x-1] < 1:
                    continue

                # condition 5
                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("gazo.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()

输入(gazo.png):

Opencv Zhang-Suen细化算法

输出:

Opencv Zhang-Suen细化算法

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程