Ask Your Question

Revision history [back]

Multithreading for Image Processing

I do not have much experience with multithreading. I just want to create 4 threads. Devide image in 4 parts and process each part in different thread and join each part back. I have written following code.

#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>
#include <stdio.h>
#include <cstdlib>
#include <pthread.h>
#include <unistd.h>

using namespace std;

struct thread_data {
    int thread_id;
    cv::Mat img;
    cv::Mat retVal;
    double alpha;
};

void *processFrame(void *threadarg)
{
    //printf("processFrame started\n");
    struct thread_data *my_data;

    my_data = (struct thread_data *)threadarg;
    printf("%d %d %d %d %d\n",my_data->thread_id, my_data->img.rows, my_data->img.cols, my_data->retVal.rows, my_data->retVal.cols);
    //cv::accumulateWeighted(my_data->img, my_data->retVal, my_data->alpha);
    pthread_exit(NULL);
}

int main(int argc, char* argv[])
{
    int NUM_THREADS = 4;
    pthread_t threads[NUM_THREADS];
    struct thread_data td[NUM_THREADS];
    int rc;

    cv::Mat img, acc;
    double alpha = 0.1;
    std::vector<cv::Mat> cutImg, accImg;

    img = cv::imread(argv[1]);
    acc = cv::Mat::zeros(img.size(), CV_32FC3);

    cutImg.push_back(cv::Mat(img, cv::Range(0, img.rows/2), cv::Range(0, img.cols/2)));
    cutImg.push_back(cv::Mat(img, cv::Range(0, img.rows/2), cv::Range(img.cols/2, img.cols)));
    cutImg.push_back(cv::Mat(img, cv::Range(img.rows/2, img.rows), cv::Range(0, img.cols/2)));
    cutImg.push_back(cv::Mat(img, cv::Range(img.rows/2, img.rows), cv::Range(img.cols/2, img.cols)));

    accImg.push_back(cv::Mat(acc, cv::Range(0, img.rows/2), cv::Range(0, img.cols/2)));
    accImg.push_back(cv::Mat(acc, cv::Range(0, img.rows/2), cv::Range(img.cols/2, img.cols)));
    accImg.push_back(cv::Mat(acc, cv::Range(img.rows/2, img.rows), cv::Range(0, img.cols/2)));
    accImg.push_back(cv::Mat(acc, cv::Range(img.rows/2, img.rows), cv::Range(img.cols/2, img.cols)));

    for(int i=0; i<NUM_THREADS; i++)
    {
        td[i].thread_id = i;
        td[i].img = cutImg[i];
        td[i].retVal = accImg[i];
        td[i].alpha = alpha;

        rc = pthread_create(&threads[i], NULL, processFrame, (void*)&td[i]);

        if(rc) {
            printf("Error: Unable to create thread\n");
            exit(-1);
        }
    }
    pthread_exit(NULL);
    return(1);
}

So when I run the program, most of the times it shows that the images that I passed have 0 rows.

accumulateWeighted starting 1
1 270 480 270 480
accumulateWeighted starting 3
3 0 480 0 480
accumulateWeighted done 3
accumulateWeighted starting 2
2 0 480 0 480
accumulateWeighted done 2
accumulateWeighted starting 0
0 270 480 270 480
accumulateWeighted done 0
accumulateWeighted done 1

What am I doing wrong here? I have tried looking for examples but couldn't find any. Is there any other way that this can be done?

Multithreading for Image Processing

I do not have much experience with multithreading. I just want to create 4 threads. Devide image in 4 parts and process each part in different thread and join each part back. I have written following code.

#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>
#include <stdio.h>
#include <cstdlib>
#include <pthread.h>
#include <unistd.h>

using namespace std;

struct thread_data {
    int thread_id;
    cv::Mat img;
    cv::Mat retVal;
    double alpha;
};

void *processFrame(void *threadarg)
{
    //printf("processFrame started\n");
    struct thread_data *my_data;

    my_data = (struct thread_data *)threadarg;
    printf("accumulateWeighted starting %d\n", my_data->thread_id);
    printf("%d %d %d %d %d\n",my_data->thread_id, my_data->img.rows, my_data->img.cols, my_data->retVal.rows, my_data->retVal.cols);
    //cv::accumulateWeighted(my_data->img, my_data->retVal, my_data->alpha);
    printf("accumulateWeighted done %d\n", my_data->thread_id);
    pthread_exit(NULL);
}

int main(int argc, char* argv[])
{
    int NUM_THREADS = 4;
    pthread_t threads[NUM_THREADS];
    struct thread_data td[NUM_THREADS];
    int rc;

    cv::Mat img, acc;
    double alpha = 0.1;
    std::vector<cv::Mat> cutImg, accImg;

    img = cv::imread(argv[1]);
    acc = cv::Mat::zeros(img.size(), CV_32FC3);

    cutImg.push_back(cv::Mat(img, cv::Range(0, img.rows/2), cv::Range(0, img.cols/2)));
    cutImg.push_back(cv::Mat(img, cv::Range(0, img.rows/2), cv::Range(img.cols/2, img.cols)));
    cutImg.push_back(cv::Mat(img, cv::Range(img.rows/2, img.rows), cv::Range(0, img.cols/2)));
    cutImg.push_back(cv::Mat(img, cv::Range(img.rows/2, img.rows), cv::Range(img.cols/2, img.cols)));

    accImg.push_back(cv::Mat(acc, cv::Range(0, img.rows/2), cv::Range(0, img.cols/2)));
    accImg.push_back(cv::Mat(acc, cv::Range(0, img.rows/2), cv::Range(img.cols/2, img.cols)));
    accImg.push_back(cv::Mat(acc, cv::Range(img.rows/2, img.rows), cv::Range(0, img.cols/2)));
    accImg.push_back(cv::Mat(acc, cv::Range(img.rows/2, img.rows), cv::Range(img.cols/2, img.cols)));

    for(int i=0; i<NUM_THREADS; i++)
    {
        td[i].thread_id = i;
        td[i].img = cutImg[i];
        td[i].retVal = accImg[i];
        td[i].alpha = alpha;

        rc = pthread_create(&threads[i], NULL, processFrame, (void*)&td[i]);

        if(rc) {
            printf("Error: Unable to create thread\n");
            exit(-1);
        }
    }
    pthread_exit(NULL);
    return(1);
}

So when I run the program, most of the times it shows that the images that I passed have 0 rows.

accumulateWeighted starting 1
1 270 480 270 480
accumulateWeighted starting 3
3 0 480 0 480
accumulateWeighted done 3
accumulateWeighted starting 2
2 0 480 0 480
accumulateWeighted done 2
accumulateWeighted starting 0
0 270 480 270 480
accumulateWeighted done 0
accumulateWeighted done 1

What am I doing wrong here? I have tried looking for examples but couldn't find any. Is there any other way that this can be done?