Skip to content

cv::parallel_for_を使ってみる

atinfinity edited this page Jun 20, 2015 · 25 revisions

cv::parallel_for_を使ってみる

はじめに

サンプルコード

cv::parallel_for_を使って二値化を行うサンプルです.

#include <opencv2/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>

void my_threshold
(
    const cv::Mat& src, cv::Mat& dst,
    double thresh, double max_value
)
{
    int x, y = 0;
    unsigned char intensity = 0;
    for (y = 0; y < src.rows; y++)
    {
        for (x = 0; x < src.cols; x++)
        {
            intensity = src.at<unsigned char>(y, x);
            if (intensity < (unsigned char)thresh)
            {
                dst.at<unsigned char>(y, x) = 0;
            }
            else
            {
                dst.at<unsigned char>(y, x) = (unsigned char)max_value;
            }
        }
    }
}

class TestParallelLoopBody : public cv::ParallelLoopBody
{
private:
    cv::Mat _src;
    cv::Mat _dst;
    double _thresh;
    double _max_value;
public:
    TestParallelLoopBody
    (
        const cv::Mat& src, cv::Mat& dst,
        double thresh, double max_value
    )
    : _src(src), _dst(dst), _thresh(thresh), _max_value(max_value) { }
    void operator() (const cv::Range& range) const
    {
        int row0 = range.start;
        int row1 = range.end;
        cv::Mat srcStripe = _src.rowRange(row0, row1);
        cv::Mat dstStripe = _dst.rowRange(row0, row1);
        my_threshold(srcStripe, dstStripe, _thresh, _max_value);
    }
};

int main(int argc, char *argv[])
{
    cv::Mat src(cv::Size(5000, 5000), CV_8UC1, cv::Scalar(255));
    cv::Mat dst = cv::Mat::zeros(src.size(), CV_8UC1);
    double f = 1000.0f / cv::getTickFrequency();

    int64 start = cv::getTickCount();
    my_threshold(src, dst, 100, 255);
    int64 end = cv::getTickCount();
    std::cout << "my_threshold: " << (end - start) * f << "[ms]" << std::endl;

    start = cv::getTickCount();
    cv::parallel_for_
        (
        cv::Range(0, dst.rows),
        TestParallelLoopBody(src, dst, 100, 255)
        );
    end = cv::getTickCount();
    std::cout << "my_threshold(parallel_for_): " << (end - start) * f << "[ms]" << std::endl;

    return 0;
}

実行結果

my_threshold: 42.6608[ms]
my_threshold(parallel_for_): 9.04392[ms]

※実行環境によって結果は異なります.

備考

筆者はOpenCV 3.0.0で動作確認しました.


Menu

Computer Vision

GPGPU

AR

ROS

Docker

Jetson

ARM

プログラミング言語

開発環境

勉強会

Clone this wiki locally