[로봇센서데이터처리] Image Transform 과 Black Hole 문제 해결

·2022년 3월 28일

1. Forward Warping 을 이용했을 때

image transform 이란 원본 이미지를 회전, 이동, 확대, 축소 하여 변환 이미지를 만드는 과정을 의미하며,

특히 Forward warping 이란 픽셀값(0~255) 또는 픽셀 좌표값 (x,y) 하나하나를 변환하여 새로운 이미지에 붙여주는 과정을 의미한다. 가령 코드는 다음과 같다.

for y in range(h):
    for x in range(w):
        new_x = np.int(np.cos(theta) * (x-ww) - np.sin(theta) * (y-hh))+ww
        new_y = np.int(np.sin(theta) * (x-ww) + np.cos(theta) * (y-hh))+hh
        # 변환 행렬 계산 수행
        if new_x < 0 or new_x >= w or new_y < 0 or new_y >= h:
            continue
        new_gray[new_y, new_x] = gray[y, x]

그런데 단순히 Forwad warping 을 적용하게 되면, 이미지를 확대 / 축소 할 때, 이미지를 rotation 할 때 Black Hole 문제가 생기게 된다. 이는 다음과 같은 이유 때문이다.

  • point rich 한 이미지(= 원본 이미지, 모든 픽셀 좌표에 픽셀값이 존재하는 이미지를 의미함)
    (x, y) 픽셀값 가져옴

  • (x, y)에 변환행렬 적용해서 (new_x, new_y) 구함

  • x,y 로 부터 new_x, new_y 를 계산후에 int 타입으로 변환하는 과정이 수반

  • 완벽하게 1:1로 매칭되는 값이 new_x, new_y 존재한다는 보장이 없음.

  • 같은 픽셀 좌표가 구해지는 존재하는 경우 완벽하게 메꾸는 것이 불가능

예를 들어 원본 포인트가 P1(0,0)P_1 (0, 0) 인 지점을 roatation 변환했더니 P1(1.3,2.5)P_1' (1.3, 2.5) 였고, P2(1,2)P_2(1,2) 인 점을 rotation 변환했더니 P2(1.4,2.7)P_2'(1.4, 2.7) 이었다 가정하자. P1,P2P_1', P_2' 모두 int 로 변환시 (1,2)(1, 2) 로 변환된다. 즉 원본 이미지와 1:1 매칭이 되지 않는 지점이 생긴다는 것이다.

2. BackWard Warping

BackWard Warping 은 반대로 변환된 이미지를 원본 이미지라고 생각하고, 원본이미지를 변환 이미지라고 생각한다. 그래서 변환 이미지의 픽셀 하나하나에 원래의 변환 행렬의 역 행렬을 곱해, 그 값이 원본이미지에 대응하는 값이라고 처리해준다. 가령 아래와 같은 방식이다.

def rotation(self, img, r):
        ''' code here '''

        src = img
        img_h, img_w, img_channel = src.shape
        center_h, center_w = np.int(img_h/ 2), np.int(img_w/2)
        img_result = np.zeros((img_h, img_w, img_channel), src.dtype)

        theta = - r * np.pi /180.0 # 내가 회전 시키고자 하는 각도는, 반시계방향일 경우 (-) 로, 시계방향일 경우 (+) 로 받아와야 합니다.

        for y in range(img_h):
            for x in range(img_w):
                new_x = int((np.cos(theta) * (x - center_w) + np.sin(theta) * (y - center_h) ) + center_w)
                new_y = int((-np.sin(theta) * (x - center_w) + np.cos(theta) * (y - center_h)) + center_h) 
                # backward 로 계산하기 위해, 회전된 이미지를 원본으로, 원본 이미지를 변환 이미지로 생각했습니다.
                # 회전된 이미지로 부터 로테이션 매트릭스의 역행렬을 곱해 new_x, new_y 라는 원본 이미지 상의 대응 되는 좌표를 찾습니다.
                # 원본이미지는 모든 픽셀 좌표에서 rgb 값을 가지고 있기 때문에, 어떤 new_x, new_y 좌표에서든지 색상 정보를 가져올 수 있습니다. 
                # 그래서 검은색 홀이 생기지 않게 될 것입니다. 
                if new_x < 0 or new_x >= img_w or new_y < 0 or new_y >= img_h:
                    continue
                img_result[y,x] = src[new_y, new_x]
        
        return img_result

profile
._.

0개의 댓글