-2

So I have this piece of code:

  if(channels == 3)
    type = CV_32FC3;
  else
    type = CV_32FC1;
  cv::Mat M(rows,cols,type);
  std::cout<<"Cols:"<<cols<<" ColsMat:"<<M.cols<<std::endl;
  float * source_data = (float*) M.data;
  // copying the data into the corresponding pixel
  for (int r = 0; r < rows; r++)
    {
      float* source_row = source_data + (r * rows   * channels);
      for (int c = 0; c < cols ; c++)
    {
      float* source_pixel = source_row + (c * channels);
      for (int ch = 0; ch < channels; ch++)
      {
        std::cout<<"Row:"<<r<<" Col:"<<c<<" Channel:"<<ch<<std::endl;
        std::cout<<"Type check: "<<typeid(T_M(0,r,c,ch)).name()<<std::endl; 
        float* source_value = source_pixel + ch;
        *source_value = T_M(0, r, c, ch);
      }
    }
    }

T_M is an Eigen::Tensor

I first thought that I got the error from T_M but it isn't the case.

I tried accessing *source_value and I am mostly sure that is the source of the error.

Funny thing is that I don't get the error in the end or the beginning. I get the seg fault around the middle. For example, with rows: 915, cols: 793, and channels:1

I get the error at Row:829 Col:729 Channel:0.

I can't figure out the source of this error.

Alperen AYDIN
  • 547
  • 1
  • 6
  • 17
  • The right tool to solve such problems is to use your debugger, but not to ask at Stack Overflow before you did so. Tell us all your observations you made when inspecting your code stepping through line by line in 1st place. Also you might want to read [**How to debug small programs (by Eric Lippert)](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/)**] At least leave us with a **[MCVE]** that reproduces your problem. (This is a personal stock comment provided by πάντα ῥεῖ™) – πάντα ῥεῖ Aug 20 '16 at 08:18
  • I generally agree. In that case, it would be a job for `electricfence` instead, well if you are using Linux. – Jean-François Fabre Aug 20 '16 at 09:01
  • I agree with you. However, I am in a unfamiliar place with a unfamiliar build tool(bazel). So I thought I would ask this while I was trying to convince Bazel to cooperate. – Alperen AYDIN Aug 20 '16 at 10:03

2 Answers2

2

you compute your row pointer wrong, should be cols instead of rows:

float* source_row = source_data + (r * cols   * channels);

In general, you must be very careful when you use a flat representation of a matrix, it's really error-prone.

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
  • this will only work if there is no padding at the end of each row. imho the right way is to compute the row_ptr in char* oder uchar* by `.data + r*widthStep` and cast to float* afterwards. – Micka Aug 20 '16 at 08:52
2

The answer from Jean-François Fabre will work, if the matrix is continuous. If you can't be sure about that (e.g. if the matrix is provided by someone else, if you use submatrixes, etc.), you should use the widthstep feature to compute the row pointer:

float* source_row = (float*)(M.data + r*M.step);

this automatically uses the right number of channels, padding, etc.

even simpler is to use the row-ptr function directly:

float* source_row = (float*)(M.ptr(r));
Micka
  • 19,585
  • 4
  • 56
  • 74
  • 1
    There are a [few other ways](http://stackoverflow.com/a/31894250/5008845). E.g. `float* source_row = M.ptr(r);` seems even simpler to me – Miki Aug 20 '16 at 12:48