Ask Your Question

Efficient calculation with multiple cv::Mat

asked 2018-07-31 15:33:44 -0500

robro gravatar image

Hello, I need to do some math with my matrices and I would like to know the most performant way. I have the following vectors:

std::vector<cv::Mat> b //200 matrices with 1 row and 1000 elements per row
std::vector<cv::Mat> w //200 matrices with 1 row and 1000 elements per row 
std::vector <cv::Mat>image //200 matrices with 500 rows and 1000 elements per row

All vectors with the same index belong together. I need to calculate the following for every Mat of the vectors with the same index and every pixel in the image:

image(x, y) = (image(x,y) – b(x)) / (w(x) – b(x))  * 0,9

I would start like the following:

for(int i=0; i<image.size(); i++) 
//And here? 
//Usage of the “at”-method or pointer arithmetic?
//Or is there an operation which can calculate everything automatically line by line?

Thank you very much :-)

edit retag flag offensive close merge delete



you could precalculate Mat mwb = 0.9 / (w - b), which is used to scale the results of every line, then for each row of an image you could calculate new_image_row = mwb * (image_row - b), where '*' is an element by element multiply. Parallelism (CPU core or thread) is a possible thing to exploit, see TBB and threads. SIMD vector arithmetic might allows you to accelerate the cell arithmetic for specific Mat data cell types. Good luck!

opalmirror gravatar imageopalmirror ( 2018-07-31 20:13:23 -0500 )edit

Thanks for the idea! I just had another one. I could make the number of rows of "b" and "w" dynamically the same as image and then use direct methods like "cv::subtract". Is this a good idea?

robro gravatar imagerobro ( 2018-08-01 00:23:25 -0500 )edit

1 answer

Sort by » oldest newest most voted

answered 2018-08-01 02:04:06 -0500

berak gravatar image

updated 2018-08-01 12:44:32 -0500

you should not do anything per pixel, but process whole rows at a time:

for(int i=0; i<image.size(); i++) 
    Mat wb = (w[i] - b[i]) * 0.9;
    for (int j=0; j<images[i].rows; j++)
       divide( image[i].row(j) - b[i], wb, image[i].row(j) );
edit flag offensive delete link more


Thank you very much! This is exactly what I was looking for :-)

robro gravatar imagerobro ( 2018-08-01 12:27:18 -0500 )edit

Full answer from @berak is great; it has one little bug in that 0.9 needs to be used to multiply elements of the j'th row of image, not divide it. So the Mat line could be rewritten:

Mat wb = (w[i] - b[i]) / 0.9;
opalmirror gravatar imageopalmirror ( 2018-08-01 13:54:12 -0500 )edit

^^ ofc. right. but i think - let's rather keep everything "as is" (not update the answer), it'll probably be much easier to understand this way

berak gravatar imageberak ( 2018-08-01 14:36:35 -0500 )edit

Question Tools

1 follower


Asked: 2018-07-31 15:33:44 -0500

Seen: 376 times

Last updated: Aug 01 '18