3

I want to represent the matrix of cv::SIFT descriptors cv::Mat descriptors as float*. This is because I want to use GMM from VLFeat (if you have any better solution, please let me know). This is the code that I came up with:

if(!prova.isContinous()){
    std::err<<"Descriptor matrix not continuous!"<<std::endl;
    return 1;
}
float *data = new float[desc.total()];
std::memcpy(data,prova.data,prova.total() * sizeof(float));

Trying this code with a toy matrix:

cv::Mat prova = (cv::Mat_<float>(3,3) << 0.1, 0.3, 2.1, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8);

And print the values:

for(int i=0;i<prova.total();i++)
    std::cout<<*(data+i)<<std::endl;

This works fine, but since we're dealing with pointers (and it's always a dangerous matter) I would like an opinion.

NOTE: just for giving a context, this is how I'm going to use data:

VlGMM* gmm = vl_gmm_new(VL_TYPE_FLOAT, desc.cols, 2) ;
vl_gmm_cluster (gmm, data, desc.rows);
Julian Declercq
  • 1,536
  • 3
  • 17
  • 32
justHelloWorld
  • 6,478
  • 8
  • 58
  • 138

2 Answers2

6

You can use the Mat::ptr method to get the float pointer to the beginning of any row. Specifically, the beginning of the matrix is:

const float* buffer=desc_mat.ptr<float>(0);
Photon
  • 3,182
  • 1
  • 15
  • 16
  • That was tricky :) But then I'm not sure if it's safe to give to `gmm` simply `buffer` instead of data. I'm still unexpert with `VLFeat`. – justHelloWorld Jul 21 '16 at 07:17
  • 1
    @Photon To get the whole data, I usually just write `float* imageData = (float*)image.data;` – Sunreef Jul 21 '16 at 09:04
  • 1
    Two issues: I try to avoid C style casting, which may lead to invalid conversions sometime. Using knowledge of the implementation which may change one day is usually less robust than using the interface. – Photon Jul 21 '16 at 09:07
-1

the issue that can happen if stride not equal to number of columns*4
4= size of float, you can get holes in the data so the only way to be sure is to copy pixel by pixel