이미지에서 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;
}
}