Task: Zhang-Suen thinning algorithm







Python: 


beforeTxt = 


smallrc01 = 

rc01 = 

def intarray(binstring):
    
    return [[1 if ch == '1' else 0 for ch in line] 
            for line in binstring.strip().split()]

def chararray(intmatrix):
    
    return '\n'.join(''.join(str(p) for p in row) for row in intmatrix)

def toTxt(intmatrix):
    Return 8-neighbours of point p1 of picture, in order'''
    i = image
    x1, y1, x_1, y_1 = x+1, y-1, x-1, y+1
    
    return [i[y1][x],  i[y1][x1],   i[y][x1],  i[y_1][x1],  
            i[y_1][x], i[y_1][x_1], i[y][x_1], i[y1][x_1]]  

def transitions(neighbours):
    n = neighbours + neighbours[0:1]    
    return sum((n1, n2) == (0, 1) for n1, n2 in zip(n, n[1:]))

def zhangSuen(image):
    changing1 = changing2 = [(-1, -1)]
    while changing1 or changing2:
        
        changing1 = []
        for y in range(1, len(image) - 1):
            for x in range(1, len(image[0]) - 1):
                P2,P3,P4,P5,P6,P7,P8,P9 = n = neighbours(x, y, image)
                if (image[y][x] == 1 and    
                    P4 * P6 * P8 == 0 and   
                    P2 * P4 * P6 == 0 and   
                    transitions(n) == 1 and 
                    2 <= sum(n) <= 6):      
                    changing1.append((x,y))
        for x, y in changing1: image[y][x] = 0
        
        changing2 = []
        for y in range(1, len(image) - 1):
            for x in range(1, len(image[0]) - 1):
                P2,P3,P4,P5,P6,P7,P8,P9 = n = neighbours(x, y, image)
                if (image[y][x] == 1 and    
                    P2 * P6 * P8 == 0 and   
                    P2 * P4 * P8 == 0 and   
                    transitions(n) == 1 and 
                    2 <= sum(n) <= 6):      
                    changing2.append((x,y))
        for x, y in changing2: image[y][x] = 0
        
        
    return image
            

if __name__ == '__main__':
    for picture in (beforeTxt, smallrc01, rc01):
        image = intarray(picture)
        print('\nFrom:\n%s' % toTxt(image))
        after = zhangSuen(image)
        print('\nTo thinned:\n%s' % toTxt(after))


VB: Public n As Variant
Private Sub init()
    n = [{-1,0;-1,1;0,1;1,1;1,0;1,-1;0,-1;-1,-1;-1,0}]
End Sub

Private Function AB(text As Variant, y As Integer, x As Integer, step As Integer) As Variant
    Dim wtb As Integer
    Dim bn As Integer
    Dim prev As String: prev = "#"
    Dim next_ As String
    Dim p2468 As String
    For i = 1 To UBound(n)
        next_ = Mid(text(y + n(i, 1)), x + n(i, 2), 1)
        wtb = wtb - (prev = "." And next_ <= "#")
        bn = bn - (i > 1 And next_ <= "#")
        If (i And 1) = 0 Then p2468 = p2468 & prev
        prev = next_
    Next i
    If step = 2 Then 
        p2468 = Mid(p2468, 3, 2) & Mid(p2468, 1, 2)
        
    End If
    Dim ret(2) As Variant
    ret(0) = wtb
    ret(1) = bn
    ret(2) = p2468
    AB = ret
End Function
 
Private Sub Zhang_Suen(text As Variant)
    Dim wtb As Integer
    Dim bn As Integer
    Dim changed As Boolean, changes As Boolean
    Dim p2468 As String     
    Dim x As Integer, y As Integer, step As Integer
    Do While True
        changed = False
        For step = 1 To 2
            changes = False
            For y = 1 To UBound(text) - 1
                For x = 2 To Len(text(y)) - 1
                    If Mid(text(y), x, 1) = "#" Then
                        ret = AB(text, y, x, step)
                        wtb = ret(0)
                        bn = ret(1)
                        p2468 = ret(2)
                        If wtb = 1 _
                            And bn >= 2 And bn <= 6 _
                            And InStr(1, Mid(p2468, 1, 3), ".") _
                            And InStr(1, Mid(p2468, 2, 3), ".") Then
                            changes = True
                            text(y) = Left(text(y), x - 1) & "!" & Right(text(y), Len(text(y)) - x)
                        End If
                    End If
                Next x
            Next y
            If changes Then
                For y = 1 To UBound(text) - 1
                    text(y) = Replace(text(y), "!", ".")
                Next y
                changed = True
            End If
        Next step
        If Not changed Then Exit Do
    Loop
    Debug.Print Join(text, vbCrLf)
End Sub

Public Sub main()
    init
    Dim Small_rc(9) As String
    Small_rc(0) = "................................"
    Small_rc(1) = ".#########.......########......."
    Small_rc(2) = ".###...####.....####..####......"
    Small_rc(3) = ".###....###.....###....###......"
    Small_rc(4) = ".###...####.....###............."
    Small_rc(5) = ".#########......###............."
    Small_rc(6) = ".###.####.......###....###......"
    Small_rc(7) = ".###..####..###.####..####.###.."
    Small_rc(8) = ".###...####.###..########..###.."
    Small_rc(9) = "................................"
    Zhang_Suen (Small_rc)
End Sub