reduction operation using OpenCV ForEach, but thread-safe and faster?

39 views Asked by At

I have the following code to fill a cv::Mat matrix but It need to keep the places where the distance value pixel is less than thr in vectors lt_thr_row and lt_thr_col and also keep the counts of the rows and columns in lt_thr_cnt_row and lt_thr_cnt_col. Since it need to keep the index, I put a mutex to make it thread safe, but it is very slow when matrices go larger. Is there a way using maybe std::atomic or other way that might be faster?

#include <vector>
#include <iostream>
#include <opencv2/core.hpp>

double distance(std::pair<double,double> a, std::pair<double,double> b)
{
    double x = a.first  - b.first; //calculating number to square in next step
    double y = a.second - b.second;
    double dist;
    dist = pow(x, 2) + pow(y, 2);       //calculating Euclidean distance
    dist = sqrt(dist);
    return dist;
}

int main()
{
    double max_val = 10000.0;
    double thr = 1.5;
    int numR = 500;
    int numC = 150;
    cv::Mat matrix = cv::Mat::zeros(numR, numC, CV_64F);
    std::vector<std::pair<double, double>> vec1 ;
    std::vector<std::pair<double, double>> vec2 ;

    //code to fill in vec1 and vec2. vec1 has size 500, vec2 has 150.

    std::vector<int> lt_thr_row;
    std::vector<int> lt_thr_col;
    std::vector<int> lt_thr_cnt_row(numR,0);
    std::vector<int> lt_thr_cnt_col(numC,0);
    lt_thr_row.reserve(numR*numC);
    lt_thr_col.reserve(numR*numC);
    std::mutex mtx;
    if(numR != 0 && numC != 0){
        matrix.forEach<double>(
            [&lt_thr_row,&lt_thr_col,&lt_thr_cnt_row,&lt_thr_cnt_col,&mtx,
             &vec1,&vec2, thr,max_val](double &pixel, const int position[]) {
                pixel = distance(vec1[position[0]], vec2[position[1]]);
                if(pixel > thr)
                    pixel = max_val;
                else
                {
                    std::lock_guard<std::mutex> lock(mtx);
                    lt_thr_row.push_back(position[0]);
                    lt_thr_col.push_back(position[1]);
                    lt_thr_cnt_row[position[0]] +=1;
                    lt_thr_cnt_col[position[1]] +=1;
                }
            });
    }
    return 0;
}

I will very much appreciate any help with this.

0

There are 0 answers