Bug on cv::Mat_ with custom data type (Bug #4415)


Added by Hernan Badino over 9 years ago. Updated over 9 years ago.


Status:New Start date:2015-06-16
Priority:Normal Due date:
Assignee:- % Done:

0%

Category:-
Target version:-
Affected version:2.4.9 (latest release) Operating System:Linux
Difficulty: HW Platform:x64
Pull request:

Description

There seems to be a bug when dealing with cv::Mat_ with custom data types. The bug is an incorrect pointer offset when trying to access a particular element of the matrix. In particular the step member seems to be incorrectly computed. My understanding is that step should be equal to sizeof(Type) * cols + padding. It looks like that when calculating step, instead of using sizeof(Type), a constant size element of 8 is used instead. The following code should replicate the problem:

  // Custom data type
  struct SType
  {
      int a;
      char c[16];
  };

  /// Create cv::Mat with custom data type
  cv::Mat_<SType> m = cv::Mat_<SType>(10, 10);

  /// Check element size and step       
  printf("cols = %i, rows = %i, step = %zi (should be %zi), elemSize = %zi (should be %zi), elemSize1 = %zi (should be %zi)\n",
          m.cols, m.rows, m.step[0], m.cols*sizeof(SType), m.elemSize(), sizeof(SType), m.elemSize1(), sizeof(SType) );

  /// Pointer to element 5,5
  unsigned char *  ptr = (unsigned char *)&m(5,5);

  /// Offset from data pointer 
  ssize_t actual       = (ptr - m.data);

  /// Expected offset 
  ssize_t real         = sizeof(SType)*(m.cols*5+5);

  printf("pointer offset in bytes = %zi (should be %zi), offset in elements = %zi (should be %zi)\n",
          actual, real, actual/sizeof(SType), real/sizeof(SType));     

The output of the code is:

cols = 10, rows = 10, step = 80 (should be 200), elemSize = 20 (should be 20), elemSize1 = 20 (should be 20)
pointer offset in bytes = 500 (should be 1100), offset in elements = 25 (should be 55)

The result 500 looks like obtained from (step * row)+(elemSize * col) -> (80 * 5)+(20 * 5). step=80 is obviously wrong as it should be 200.

As a result, both the operator() and the template method at<Type> result in incorrect memory accesses, leading to corrupted data and eventual segmentation faults. My version.hpp contains.

#define CV_VERSION_EPOCH    2
#define CV_VERSION_MAJOR    4
#define CV_VERSION_MINOR    11

I'm using a Linux (Ubuntu 14.05) environment.


History

Updated by Maksim Shabunin over 9 years ago

Issue has been transferred to GitHub: https://github.com/Itseez/opencv/issues/5027

Also available in: Atom PDF