Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rotation-Invariant Features #12

Open
Jinu-Lee opened this issue Jul 16, 2020 · 5 comments
Open

Rotation-Invariant Features #12

Jinu-Lee opened this issue Jul 16, 2020 · 5 comments
Labels
Features Features to be used for classification 구현완료

Comments

@Jinu-Lee
Copy link
Collaborator

Jinu-Lee commented Jul 16, 2020

Wafer Map Defect Pattern Recognition Using Rotation-Invariant Features - Rui Wang and Nan Chen
원본 / 요약본

1

Rotation-Invariant Feature: 회전해도 변하지 않는 Feature

@Jinu-Lee Jinu-Lee changed the title Rotation-Invariant Features - Line Masks Rotation-Invariant Features Jul 16, 2020
@dotoleeoak dotoleeoak reopened this Jul 17, 2020
@Jinu-Lee Jinu-Lee added Features Features to be used for classification and removed Features Features to be used for classification labels Jul 20, 2020
@dotoleeoak dotoleeoak added the Features Features to be used for classification label Jul 20, 2020
@Jinu-Lee
Copy link
Collaborator Author

Jinu-Lee commented Jul 20, 2020

  1. Polar Mask
def polar_mask(N_a, N_c, size=32):
    A = [[2 ** N_a - 1], [(1 << (N_a // 2)) - 1], []]
    C = [[] for i in range(N_c)]

    bit_mask = 2 ** N_a - 1
    #a_1,*
    for i in range(1, N_a):
        if i == N_a // 2:
            continue
        A[0].append((A[0][0] << i) & bit_mask)
    
    #a_2,*
    for i in range(1, N_a // 2):
        A[1].append((A[1][0] ^ (A[1][0] << i)) & bit_mask)

    A = [list(map(lambda x: list(map(int, bin(x)[2:].zfill(N_a))), arr)) for arr in A]
    
    #a_3,*
    A[2] = [list(map(lambda x: 2 * x - 1, arr)) for arr in A[1]]

    #c
    for i in range(N_c):
        C[i].append(2 ** (i + 1) - 1)
        for j in range(1, N_c - i):
            C[i].append(C[i][0] << j)

    C = [list(map(lambda x: list(map(int, bin(x)[2:].zfill(N_c))), arr)) for arr in C]
    
    #flatten
    A = [a for arr in A for a in arr]
    C = [c for arr in C for c in arr]

    weight_matrix = np.array([np.matmul(np.array([a]).T, np.array([c])) for a in A for c in C])

    #make mask
    R = size // 2
    rad = np.linspace(0, R, num=N_c, endpoint=False)
    angle = np.linspace(0, 2*np.pi, num=N_a, endpoint=False)
    dist = lambda y, x: np.sqrt((x - R) ** 2 + (y - R) ** 2)

    mask = np.zeros((size, size))    
    for i in range(size):
        for j in range(size):
            d = dist(i, j)
            if d > R:
                continue

            theta = np.arctan2(R - i, j - R)
            if theta < 0:
                theta += 2 * np.pi

            mask[i][j] = np.argmax(angle[angle <= theta]) * N_c + np.argmax(rad[rad <= d]) + 1
    
    #apply weight on mask
    masks = []
    for weight in weight_matrix:
        weighted_mask = mask.copy()
        for i in range(N_a):
            for j in range(N_c):
                weighted_mask[weighted_mask == (N_c * i + j + 1)] = weight[i][j]
        masks.append(weighted_mask)
    
    return masks

논문에 나와있는 예시인 N_a=4, N_c=3를 넣으면 아래와 같은 Master Mask가 나온다.
1

논문에서 실제 사용한 값인 N_a=4, N_c=5, N_t=16을 이용해 추출
-> 추출되는 개수는 (2*N_a-1)(1+N_c)(N_c)/2=105
polar_mask.zip

@Jinu-Lee
Copy link
Collaborator Author

Jinu-Lee commented Jul 21, 2020

(3개의 feature 공통)
하나의 master mask에서 feature 추출하기
-> 여러 각도로 돌린 결과 중 최댓값

img -> 변형 필요

img[img != 2] = 0
img[img == 2] = 1
def extract_features(img, mask, N_t, size=32):
    result = []
    for angle in np.linspace(0, 360, num=N_t, endpoint=False):
        rotation_matrix = cv2.getRotationMatrix2D((size / 2, size / 2), angle, 1)
        rotated_mask = cv2.warpAffine(mask, rotation_matrix, (size, size))

        masked_img = img * rotated_mask
        result.append(masked_img.sum(dtype=np.int32))

    return max(result)

@Jinu-Lee
Copy link
Collaborator Author

Jinu-Lee commented Jul 21, 2020

  1. Line Mask
def line_mask(N_l, size=32):
    R = size // 2
    dist = lambda y, x: np.sqrt((x - R) ** 2 + (y - R) ** 2)
    rad = np.linspace(0, R, num=N_l, endpoint=False)

    mask = np.zeros((size, size))
    for i in range(size):
        for j in range(size):
            d = dist(i, j)
            if d > R:
                continue

            theta = np.arctan2(R - i, j - R)
            if -np.pi / 2 <= theta <= np.pi / 2:
                mask[i][j] = np.argmax(rad[rad <= (j - R)]) + 1

    masks = []
    for i in range(1, N_l + 1):
        weighted_mask = mask.copy()
        weighted_mask[weighted_mask != i] = 0
        weighted_mask[weighted_mask == i] = 1
        masks.append(weighted_mask)

    return masks

논문에 사용된 N_l=7
2
line_mask.zip

@Jinu-Lee
Copy link
Collaborator Author

Jinu-Lee commented Jul 22, 2020

  1. Arc Mask
def arc_mask(N_r, R_l, R_h, N_o, R_c, size=32):   
    R_l, R_h, R_c = [(size / 2) * i for i in (R_l, R_h, R_c)]

    dist = lambda y, x, c: np.sqrt((x - c - size / 2) ** 2 + (y - size / 2) ** 2)
    
    rad = np.linspace(R_l, R_h, num=N_r, endpoint=False)
    center = np.linspace(R_c, 0, num=N_o, endpoint=False)

    masks = []
    for c in center:
        mask = np.zeros((size, size))

        for i in range(size):
            for j in range(size):
                d = dist(i, j, c)
                if d < R_l or d > R_h:
                    continue
                
                mask[i][j] = np.argmax(rad[rad <= d]) + 1

        for i in range(1, N_r + 1):
            weighted_mask = mask.copy()
            weighted_mask[weighted_mask != i] = 0
            weighted_mask[weighted_mask == i] = 1
            masks.append(weighted_mask)

    return masks

논문에 나온대로 N_o=12, N_r=6, R_c=1.2R, R_l=0.5R, R_h=R
주석 2020-07-17 162952
arc_mask.zip

@Jinu-Lee
Copy link
Collaborator Author

D: Density / G: Geometry / R: Radon
P: Polar / L: Line / A: Arc

image

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Features Features to be used for classification 구현완료
Projects
None yet
Development

No branches or pull requests

2 participants