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;
}
```

+ Recent posts