[OpenCV] 원하는 이미지 영역(관심영역, ROI) 자르기(Crop)

반응형

블로그 글을 쓰다보면 특정 영역만을 잘라서 저장하고 싶을 때가 있습니다. 윈도를 사용하다보면 윈도에서 제공하는 Windows 사진 뷰어 등의 프로그램을 이용해 원하는 이미지의 영역을 자를 수 있는데, Mac OS X나 Ubuntu에 있다보면 기본 프로그램으로 이런 것들을 제공하지 않다보니 쓸 프로그램을 찾게 되는 경우가 잦았는데요.

 

이렇게 원하는 이미지를 불러와서 간단하게 원하는 영역을 자를 수 있는 프로그램을 한 번 만들어보도록 하겠습니다.

 

 

 

MouseEvent

OpenCV에서 MouseEvent를 사용하기 위해서는 콜백 함수를 구현해야 합니다. 콜백 함수에 대해 잘 모르시겠다면 아래의 글을 참고해보세요.

 

2016.12.18 - [Programming/OpenCV] - OpenCV에서 Mouse Event를 사용해보자

 

OpenCV에서 Mouse Event를 사용해보자

저에게 맡겨진 3개의 프로젝트와 기말고사가 드디어 끝이났네요. 이런저런 일들이 많았지만 그렇다보니 블로그 포스팅에 대해 소홀해지게 되었는데요. 오늘은 지난 포스트에 이어서 OpenCV를 이

blog.neonkid.xyz

이를 토대로 우리는 원하는 영역을 자르는 코드를 구현해 볼 수 있습니다.

 

 

 

ROI (Region Of Interest)

이미지에서 원하는 영역을 Computer Vision에서는 관심 영역이라고 얘기합니다. 이를 ROI라고 표현하는데요. 컴퓨터 비전에서 관심 영역을 처리하기 위해서는 Rect, Point를 이용하여 이미지의 원본과 관찰하려는 대상을 따로 분리하여 영상 처리를 진행합니다.

 

본래 이미지가 srcImage입니다. 해당 이미지를 불러와서 roi라는 변수에 특정 위치에 특정 크기만큼 원하는 영역을 가져와 이미지 처리하는 기본 코드입니다.

 

실제로 가져와보면 이런 형태가 되는 것이죠. 원본 이미지가 왼쪽, 제가 원하는 부분은 이미지의 입쪽이라고 한다면 입쪽에 해당하는 것을 이렇게 잘라서 메모리로 가져오는 것입니다. 

 

이러한 방법을 일반적으로는 원하는 이미지 자르기, 컴퓨터 비전에서는 ROI, 관심 영역 가져오기 라고 이야기 합니다.

 

하지만 기본 코드로는 우리가 원하는 영역이 어디인지를 알 수가 없습니다. 따라서 마우스 이벤트를 이용해 우리가 원하는 관심 영역을 직접 드래그해서 짜르도록 하는 것이 이번 글의 목표입니다.

 

 

 

Develop

자 이제 요구 사항과 구현 원리를 알았으니 이제 구현에 들어가보도록 하겠습니다.

 

우리가 이미지 위에 마우스를 놓았을 때 어떤 영역을 드래깅하고 있는지를 보여주기 위해 별도의 img_draw 매트릭스가 필요합니다. 원본 이미지를 건드리면 나중에 복구가 되지 않기 때문에 드래깅하는 상태를 보여주는 matrix를 별도의 변수로 사용합니다.

 

  • EVENT_LBUTTONDOWN: 마우스 왼쪽 버튼을 누르고 있을 때.
  • EVENT_MOUSEMOVE: 마우스를 움직이고 있을 때.
  • EVENT_LBUTTONUP: 마우스 왼쪽 버튼을 뗐을 때.

 

우리가 사용할 마우스 이벤트는 3가지 입니다. 원하는 영역을 드래깅 하고 있을 이벤트를 감지하기 위한 LBUTTONDOWN과 MOUSEMOVE로 drag 중인지를 변수로 확인하고, drag 중이면 이 때부터 rectangle을 마우스 위치에서부터 그려나가도록 합니다.

 

마지막으로 마우스 버튼을 뗐을 때는 우리가 원하는 영역 선택을 마쳤으므로 마우스를 드래그하기 시작했던 부분부터 마지막 부분까지의 x, y 좌표와 width, height를 계산해 변수로 넣습니다. 

 

여기서 callback 함수의 x, y가 원본 이미지의 x, y이고, gx, gy가 드래그 하는 초기 시점부터의 x, y 좌표입니다.

 

이미지를 자른 영역이 roi 변수에 저장되었으면 원하는 파일 이름으로 저장될 수 있도록 imwrite 함수에 이미지 파일 이름을 넣습니다.

 

그러면 제가 원하는 로봇의 입 부분만 드래그를 했을 때 저렇게 오른쪽에서 입 부분만 잘라진 것을 볼 수 있습니다.

 

 

 

마치며...

이미지를 Crop하는 것이 간단한 일임에도 불구하고 항상 쓸만한 프로그램을 찾다보면 시간이 지나가기 마련이라 간단하게 구현해볼 수는 없을까 하다 다시 OpenCV로 오게 되었습니다.

 

C++가 어렵다면 Python으로도 구현해볼 수 있으니 Python으로 구현해보고 싶다면 C++ 코드를 참고해서 구현해보시는 것도 좋을 것 같습니다.

 

 

반응형

Tistory Comments 0