본문 바로가기
코딩/OpenCV

[C++ opencv] 관심영역 Region of Interest (RoI) 사용 방법

by DIYver 2020. 7. 21.

본문 목표

영상처리에서 가장 중요한 것은 정확성과 처리속도라고 할 수 있다.

 

정확성을 높이기 위해서는 관찰하려는 대상에 초점이 맞춰져 있어야한다.

 

원하는 피사체(대상)를 따로 분리하여 영상처리를 하고 싶은 경우 사용하는 방법이 '관심영역 설정'이다.

 

영어로는 RoI(Region of Interest) 라고 부른다.

 

 

 

 

키워드 :  rect, RoI

 

 

 

 

 

알아볼 함수 원형

- 관심영역 ( Roi )

	Mat img = imread("Lenna.png", 1);

	Mat img_roi_1, img_roi_2;

	img_roi_1 = img(Rect(200, 200, 100, 100));
	img_roi_2 = img(Rect(Point(300, 200),Point( 400, 300)));

 

src( Rect( x, y, width, height)) )

 

  ○ src : 관심영역을 설정할 원본 이미지

 

  ○ Rect( x, y, width, height) ) : 관심영역을 설정할 사각형 정보, 좌표( x, y)를 시작으로 width 와 height 를 설정함

 

 

src( Rect( Point( x1, y1 ), Point( x2, y2) ) )

  ○ src : 관심영역을 설정할 원본 이미지

 

  ○ Rect( Point( x1, y1 ), Point( x2, y2) ) : 관심영역을 설정할 사각형 정보, 두 좌표를 지정하여 사각형 범위를 설정함

 

 

 

 

 

 

 

 

 

 

 

 

마우스로 지점을 선택하여 RoI 를 설정할 수 있지만,

 

가장 기초적인 방법을 설명하자면

 

직접 관심영역에 대한 좌표를 입력해줘야 한다.

 

쉽게 알 수 있는 방법은 그림판을 이용하는 것이다.

 

 

그림판에서 이미지를 불러온 후

 

자신이 관심영역을 지정할 사각형을 먼저 그려본다.

 

하얀색과 노란색으로 그렸으면,

 

좌상단 꼭지점의 좌표를 확인한다.

 

좌상단 꼭지점에 마우스를 올리고, 아래의 픽셀 정보를 확인한다.

 

 

그림판 아래 표시줄을 보면, 좌표를 확인할 수 있다.

 

현재 빨간색 포인터 위치의 좌표는 227, 228 이다.

 

 

 

이제 같은 방식으로 우하단의 꼭지점 좌표를 확인한다.

 

우하단 꼭지점의 좌표는 299, 293 임을 확인할 수 있다.

 

 

 

 

코딩을 할 때, 위에서 확인한 좌표를 그대로 입력해주면 된다.

 

오른쪽의 노란색 영역을 같은 방식으로 구하면

 

좌상단 좌표 : 307, 236

우하단 좌표 : 370, 295

 

임을 알 수 있다.

 

 

그림판을 이용하면 두 꼭지점을 이용한 RoI 설정이 쉽다.

 

하지만 width 와 height 로 해보자면

 

노란색 관심영역은 

기준 좌표가 (307, 236) 이 되고,

width 는 63, height 는 59 가 된다.

 

 

방금 구한 치수들을 코드에 입혀서 실행해보자.

 

 

 

 

 

 

 

 

 

코드 테스트 결과

- CODE

#include <opencv2/opencv.hpp>


using namespace cv;
using namespace std;

int main(int ac, char** av)
{
	Mat img = imread("Lenna.png", 1);

	Mat img_roi_1, img_roi_2;

	img_roi_1 = img(Rect(307, 236, 63, 59));
	img_roi_2 = img(Rect(Point(227, 228),Point( 299, 293)));

	imshow("img", img);
	imshow("img_roi_1", img_roi_1);
	imshow("img_roi_2", img_roi_2);
	waitKey(0);
	return 0;
}

 

- RESULT

왼쪽눈과 오른쪽 눈을 잘 검출한 것을 볼 수 있다.

 

그림판은 x, y 좌표계를 이용하므로,

 

환경이 좋지 않을 때, 기본프로그램으로 좌표를 쉽게 알 수 있게 해준다.

 

 

 

 

 

 

 

 

 

 

여기서 중요한게 있다.

 

Mat 는 주소값이라고 했다.

 

RoI 로 이미지를 새로 만든것이 아니라

 

원본 img 의 주소를 참조하고 있는 것이다.

 

위의 코드를 보기 쉽게 그림으로 표현하자면 다음과 같다.

컴퓨터 내의 메모리에서는 위와 같은 상황이다.

 

img 에만 이미지가 저장되어 있고,

 

나머지 img_roi_1 과 img_roi_2 에는 아직 값이 안 들어가 있다.

 

 

 

그다음 명령인 RoI 를 설정하는 부분이다.

 

OpenCV 에서는 항상 ' = ' 연산을 사용할 때 조심해야 한다.

 

RoI 에서도 마찬가지이다.

 

위의 코드를 보기 쉽게 그림으로 표현하자면

 

위와 같은 상황이 되는 것이다.

 

img_roi_1 의 메모리 값이 가리키고 있는 것은 

img 의 한 부분인 것이다.

 

따라서 img_roi_1 을 수정하게 된다면

원본인 img 의 해당 영역이 수정되게 되는 문제가 생기게 된다.

 

 

 

 

아래 코드에서 확인해 보면

#include <opencv2/opencv.hpp>


using namespace cv;
using namespace std;

int main(int ac, char** av)
{
	Mat img = imread("Lenna.png", 0);

	Mat img_roi_1, img_roi_2;

	img_roi_1 = img(Rect(307, 236, 63, 59));
	img_roi_2 = img(Rect(Point(227, 228),Point( 299, 293)));

	img_roi_1 = img_roi_1 - 80;

	imshow("img", img);
	imshow("img_roi_1", img_roi_1);
	imshow("img_roi_2", img_roi_2);
	waitKey(0);
	return 0;
}

 

RoI 영역은 위와 같이 출력되고,

 

원본 이미지는 아래와 같이 출력된다.

 

 

 

 

코드에서 딱히 원본 이미지를 건드린 적이 없다고 생각할 수 있겠으나,

 

RoI 로 따온 영역을 무심코 건드렸다가는 원본이미지가 위와같이 바뀔 수 있는 것이다.

 

 

 

 

 

OpenCV 가 발전함에 따라서 

컬러 원본이미지에 관심영역을 설정한 후

관심영역만 흑백 변환을 한 경우에는 원본에 영향을 미치지 않은 것으로 확인되었다.

애초에 이미지 색 채널이 달라서 연산이 불가능한 경우인데, 내부적으로 이미지를 복사하는 작업을 거치는 듯 하다.

 

 

 

 

결론.

 

이미지에서 관심영역을 설정하면 정확도를 높이고, 연산속도를 증가시킬 수 있다.

 

OpenCV 에서는 Rect 사각형 범위를 설정하여 RoI를 지정할 수 있다.

 

RoI 를 사용할 때에는 원본 이미지를 참조할 수 있으므로 조심해서 사용하여야 한다.

 

 

 

 

 

 

 

도움이 되었거나, 문제가 있는 경우 댓글로 알려주세요~!

감사의 댓글은 작성자에게 큰 힘이 됩니다 ^^

댓글