안녕하세요, Justin4AI입니다.
저번 포스트 이후로 놀고 stat만 좀 공부하느라 DL에 관해서 딱히 글을 쓸 거리가 없었는데, 재밌는 주제 (개인적인 ㅎㅎ)가 생겨서 다뤄보게 됐습니다.
요즘 computer vision 분야에서도 object detection이 굉장히 인기인데요, 특히나 의료쪽이나 바이오쪽 도메인이 있으신 분들은 EMA image를 자주 다루시곤 합니다.
그러나 정제되지 않은 데이터, 특히 image 데이터에서 항상 문제가 되는 놈이 바로 'noise'인데요, 깔끔한 segmentation의 가장 큰 방해요소 중 하나입니다.
※이 글의 메인은 SOLUTION 2 파트니 참고해주세요!
한 달 정도 전에 받은 질문입니다. 질문자님께서 폐 image를 segmentation을 했는데, 사진에서 보시다시피 중간에 noise가 많이 끼어있죠.
이걸 매끈하게 만들어야 하는데, 고급 기술을 알려드리기보단 쉬운 방법으로 해결할 순 없을까 저도 고민해봤습니다.
당시에 제가 드렸던 답변은 기본 dilation과 erosion 연산 순서로 결합한 morphology (python opencv에선 morphologyEX() function)을 여러번 반복하는 것이었습니다. 대화 내용에서는 마치 제가 dilation을 n번, erosion을 m번 반복하라고 말씀드린 것처럼 나오긴 했지만요 ㅠㅠ
결론적으로 morphologyEX (closing 연산) 12회 뒤 erode 10회 추가 진행해서 어느정도 object 손상 없이 noise 제거가 되었습니다.
당시에는 제가 아는 방법 내에선 가장 간단하고 괜찮았기 때문에 만족했었죠.
그런데 오늘, 같은 질문을 CV방에서 받았습니다.
당연히 저는 지난번과 같은 답변을 드렸구요,, ㅎㅎ
감사인사 받으니 도움이 됐다는 생각에 기분 좋게 하던 일 하러 가려 했습니다,,
그! 런! 데!
무려 object의 손상이 없이, noise elimination이 가능하다는 바다로가요님의 답변이었습니다. (여기서 정말 많이 놀랐고, "역시 아직 멀었구나" 이 생각이 또 들었습니다 ㅋㅋㅋ)
(denseCRF는 저도 처음 들어봐서, 다음에 공부해봐야겠네요.)
자세히 어떤 방식인가 보면,
제가 최대한 더 쉽게 풀어보겠습니다.
위와 같은 예시 이미지가 있습니다.
좌측부터 순서대로 '원본 이미지', '마스킹 이미지', '결과 이미지'입니다.
'마스킹 이미지'는 '원본 이미지'에 morphology 연산을 적용하여 (closing이나 단순 erosion) 만든 것으로, 실제로는 예시보다 객체가 손상되어 있겠죠.
이런 식으로 실제론 (위 예시와 달리) 외곽부분의 손상이 있을 것입니다.
여기서 제가 들었던 의문이 바로,
"마스킹 이미지의 외곽이 손상된다면, 객체가 보존될 순 없지 않나?"
입니다.
왜냐하면 저는 원본과 마스킹 이미지간의 AND 비트연산(대화 중에는 OR이라고 잘못 썼네요), 즉 intersection을 결과값으로 가지는 방식이라고 잘못 이해했기 때문입니다.
-빛-이신 바다로가요님께서 다행히 이렇게 정정해주셨답니다.
키포인트는 화소당 계산이 아닌 'contour를 잡아서 area 단위로 선택'한다는 점입니다! 자세히 풀어보면요,
이러한 원본 이미지가 있었죠.
이렇게 실제로는 객체도 함께 깎여버린 마스킹 이미지가 있었구요.
여기서 두 이미지간 교집합을 결과로 내지 않고, 원본 이미지의 contour를 따게 됩니다.
제가 빨간 선으로 두른게 object의 contour가 되겠죠? (노트북 마우스라,,ㅎㅎ) contour가 있는 원본 이미지와, 마스킹 이미지 (편의상 파란색으로 색칠)를 겹쳐두면 위와 같이 되겠죠.
contour로 둘러싸인 부분은 화소단위가 아닌 '영역' 단위이기 때문에,
마스킹 이미지 (파란색)가 포함된 영역 (빨간색)만 가져오면 되는 것입니다.
그럼 이렇게 contour로 둘러싸였던 영역만 가져올 수 있게 됩니다.
Without 객체의 손실!
++
사실 저도 그렇고 여러분도 아시듯, 학습 데이터에서 객체가 약간 손실된다고 해서 결과를 내는 데에 크게 무리가 생기진 않습니다. 그러나 확실히 손실이 치명적인 task에서는, 굉장히 효과적인 방법이 될 것 같습니다.
굳이 단점을 꼽자면,, contour의 임계값을 정해줘야 한다는 것? 정도가 되겠네요.
1년 동안 대학생으로 살면서 나름 치열하게 알아보고, 혼자 이리저리 굴러봤다고 생각했지만 역시 한참 멀었다는 생각밖에 안드네요...
근데 사실 이렇게 제 부족함이 드러날 때마다 너무 기분이 좋습니다. 덕분에 한층 발전할 수 있고, 자연스럽게 겸손해지는 것 같아요 - 겸손한 실력이라 그렇지만요.
작년 9월까지, 맨날 놀고 술만 마시던 인생을 카톡 오픈채팅방 하나로 끝내고 이렇게 바뀌게 될 줄 몰랐습니다.
여러분께 제 글도 미약하나마 자극제가 되길 바라면서, 글 마치겠습니다!
다음 포스팅때 찾아뵐게요 :)
(재밌는 고민거리 던져주신 gaaaaann과 틱택님, 너무 멋진 해결법 알려주신 바다로가요님 정말 감사합니다!)