본문 목표
영상처리에서 가장 중요한 것은 정확성과 처리속도라고 할 수 있다.
정확성을 높이기 위해서는 관찰하려는 대상에 초점이 맞춰져 있어야한다.
원하는 피사체(대상)를 따로 분리하여 영상처리를 하고 싶은 경우 사용하는 방법이 '관심영역 설정'이다.
영어로는 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 를 사용할 때에는 원본 이미지를 참조할 수 있으므로 조심해서 사용하여야 한다.
도움이 되었거나, 문제가 있는 경우 댓글로 알려주세요~!
감사의 댓글은 작성자에게 큰 힘이 됩니다 ^^
'코딩 > OpenCV' 카테고리의 다른 글
[C++ opencv] 이미지의 pixel 데이터 접근하기, 색상 정보 확인하기 (7) | 2020.07.28 |
---|---|
[C++ opencv] HSV 색상 검출하기 (7) | 2020.07.27 |
[C++ opencv] 이미지에 원 그리기, circle( ) (0) | 2020.07.21 |
[C++ opencv] 이미지에 사각형 그리기, rectangle( ) (0) | 2020.07.21 |
[C++ opencv] 이미지에 선, 직선 그리기 (0) | 2020.07.21 |
댓글