I want to create a two-channel matrix in OpenCV, whose values are the corresponding pair of row and column indexes. I can easily do that in the following way:
for (int i = 0 ; i< img_height ; ++ i){
for (int j = 0 ; j < img_width ; ++ j){
src.ptr<Point2f>(i)[j] = Point2f(j,i);
}
}
I wonder if there is a way in OpenCV to initialize such a matrix in a faster and more compact way, without necessarily using this element-wise approach. I searched on the documentation, but I didn't find anything that could help me for this purpose.
I ask that because I do need my application to be faster, so I'm looking for any possible improvements I can apply on my code.
Thanks in advance
There's no builtin function to to this. You can eventually mimic the Matlab function meshgrid
using repeat, but in this case is going to be much slower.
You can however improve a few things:
Have a look at this code:
Mat2f src(img_height, img_width);
for (int i = 0; i < img_height; ++i) {
Vec2f* ptr = src.ptr<Vec2f>(i);
for (int j = 0; j < img_width; ++j) {
ptr[j][0] = i;
ptr[j][1] = j;
}
}
This snippet is a little faster (time in ms):
@MarcoFerro: 1.22755
@Miki: 0.818491
Testing code:
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
int main()
{
int img_height = 480;
int img_width = 640;
{
Mat2f src(img_height, img_width);
double tic = double(getTickCount());
for (int i = 0; i< img_height; ++i){
for (int j = 0; j < img_width; ++j){
src.ptr<Point2f>(i)[j] = Point2f(i, j);
}
}
double toc = (double(getTickCount()) - tic) * 1000.0 / getTickFrequency();
cout << "@MarcoFerro: \t" << toc << endl;
}
{
Mat2f src(img_height, img_width);
double tic = double(getTickCount());
for (int i = 0; i < img_height; ++i) {
Vec2f* ptr = src.ptr<Vec2f>(i);
for (int j = 0; j < img_width; ++j) {
ptr[j][0] = i;
ptr[j][1] = j;
}
}
double toc = (double(getTickCount()) - tic) * 1000.0 / getTickFrequency();
cout << "@Miki: \t\t" << toc << endl;
}
getchar();
return 0;
}