lundi 23 mai 2016

OpenCV: how to perform batch processing of folder with images?

I have folder of images and I perform sequence of some basic operations on them:

  1. Load source image.
  2. Perform some image processing on image.
  3. Save result image.

So I want to process each image in separate thread to speedup processing.

Here is my example code:

ThreadExample.h

#include <thread>


    class ThreadProcessing
    {
         static unsigned int concurentThreadsSupported;

         void Func1();
         static void Func2();
         void Func3(int i);
         static void Func4(int i);

         static void ImageProcessingFunction(const std::string &input_dir, const std::string &filename);
    public:
         void PrintNumberOfCPU();
         void MultithreadingProcessing(const std::string &dir, int N);
         void SingleThreadProcessing(const std::string &dir);
    };

ThreadExample.cpp

    #include "ThreadExample.h"

    unsigned int ThreadProcessing::concurentThreadsSupported = std::thread::hardware_concurrency();

    using namespace std;

    void ThreadProcessing::PrintNumberOfCPU()
    {
        cout << "Number of CPU : " << concurentThreadsSupported << endl;
    }

void ThreadProcessing::ImageProcessingFunction(const string &input_dir, const string &filename)
    {
        //cout << "input_filename : " << input_dir+"/"+filename << endl;

        Mat src= imread(input_dir+"/"+filename);
        Mat dst;

        for(int i=0; i<10; ++i)
        {
            medianBlur(src, dst, 71);
        }

        boost::filesystem::path name= path(filename).stem();

        string output_filename= (input_dir/name).string()+"_output.png";
        //cout << "output_filename : " << output_filename << endl;
        imwrite(output_filename, dst);
    }

    void ThreadProcessing::Func1()
    {

    }

    void ThreadProcessing::Func2()
    {

    }

    void ThreadProcessing::Func3(int i)
    {

    }

    void ThreadProcessing::Func4(int i)
    {

    }

    void ThreadProcessing::SingleThreadProcessing(const string &dir)
    {
        time_t SingleThreadProcessingTime = clock();

        vector<string> imageNames= GetAllFilenamesInDir(dir, ".jpg");
    //    cout << "imageNames.size() : " << imageNames.size() << endl;
    //    for(int i=0; i<(int)imageNames.size(); ++i)
    //    {
    //      cout << imageNames[i] << endl;
    //    }

        for(int i=0; i<(int)imageNames.size(); ++i)
        {
            ImageProcessingFunction(dir, imageNames[i]);
        }

        SingleThreadProcessingTime = clock() - SingleThreadProcessingTime;
        cout << "SingleThreadProcessingTime : " << (float(SingleThreadProcessingTime) / CLOCKS_PER_SEC) << endl;
    }

    void ThreadProcessing::MultithreadingProcessing(const string &dir, int N)
    {
        time_t MultithreadingProcessingTime = clock();

        std::thread threads[N];

        bool isAllImageProcessed= false;
        vector<string> imageNames= GetAllFilenamesInDir(dir, ".jpg");
    //    cout << "imageNames.size() : " << imageNames.size() << endl;
    //    for(int i=0; i<(int)imageNames.size(); ++i)
    //    {
    //      cout << imageNames[i] << endl;
    //    }

        for(int i=0; i<(int)imageNames.size();)
        {
            //Launch a group of threads
            for(int k= 0; k< N; ++k)
            {
                threads[k] = std::thread(ImageProcessingFunction, dir, imageNames[i]);

                //examples:
                //threads[k] = std::thread(&ThreadProcessing::Func1, this);     //v1
                //threads[k] = std::thread(Func2);                              //v2
                //threads[k] = std::thread(&ThreadProcessing::Func3, this, k);  //v3
                //threads[k] = std::thread(Func4, k);                           //v4

                i++;

                if(i>=(int)imageNames.size())
                {
                    N= k+1;
                    isAllImageProcessed= true;
                    break;
                }
            }

            //Join the threads with the main thread
            for(int k= 0; k< N; ++k)
            {
                threads[k].join();
            }

            //cout << "i : " << i << endl;
            //cout << "N : " << N << endl;

            if(isAllImageProcessed)
                break;
        }

        MultithreadingProcessingTime = clock() - MultithreadingProcessingTime;
        cout << "MultithreadingProcessingTime : " << (float(MultithreadingProcessingTime) / CLOCKS_PER_SEC) << endl;
    }

main.cpp

int main(int argc, char** argv)
{
    ThreadProcessing threadProcessing;
    threadProcessing.PrintNumberOfCPU();
    threadProcessing.SingleThreadProcessing("/home/user/Images");
    threadProcessing.MultithreadingProcessing("/home/user/Images", 1);
    cout << "Done." << endl;
    return 0;
}

But it seems there is no speed improvement:

When I use 1 thread, output is:

Number of CPU : 8
SingleThreadProcessingTime : 6.54173
MultithreadingProcessingTime : 6.73393
Done.

When I use 4 threads, output is:

Number of CPU : 8
SingleThreadProcessingTime : 6.39089
MultithreadingProcessingTime : 8.3365
Done.

Is there is something wrong with my code or something conceptually wrong?

Aucun commentaire:

Enregistrer un commentaire