# Efficient calculation with multiple cv::Mat

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 close merge delete

2

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!

( 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?

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

Sort by » oldest newest most voted

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) );
}
}

more

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

( 2018-08-01 12:27:18 -0500 )edit
2

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;

( 2018-08-01 13:54:12 -0500 )edit
2

^^ 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

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