圖形相似在模式識別中的應用及python實現

Reference

算法流程圖

注意:基本原理方法在文章中有詳細介紹

使用該文章的方法,實現一個圖形相似度的計算,完成模式識別

import numpy as np


class Cycle(object):
    def __init__(self, N, E, S):
        self.N = N  # 元素數量
        # [['類型', '連接方式', '尺寸約束'], ['類型', '連接方式', '尺寸約束'], ['類型', '連接方式', '尺寸約束']...]
        self.E = E
        self.S = S  # 對稱性

    def __str__(self):
        return 'N={}\nE={}\nS={}\n'.format(self.N, self.E, self.S)

    __repr__ = __str__


# 幾何元素類型的相似係數
def type_coeff(o1, o2):
    if o1 == o2:
        return 1
    return 0.25


# 幾何元素的連接方式的相似係數
def method_coeff(o1, o2):
    if o1 == o2:
        return 1
    if o1 in (0,6) and o2 in (0,6):
        return 0.75
    if o1 in (0,6) and o2 in (1,2,5) or o2 in (0,6) and o1 in (1,2,5):
        return 0.5
    return 0
    # if o1 in [0,1,2,6] and o2 in [3,4] or o2 in [0,1,2,6] and o1 in [3,4]:
    #     return 0
    # return 0


# a = method_coeff(1, 1)
# print(a)

# 幾何元素的尺寸約束狀況的相似係數
def size_coeff(o1, o2):
    if o1 == o2:
        return 1
    if o1 in (2,3) and o2 in (2,3):
        return 0.75
    return 0
    # if o1 in (2,3) and o2 in (1,4,5) or o2 in (2,3) and o1 in (1,4,5):
    #     return 0


# 對稱性的相似係數
def symmtry_coeff(o1, o2):
    if o1 == o2:
        return 1
    return 0


def calculate_Qt(ca, cb):
    N = ca.N
    qt = 0
    for i in range(N):
        o1_type = ca.E[i][0]  # C1元素類型
        o2_type = cb.E[i][0]  #
        o1_state = ca.E[(i+1) % N][0]  # C1連接狀態
        o2_state = cb.E[(i+1) % N][0]
        qt += type_coeff(o1_type, o2_type) + type_coeff(o1_state, o2_state)
    # gt /= (2*N)
    return qt/(2*N)


def calculate_Qg(ca, cb):
    N = ca.N
    qg = 0
    for i in range(N):
        o1_type = ca.E[i][0]  # C1元素類型
        o2_type = cb.E[i][0]  #
        o1_state = ca.E[(i + 1) % N][0]  # C1連接狀態
        o2_state = cb.E[(i + 1) % N][0]
        o1_method = ca.E[i][1]  # C3連接方式
        o2_method = cb.E[i][1]  #
        qg += type_coeff(o1_type, o2_type) + type_coeff(o1_state, o2_state) + method_coeff(o1_method, o2_method)
    o1_sym = ca.S  # C4對稱性
    o2_sym = cb.S
    qg += symmtry_coeff(o1_sym, o2_sym)
    return qg / (3 * N + 1)


def calculate_Qd(ca, cb):
    N = ca.N
    qd = 0
    for i in range(N):
        o1_type = ca.E[i][0]  # C1元素類型
        o2_type = cb.E[i][0]  #
        o1_state = ca.E[(i + 1) % N][0]  # C1連接狀態
        o2_state = cb.E[(i + 1) % N][0]
        o1_method = ca.E[i][1]  # C3連接方式
        o2_method = cb.E[i][1]  #
        o1_size = ca.E[i][2]  # C5尺寸約束
        o2_size = cb.E[i][2]
        qd += type_coeff(o1_type, o2_type) + type_coeff(o1_state, o2_state) \
              + method_coeff(o1_method, o2_method) + size_coeff(o1_size, o2_size)
    o1_sym = ca.S  # C4對稱性
    o2_sym = cb.S
    qd += symmtry_coeff(o1_sym, o2_sym)
    return qd / (4 * N + 1)


def core(graph, re_graph):
    # -1 代表確定性相似  -2 表示模糊性相似 -3 表示完成不相似
    graph_similar = []
    jude_similar = []
    for i in range(len(graph)):  # 檢查圖的每一個環
        s = ''
        qt = 0
        qg = 0
        qd = 0
        qt = calculate_Qt(graph[i], re_graph[i])
        if qt == 1:
            qg = calculate_Qg(graph[i], re_graph[i])
            if qg == 1:
                qd = calculate_Qd(graph[i], re_graph[i])
                # t = qd
                if qd == 1:
                    s = '確定性相似'
                elif qd == 0:
                    s = '完全不相似'
                else:
                    s = '模糊性相似'
            elif qg == 0:
                s = '完全不相似'
            else:
                s = '模糊性相似'
        elif qt == 0:
            s = '完全不相似'
        else:
            s = '模糊性相似'
        similar = qt + qg + qd
        graph_similar.append(similar)
        jude_similar.append(s)
    return graph_similar, jude_similar


"""
元素類型:
    直線:0
    圓弧:1
    圓:2
    樣條曲線:3
鄰接狀態:

連接方式:
    垂直連接:0
    銳連接:1
    鈍連接A:2
    鈍連接B:3
    相切連接:4
    相割連接:5
    其它連接:6
尺寸約束狀況:
    無尺寸約束:0
    線性尺寸:1
    直徑類尺寸:2
    半徑類尺寸:3
    球徑類尺寸:4
    螺紋類尺寸:5
對稱性:
    不對稱:0
    對稱:1

"""
if __name__ == '__main__':
    c1 = Cycle(4, [[1, 4, 0], [0, 1, 0], [0, 1, 0], [0, 4, 0]], 1)
    c2 = Cycle(1, [[2, -1, 4]], 1)
    c3 = Cycle(4, [[1, 5, 0], [0, 0, 0], [0, 1, 0], [0, 5, 0]], 0)
    c4 = Cycle(4, [[1, 5, 0], [0, 1, 0], [0, 0, 0], [0, 5, 0]], 0)
    Graph = [c1, c2, c3, c4]

    c1 = Cycle(4, [[1, 4, 0], [0, 1, 0], [0, 1, 0], [0, 4, 0]], 1)
    c2 = Cycle(1, [[2, -1, 4]], 1)
    c3 = Cycle(4, [[1, 5, 0], [0, 0, 0], [0, 1, 0], [0, 5, 0]], 0)
    c4 = Cycle(4, [[1, 5, 0], [0, 1, 0], [0, 0, 0], [0, 5, 0]], 0)
    Graph_re0 = [c1, c2, c3, c4]

    c1 = Cycle(4, [[1, 4, 0], [0, 1, 1], [0, 1, 1], [0, 4, 1]], 0)
    c2 = Cycle(1, [[2, -1, 3]], 1)
    c3 = Cycle(4, [[1, 5, 0], [0, 0, 1], [0, 1, 1], [0, 5, 1]], 0)
    c4 = Cycle(4, [[1, 5, 0], [0, 1, 1], [0, 0, 1], [0, 5, 1]], 0)
    Graph_re1 = [c1, c2, c3, c4]

    c1 = Cycle(4, [[1, 4, 0], [0, 1, 0], [0, 1, 0], [0, 4, 0]], 1)
    c2 = Cycle(1, [[2, -1, 4]], 1)
    c3 = Cycle(4, [[1, 5, 0], [0, 0, 0], [0, 1, 0], [0, 5, 0]], 0)
    c4 = Cycle(4, [[1, 5, 0], [0, 1, 0], [0, 0, 0], [0, 5, 0]], 0)
    Graph_re2 = [c1, c2, c3, c4]

    c1 = Cycle(4, [[1, 4, 0], [0, 1, 0], [0, 1, 0], [0, 4, 0]], 1)
    c2 = Cycle(1, [[2, -1, 2]], 1)
    c3 = Cycle(4, [[1, 5, 0], [1, 0, 0], [0, 1, 0], [0, 5, 0]], 0)
    c4 = Cycle(4, [[1, 5, 0], [2, 1, 0], [0, 0, 0], [0, 5, 0]], 0)
    Graph_re3 = [c1, c2, c3, c4]

    c1 = Cycle(4, [[1, 4, 0], [0, 1, 1], [0, 1, 1], [0, 4, 1]], 0)
    c2 = Cycle(1, [[2, -1, 3]], 1)
    c3 = Cycle(4, [[1, 5, 0], [0, 0, 0], [2, 1, 0], [0, 5, 0]], 0)
    c4 = Cycle(4, [[1, 5, 0], [0, 1, 0], [1, 0, 0], [0, 5, 0]], 0)
    Graph_re4 = [c1, c2, c3, c4]

    # Graph_list = [Graph_re0, Graph_re1, Graph_re2, Graph_re3, Graph_re4]

    graph_similar, jude_similar = core(Graph,Graph_re0)
    print(graph_similar)
    print(jude_similar)

與Graph_re0識別(每條弧的相似性):

與Graph_re1識別(每條弧的相似性):

與Graph_re2識別(每條弧的相似性):

與Graph_re3識別(每條弧的相似性):

與Graph_re4識別(每條弧的相似性):

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章