Opencv Data Type Definition

Hello, I was trying to somehow access my pixels in opencv 2. For this, I defined the following pixel structure:

struct mypixels { unsigned char red; unsigned char green; unsigned char blue; }; 

Now I tried the following and it works:

 int sz[3] = {2,2}; cv::Mat XL(2,sz, CV_8UC3, cv::Scalar::all(0)); cv::Mat_<cv::Vec3b> pixiter = XL; pixiter.at<mypixels>(0,0).green = 22; 

Now this code works well in release mode, but in debug mode I get some access violation error. I did not try to hack or rewrite opencv classes. I just don’t understand what I have to do to make this code work in release and debug mode. I thought, maybe I need to determine my pixels, as it is written here: http://docs.opencv.org/trunk/modules/core/doc/basic_structures.html#datatype But I could not understand how and what I should do here. Maybe here is someone who knows more.

- EDIT -

Using the working solution user2151446 and some extra brain power, I came up with this solution:

 template<> class cv::DataType<mypixels> { public: typedef mypixels value_type; typedef int work_type; typedef unsigned char channel_type; typedef value_type vec_type; enum { depth = CV_8U, channels = 3, type = CV_MAKETYPE(depth, channels), fmt=(int)'u' }; }; 
+4
source share
3 answers

The reason your code "works" in release mode is because the following statement is disabled:

 template<typename _Tp> inline _Tp& Mat::at(int i0, int i1) { CV_DbgAssert( dims <= 2 && data && (unsigned)i0 < (unsigned)size.p[0] && (unsigned)(i1*DataType<_Tp>::channels) < (unsigned)(size.p[1]*channels()) && CV_ELEM_SIZE1(DataType<_Tp>::depth) == elemSize1()); return ((_Tp*)(data + step.p[0]*i0))[i1]; } 

You can add this after defining mypixels (although I'm not sure what I recommend):

 template<> class DataType<mypixels> { public: typedef mypixels value_type; typedef int work_type; typedef value_type channel_type; typedef value_type vec_type; enum { depth = 1, channels = 3, type = CV_MAKETYPE(depth, channels) }; }; 

And then you can do it:

 Mat_<mypixels>& M1 = (Mat_<mypixels>&)pixiter; M1.at<mypixels>(0,0).green = 22; 
+4
source

You should use the type cv::Vec3b as the template parameter in pixiter.at<T>(row,col) . Since your custom type matches the definition of cv::Vec3b , oyu can directly execute the result if you need to.

Oh, by the way, the default color order of OpenCV is BGR.

+2
source

There are two possible problems.

  • Make sure that you are using the correct version of the mode to run the program.

  • Your use of an iterator template with mypixels for a matrix containing elements of type cv :: Vec3b is incorrect. Although they are similarly defined, they cannot be considered the same.

The cleanest way is

 int sz[3] = {2,2}; cv::Mat XL(2,sz, CV_8UC3, cv::Scalar::all(0)); cv::Mat_<cv::Vec3b> pixiter = XL; pixiter.at<cv::Vec3b>(0,0).val[1] = 22; 

If you really want to do this, you can do something like this. But it will break when OpenCV changes its data structure, if by accident.

 int sz[3] = {2,2}; cv::Mat XL(2,sz, CV_8UC3, cv::Scalar::all(0)); cv::Mat_<cv::Vec3b> pixiter = XL; cv::Vec3b& aVec = pixiter.at<cv::Vec3b>(0,0); mypixels& aMyPixel = reinterpret_cast<mypixels&>(aVec); aMyPixel.green = 22; 
0
source

Source: https://habr.com/ru/post/1486003/


All Articles