[OpenCV] iteration에 대한 고찰

유경박·2023년 12월 5일
0
post-thumbnail

-OpenCV 복습하던 중 Iteration에 대한 흥미로운 사실을 발견하고, 차후 내가 알아보기 위해 기록을 남김

c++ 기반 OpenCV를 복습하고 있는데 Mat의 원소를 얻는 연산중 접근할수 있는 방법은 3가지 정도가 있다.

*m1,m2,m3 변수는 32비트 float형 3채널 데이터 타입이며 10000x10000크기로 모두동일 하다

1) MatIterator를 이용한 접근
OpenCV Mat클래스 또한 STL 형식의 Iterator를 지원하며 STL의 Vector와 같이 컨테이너의 반복자를 이용하여 접근 및 할당하는 방식이다.

for (MatIterator_<Vec3f> it = m1.begin<Vec3f>(); it != m1.end<Vec3f>(); ++it) {
    (*it)[0] *= 0.3f;
    (*it)[1] *= 0.5f;
    (*it)[2] *= 0.6f;
}

2) for문을 이용한 접근
제일 많이 쓰이고 예제에서도 많이 보이는 접근 방식으로 Mat.at(i,j) = T형식으로 데이터를 접근하는 방법이다.

for (int i = 0; i < m2.rows; i++) {
    for (int j = 0; j < m2.cols; j++) {
        m2.at<Vec3f>(i, j) = Vec3f(0.3f, 0.5f, 0.6f);
    }
}  

3) forEach를 이용한 접근
opencv 3.0버전 이상부터 사용 가능한 함수로써, 람다형식의 파라미터를 전달받고 처리를 한다.

m3.forEach<Vec3f>([](Vec3f &pixel, const int  position[]) -> void {
    pixel = Vec3f(0.3f, 0.5f, 0.6f);
});

그렇다면, 대용량의 이미지를 처리한다고 했을때 1,2,3번의 항목 중 어느것이 제일 빠를까?

결론부터 말하자면
forEach >>> .at >>> iterator 순으로 빠르며 결과는 다음과 같다.

Elapsed time for iterator: 3.68594 seconds
Elapsed time for at function: 0.691739 seconds
Elapsed time for forEach function: 0.197883 seconds

이와 같이 결과가 나온 원인에 대해 찾아보던 중 Performance에 대한 내용은 공식문서는 사실상 잘 나와있지 않고 몇몇 해외유저들도 비슷한 의견을 남기는걸 목격했다.

공식 opencv github에서 조차 관련 문제를 해결하기 위해 이것저것 얘기를 나눈거 같은데 끝내 머지가 블록되는것만 보이고 관련 내용은 더이상 찾아볼수 없었다.

일반적으로 포인터로 접근하여 처리하는게 더 빠를거라 예상했지만 각 분야별 비슷하게 제공하는 API의 퍼포먼스측면에서는 차이가 날수 있을거라는 생각이 든 시간이였으며, 특히, foreach의 경우 자체 알고리즘이 병렬적으로 처리하기 때문에 이를 권장하는 느낌이 들었고 이는 문서나 정보를 확실히 많이 접해야겠다는 생각이들었다.
(물론 대용량이 아닐경우는 차이가 미미하겠지만..)

profile
으아아

0개의 댓글