OpenCV 픽셀 접근 속도 테스트
픽셀단위에 접근하여 연산할 때 가장 어떤 방법이 가장 빠른가?
결론 :
- 순차처리
- atFunc : 2.0873msec.
- dataPtr : 1.4164msec.
- ptrFunc : 1.1877msec.
- ptr++ : 0.2126msec.
- 병렬처리
- parallel_for dataPtr : 0.393msec.
- parallel_for ptr: 0.2211msec.
- parallel_for Optimize: 0.0557msec.
```cpp
#include <iostream>
#include <stdio.h>
#include "opencv2/opencv.hpp"
#include <ppl.h>
int main()
{
//화면을 표시할 윈도우 설정
std::string wndName = "Color Test";
namedWindow(wndName, cv::WINDOW_NORMAL);
cv::setWindowTitle(wndName, "Color Test");
//mnms이미지 불러오기
cv::Mat OriginImg = cv::imread("../images/mnms.png",cv::IMREAD_GRAYSCALE);
cv::Mat TestImg = OriginImg;
//원본 이미지 출력
cv::imshow(wndName, OriginImg);
cv::waitKey(0);
cv::destroyWindow(wndName);
//이미지의 모든 픽셀을 순회할 때 소요된 시간을 측정해본다.
//시작,종료 시간을 기록하기 위한 timer
cv::TickMeter tm;
#pragma region atFunc
tm.reset();
tm.start();
for (int y = 0; y < TestImg.rows; ++y)
{
for (int x = 0; x < TestImg.cols; ++x)
{
uchar val = TestImg.at<uchar>(y, x);
TestImg.at<uchar>(y, x) = val + 1;
}
}
tm.stop();
std::cout << "atFunc : " << tm.getTimeMilli() << "msec." << std::endl;
#pragma endregion
#pragma region dataPtr
tm.reset();
tm.start();
uchar* pTestImg = TestImg.data;
for (int y = 0; y < TestImg.rows; ++y)
{
for (int x = 0; x < TestImg.cols; ++x)
{
uchar val = pTestImg[TestImg.rows * y + x];
pTestImg[x] = val + 1;
}
}
tm.stop();
std::cout << "dataPtr : " << tm.getTimeMilli() << "msec." << std::endl;
#pragma endregion
#pragma region ptr
tm.reset();
tm.start();
for (int y = 0; y < TestImg.rows; ++y)
{
//Test이미지의 행의 시작 주소를 가져옴
uchar* pImg = TestImg.ptr<uchar>(y);
//행의 시작에서 하나씩 증분하여 한 행의 끝까지 데이터 탐색
for (int x = 0; x < TestImg.cols; ++x)
{
uchar val = pImg[x];
pImg[x] = val + 1;
}
}
tm.stop();
std::cout << "ptrFunc : " << tm.getTimeMilli() << "msec." << std::endl;
#pragma endregion
#pragma region ptr++
tm.reset();
tm.start();
for (int y = 0; y < TestImg.rows; ++y)
{
//Test이미지의 행의 시작 주소를 가져옴
uchar* pSrc = TestImg.ptr<uchar>(y);
//Test이미지의 행의 마지막 주소를 가져옴
uchar* pSrc_end = pSrc + TestImg.cols;
//한행의 끝이 나올때까지 반복
for (; pSrc < pSrc_end;)
{
uchar val = *pSrc;
//후치 연산자로 val값 업데이트 후 포인터 위치변경
*pSrc++ = val + 1;
}
}
tm.stop();
std::cout << "ptr++ : " << tm.getTimeMilli() << "msec." << std::endl;
#pragma endregion
#pragma region parallel_for dataPtr
tm.reset();
tm.start();
uchar* pSrc = TestImg.data;
Concurrency::parallel_for(int(0), TestImg.rows, [&](int y)
{
for (int x = 0; x < TestImg.cols; ++x) {
uchar val = pSrc[TestImg.cols * y + x];
pSrc[TestImg.cols * y + x] = val + 1;
}
});
tm.stop();
std::cout << "parallel_for dataPtr : " << tm.getTimeMilli() << "msec." << std::endl;
#pragma endregion
#pragma region parallel_for ptr
tm.reset();
tm.start();
Concurrency::parallel_for(int(0), TestImg.rows, [&](int y)
{
uchar* pSrc = TestImg.ptr<uchar>(y);
for (int x = 0; x < TestImg.cols; ++x) {
uchar val = pSrc[x];
pSrc[x] = val + 1;
}
});
tm.stop();
std::cout << "parallel_for ptr: " << tm.getTimeMilli() << "msec." << std::endl;
#pragma endregion
#pragma region parallel_for ptr++
tm.reset();
tm.start();
concurrency::parallel_for(int(0), TestImg.rows, [&](int y)
{
uchar* pSrc = TestImg.ptr<uchar>(y);
uchar* pSrc_end = pSrc + TestImg.cols;
for (; pSrc < pSrc_end;) {
uchar val = *pSrc;
*pSrc++ = val + 1;
}
});
tm.stop();
std::cout << "parallel_for Optimize: " << tm.getTimeMilli() << "msec." << std::endl;
#pragma endregion
return 0;
}
```