1

I have a Mat matrix in openCV in c++, and I want to change the values in this matrix by providing the row and column positions in vectorial form. For example:

Mat M = Mat::zeros(10,10,CV_8UC1);
Mat IJ_coord = (Mat_<uchar>(3,2) << 0,0, 1,0, 2,7);
M.at<uchar>(IJ_coord) = 255;

Is there a way to do this without using a "for" cycle that is too slow? Below there is the code. Before there are some initialization I have omitted for simplicity. The last for cycles are the critical ones. They take 0.6 sec, almost half the time of the entire code.

int64 t0 = getTickCount();   



if (num_frame < 10){
prefix_num = "000";
} else if(num_frame < 100){
prefix_num = "00";
} else if(num_frame < 1000){
prefix_num = "0";
} else prefix_num = "";

string frame_num = to_string(num_frame);


Mat Point_w = readMatrix(folder_pnt_w + prefix_num + frame_num + ".txt",2);
Mat Point_I = readMatrix(folder_pnt_I + prefix_num + frame_num + ".txt",2);
I = imread(folder_frm + prefix_num + frame_num + ".jpg", 1);


split(I, planes);
I_ir = planes[2]-planes[1];




Mat H = findProjectiveTransformation(Point_I, Point_w);


addWeighted(i0, H.at<double>(0), j0, H.at<double>(1), H.at<double>(2), Num, 
-1);
addWeighted(i0, H.at<double>(6), j0, H.at<double>(7), 1, Den, -1);
divide(Num, Den, X_geo);
addWeighted(i0, H.at<double>(3), j0, H.at<double>(4), H.at<double>(5), Num, 
-1);
divide(Num, Den, Y_geo);

// here I will calculate the coordinates to access in the matrix

J_x_geo = (X_geo-X_min)/dx;
I_y_geo = (Y_max - Y_geo)/dy;

J_x_geo.convertTo(J_x_geo, CV_32S, 1, 0);
I_y_geo.convertTo(I_y_geo, CV_32S, 1, 0);



for(size_t i=0; i<I_ir.rows; i++){
for(size_t j=0; j<I_ir.cols; j++){




if (Y_geo.at<float>(i,j) >= Y_min && Y_geo.at<float>(i,j) <= Y_max && 
X_geo.at<float>(i,j) >= X_min && X_geo.at<float>(i,j) <= X_max){

if (Map.at<uchar>(I_y_geo.at<int>(i,j),J_x_geo.at<int>(i,j)) < I_ir.at<uchar>
(i,j)){

            Map.at<uchar>(I_y_geo.at<int>(i,j),J_x_geo.at<int>(i,j)) = 
            I_ir.at<uchar>(i,j);

         }
     }

}
}









int64 t1 = getTickCount();
double secs = (t1-t0)/getTickFrequency();

cout << secs << endl;
  • If you need to do this several times, you can create a mask once, and then use: `M.setTo(255, mask);`. What is the size of your matrices? _"Too slow"_ what actually means? Have you profiled it? – Miki Oct 12 '17 at 22:02
  • The mask can not work because I am processing a video and from frame to frame the indexed positions will change. The matrix is a Gray image, so it can be also 1000x1000. For slow I mean that it takes about 0.1 sec for frame (without considering the remaining of the code) – F. DE VIVO Oct 12 '17 at 22:22
  • Can you show the code you used? It seems it takes too much – Miki Oct 12 '17 at 22:48
  • I have posted the code in the image below – F. DE VIVO Oct 12 '17 at 23:03
  • Please use the [edit] button and add new info into the original question. And please don't post code as an image, but use formatting. And remove the answer, because it's not an answer – Miki Oct 12 '17 at 23:11
  • I did it as you suggested – F. DE VIVO Oct 12 '17 at 23:30

0 Answers0