Vector of a class that inherits from a standard OpenCV class

asked 2020-05-15 07:39:59 -0500

thewoz gravatar image

updated 2020-05-18 05:50:32 -0500

berak gravatar image

Hi all,

I try to run this code but I have some troubles. The code is the following:

class point3D_t : public cv::Point3f { 

  public:

    int label;
    int frame;
    double value;

};

class point2D_t : public cv::Point2f { 

  public:

    int label;
    int frame;
    double value;

};

int main(int argc, const char * argv[]) {

  std::vector<point3D_t> input;
  std::vector<point2D_t> output;

  cv::Mat R,T,K;
  std::vector<double> distCoeffs;

  cv::projectPoints(input, R, T, K, distCoeffs, output);

  return 0;

}

It gives me back as error in:

#include <opencv2/opencv.hpp>
#include "opencv2/core.hpp"
#include "opencv2/core/traits.hpp"

template<typename _Tp> inline
_InputArray::_InputArray(const std::vector<_Tp>& vec)
{ init(FIXED_TYPE + STD_VECTOR + traits::Type<_Tp>::value + ACCESS_READ, &vec); }

this:

Incomplete definition of type 'cv::traits::Type<point3D_t>'

@mshabunin suggest me:

You have to specify cv::traits::Type<...> in your code to be able to use custom types like this

But I do not know what doesn't means.

In the mean time I do that:

template <>
class cv::DataType<cv::Point2f> {

public:
  typedef point2D_t value_type;
  typedef point2D_t work_type;
  typedef float channel_type;

  enum { generic_type = 0,
    channels     = 2,
    fmt          = traits::SafeFmt<channel_type>::fmt + ((channels - 1) << 8)
  };

};

namespace cv::traits {
  template<>
  struct Depth<point2D_t> { enum { value = Depth<cv::Point2f>::value }; };
  template<>
  struct Type<point2D_t> { enum { value = CV_MAKETYPE(Depth<point2D_t>::value, 2) }; };
}

and

template <>
class cv::DataType<cv::Point3f> {

public:
  typedef point3D_t value_type;
  typedef point3D_t work_type;
  typedef float channel_type;

  enum { generic_type = 0,
    channels     = 3,
    fmt          = traits::SafeFmt<channel_type>::fmt + ((channels - 1) << 8)
  };

};

namespace cv::traits {
  template<>
  struct Depth<point3D_t> { enum { value = Depth<cv::Point3f>::value }; };
  template<>
  struct Type<point3D_t> { enum { value = CV_MAKETYPE(Depth<point3D_t>::value, 3) }; };
}

the error went away. However I have problem in run time. As if the memory was corrupted

edit retag flag offensive close merge delete

Comments

can you explain, why you need this design ?

berak gravatar imageberak ( 2020-05-15 10:59:02 -0500 )edit

this is a simplification of my design. In reality my 2D and 3D class have a lot of stuff inside. However I would like that are compatible with the opencv function.

thewoz gravatar imagethewoz ( 2020-05-16 04:48:16 -0500 )edit

^ i asked: why ?

berak gravatar imageberak ( 2020-05-16 08:04:40 -0500 )edit

Ok sorry, In my code I have a lot of function that works on my class point3D_t and point2D_t. I store into that information like color label and other stuff. I also have heredity the base OpenCV points class to take advantage of all the function defined in that class. Moreover I would like to use the function defined in OpenCV like cv::projectPoints(). in my stupidity I thought that heredity a standard OpenCV class it is enough. If you think there is a more suitable design?

thewoz gravatar imagethewoz ( 2020-05-16 08:57:04 -0500 )edit

@berak what you think?

thewoz gravatar imagethewoz ( 2020-05-17 08:41:25 -0500 )edit

your classes are not binary compatible to the opencv ones they inherit from. and the Datatype templates do not respect your extra class members (label,frame,value). there will be internal "slicing", where they expect consecutive memory with either 2 or 3 elements, and that's where it'll crash.

again, inheritance works fine, when you have interfaces, virtual functions, references and that, NOT for primitive types, where exact memory layout is required

any chance you can achieve what you need without this terrible design (OOP overengineering) ?

berak gravatar imageberak ( 2020-05-18 01:38:16 -0500 )edit

Ok so there is a way to fix the Datatype templates to respect my extra class members? I understand that inherit a primitive types is not a good idea. Maybe I should have used another approach. But that is a way to fix this situation without rewrote all the code?

thewoz gravatar imagethewoz ( 2020-05-18 06:14:07 -0500 )edit