Mask R CNN Mask 영역 활용하기 - DBChoi85/Hanja_DKU GitHub Wiki
(Git_hub : https://github.com/matterport/Mask_RCNN.git 참고)
위 git에서 mask rcnn 결과물 출력을 담당하는 부분은 mrcnn폴더의 visualize.py 이다. visualize.py 파일에서 display_instances메소드가 출력시 이미지에 mask영역과 bbox영역을 설정해 주는 역할을 한다. 우리가 얻고자하는 출력결과는 bbox영역으로 이미지를 crop하면서 bbox 내에 있는 필요없는 부분(bbox영역 내 다른 이미지가 겹쳐서 출력된 부분) 은 출력되지 않게 하는 것이다. 이미 메소드의 매게변수로 bbox영역과 mask영역을 받기 때문에 이 결과물을 내는 것은 생각보다 간단하다.
1. bbox 영역으로 출력하기
이미 함수안에 bbox영역을 좌표로 받는 부분이 존재한다. ( y1, x1, y2, x2 = boxes[i]) 여기서 함정은 우리가 생각하는 x와 y를 바꿔서 (x -> y , y -> x) 받았다는 점이다. 때문에
copy = image
crop_im = copy[y1:y2, x1:x2,:].copy()
이런식으로 y변수를 행으로 두고 x변수를 열로 둬서 crop을 실시하였다. 또한 원본 이미지를 copy로 받아야지만 수정시 원본이미지를 보존할 수 있음을 주의하여야 한다.(필자는 이 부분을 간과하여 굉장히 고생하였다.) boxes: [num_instance, (y1, x1, y2, x2, class_id)] 형태를 하기 때문에 num_instance를 for문으로 받아서 반복해주면 그 이미지에 해당하는 bbox영역을 모두 crop하여 출력하는 것이 가능하다.(num_instance은 그 이미지 내에 존재하는 bbox에 번호를 메긴것이다.)
2. mask 영역을 받아 외부 영역 지우기
1번 과정을 수행했다면 2번 과정은 순조롭게 진행이 가능할 것이다. mask영역은 [height, width, num_instances] 형태로 메게변수 취급을 받아 메소드로 들어온다. 마찬가지로 num_instances은 그 이미지의 영역번호에 해당하므로 위 과정에서 for문을 받을때 같이 들어가 주면 된다. mask메게변수 또한 그 이미지 전체에 해당하는 부분이기 떄문에 같은 영역으로 crop을 실시해준다.
copy_mask = masks
crop_ma = copy_mask[y1:y2, x1:x2,i].copy()
이후 임의로 만든 def apply_mask_white(image, mask)에 crop한 두 영역을 인수로 넣어주면 된다.
def apply_mask_white(image, mask):
ima = image
for c in range(3):
ima[:, :, c] = np.where(mask == 0, 255, ima[:, :, c])
return ima
위 메소드는 mask영역에서 0에 해당하는 부분을 이미지에서 흰배경으로 처리하고 아닌 부분은 이미지 그대로 받겠다는 메소드이다. mask는 false(=0)과 true(=1)로 이루어져있으며 mask rcnn을 거쳐 물체가 있는 부분은 1로 아닌 부분을 0으로 출력해준다.
따라서 이 과정을 거치게 되면 원본 이미지에서 해당하는 물체를 노이즈 없이 출력하는 것이 가능해 진다.