2013-06-13 4 views
4

Здравствуйте, я продумал доступ к моим пикселям в opencv 2 каким-то умным способом. Для этого я определил следующую структуру пикселя:Opencv Определение типа данных

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

теперь я судимое следующее, и она работает:

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; 

Сейчас этот код хорошо работает в режиме выпуска, но в режиме отладки, я получаю какое-то нарушение доступа ошибка. Я не пытался взломать или переписать классы opencv. Я просто не понимаю, что я должен сделать, чтобы этот код работал в режиме выпуска и отладки. Я подумал, что, может быть, я должен определить свои пиксели так, как это написано здесь: http://docs.opencv.org/trunk/modules/core/doc/basic_structures.html#datatype Но я не мог понять, как и что мне здесь делать. Может быть, это тот, кто знает больше.

--EDIT--

С рабочим раствором user2151446 и некоторой дополнительной мощностью мозга я пришел к этому решению:

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' }; 
}; 
+1

int sz [3] = {2,2}; 3-разрядный массив инициализируется всего двумя значениями. Это то, что вы действительно хотите? – PermanentGuest

+0

это ошибка, которую я потратил только на два измерения, но я думаю, что это не должно вызывать никаких различий в коде – jamk

+0

Действительно?Это заставит cv_Mat выделить память для дополнительного измерения неопределенного размера. – PermanentGuest

ответ

4

Причина ваш код «работает» в режиме выпуска является то, что следующее утверждение отключено:

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]; 
} 

Вы можете добавить это после определения mypixels (хотя я не уверен, что я рекомендую):

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) }; 
}; 

И тогда вы можете сделать это:

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

Привет, спасибо это работает :) Я также не знаю, если это имеет смысл ... но иногда вам нужно собственное определение пикселей. Большое спасибо за то, что уделили вам время – jamk

2

Вы должны использовать cv::Vec3b тип в качестве параметра шаблона в pixiter.at<T>(row,col). Поскольку ваш пользовательский тип соответствует определению cv::Vec3b, oyu может напрямую направить результат, если вам нужно.

О, кстати, заказ цветов по умолчанию для OpenCV - BGR.

+0

+1 для подбора порядка пикселей – Bull

0

Возможны две проблемы.

  1. Убедитесь, что вы используете двоичные файлы режима свободной версии для запуска программы.

  2. Неправильное использование итератора с шаблонами с мипикселями для матрицы, содержащей элементы типа cv :: Vec3b. Несмотря на то, что они аналогично определены, они не могут считаться одинаковыми.

Чистейший путь

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; 

Если вы действительно хотите сделать в вашем пути, вы могли бы сделать что-то вроде этого. Но это сломается, когда OpenCV изменит свою структуру данных, если случайно.

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; 
Смежные вопросы