본문 바로가기

카테고리 없음

OpenCV C++ 이미지 ROI 영역에서 포인터 접근

이미지에서 ROI에만 포인터를 접근할 때, 주의해야할 것이 있다.

 

보통 실무자들이 선호하고 자주 쓰는 것은 image.data인데, image.data로 접근해서 수정하면 이상하게 나올 때가 있을 것이다. 그건 단순히 이 중 포문으로 접근하면 1차 배열이기 때문에 roi가 아닌 roi 영역 밖으로 포인터가 나가기 때문.

for문 조건을 달던지 해서 .data로 처리할 순 있겠지만 그냥 간단하게 알려주겠다.

 

우리는 보통 3가지 방법으로

1. at

2. ptr

3. data

를 통해 포인터 접근을 할 수 있다.

 

영상처리에서 포인터 없이 이미지에 접근하면 속도가 넘 차이 나는 데, 여기서도 속도 순서는 data>ptr>at 이다.

 

핵심만 말하겠다.

평소처럼 2중 for문 사용해서 image에서 roi 영역에 올바르게 접근하고 싶다면 ptr을 사용하는 게 편하다. (내 기준)

.data 방식으로 for문을 돌리면, 알고리즘으로 어찌어찌 해결할 순 있겠지만 좀 더 복잡할 것이다.

data로 구현할 수 있으면 하돼 여기서는 ptr로 올바르게 접근할 수 있도록 알려준다.

 

**

data로 하려면 이중포문 아주 잘짤것. 속도가 좀 느리지만 저는 ptr 사용중.

data + parrel_for 가 속도 제일 빠른 걸로 알고 있습니다

 

코드 첨부

#include <opencv2/opencv.hpp>
// When 3 channel image

using cv;

Mat image = imread("pathToBgrImage.png");

uchar * pointer = (uchar*)image.data;

Rect roi(0,0,100,100); // anonymous roi for example

// i will fill roi region to white
for (int y = 0; y < roi.height ; y++){
	Vec3b* imageRoiRows = image(roi).ptr<Vec3b>(y);
    for (int x = 0; x < roi.width; x ++){
    	imageRoiRows[x][0] = 255;
        imageRoiRows[x][1] = 255;
        imageRoiRows[x][2] = 255;        
    }
}



-------------------------------------


// When 1 channel image
#include <opencv2/opencv.hpp>
using cv;

Mat gray = imread("pathToBgrImage.png",IMREAD_GRAY); // 되도록 0 말고 습관적으로 변수 된 것을 사용할 것

uchar * pointer = (uchar*)image.data;

Rect roi(0,0,100,100); // anonymous roi for example

// i will fill roi region to white
for (int y = 0; y < roi.height ; y++){
	Vec3b* imageRoiRows = image(roi).ptr<Vec3b>(y);
    for (int x = 0; x < roi.width; x ++){
    	imageRoiRows[x] = 255;
    }
}