есть ли метод шаблона для доступа к элементу OpenCV?

У меня есть некоторые процедуры, работающие с OpenCV Mat. Это один из них:

void drawCircles(Mat& image, const Mat points, Scalar color)
{
    // fix format of Matrix <-> hard coding

    //MatInfo(points);
    //getchar();

    CV_Assert(points.channels() == 2);
    //CV_Assert(points.depth() == CV_32FC2); // this is so restricted!!

    //CV_Assert(points.channels() == 2);
    //CV_Assert(points.depth() == CV_16UC2); 

    // added working for both row/col point vector

    Point2d p0;

    for (int i = 0; i < points.cols; i++)
    {   
        //p0.x = cvRound(points.at<Vec2i>(0,i)[0]);
        //p0.y = cvRound(points.at<Vec2i>(0,i)[1]);

        p0.x = cvRound(points.at<Vec2f>(0,i)[0]);
        p0.y = cvRound(points.at<Vec2f>(0,i)[1]);

        //p0.x = cvRound(points.at<Vec2d>(0,i)[0]);
        //p0.y = cvRound(points.at<Vec2d>(0,i)[1]);

        circle(image, p0, 5, color, 2, 8);
    }
}

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

У меня все в порядке с доступом к элементу Мата с помощью matrixA.at(i,j). Впрочем, это так специфично. Когда тип элемента матрицы отличается, функция не может работать. Можно ли в этом случае написать своего рода шаблонную функцию?? который не зависит от типа элемента Mat??

Спасибо

Редактировать01:

если это что-то вроде

template <class T> 
void drawCircles(Mat_<T> img, const Mat points, Scalar cl)
{
  ..
  img.at<T>() = something;
  ..
}

тогда было бы идеально. Но я выполнил поиск в документах OpenCV и не думаю, что это поддерживается OpenCV MAT. Или я упускаю какие-то моменты?

Edit02: Это моя попытка:

template <class Type>
void drawCircles(Mat& image, const Mat_<Vec<Type, 2> > points, Scalar color)
{

    for (int i = 0; i < points.cols; i++)
    {
        p0.x = cvRound(points.at<Vec<Type, 2>>(0,i)[0]);
        p0.y = cvRound(points.at<Vec<Type, 2>>(0,i)[1]);

        circle(image, p0, 5, color, 2, 8);
    }
}

и я называю это с помощью:

drawCircles(frame, Points, Scalar(255, 255, 255));

где Очки:

Mat Points = Mat(1, 5, CV_32FC2, 0);

Все равно не получается :(


person TSL_    schedule 16.12.2012    source источник
comment
Похоже, вам нужна такая функция, как Point2d roundedElement(mat,row,col), которая проверяет тип матрицы, использует соответствующий метод at<T> для этого типа, а затем возвращает округленный результат. Это звучит правильно?   -  person Vaughn Cato    schedule 16.12.2012
comment
@Mr.Vaughn: я попытался сделать это более понятным с помощью edit01   -  person TSL_    schedule 16.12.2012
comment
Вы могли бы сделать что-то подобное, но вам нужно было бы проверить тип данных для points, а затем вызвать drawCircles(img,Mat_‹U›(points),c1), где U является подходящим типом.   -  person Vaughn Cato    schedule 16.12.2012


Ответы (1)


Прежде всего: ваш дизайн кажется мне немного сломанным. Если «Точки» - это не что иное, как матрица 1xn, содержащая 2D-векторы, было бы более целесообразно использовать вместо этого вектор, например. std::vector<Point2f>.

Однако с небольшими изменениями в вашей попытке шаблонная версия должна работать:

template <typename T>
void drawCircles(InputArray _image, InputArray _points, Scalar color)
{
    Mat images = _image.getMat(), points = _points.getMat();
    CV_Assert(points.channels() == 2);

    for (int i = 0; i < points.cols; i++) {
        Vec<T,2>& v = points.at<Vec<T,2>>(0,i);

        Point2i p;
        p.x = cvRound(v[0]);
        p.y = cvRound(v[1]);

        circle(image, p, 5, color, 2, 8);
    }
}

// Usage:
drawCircles<float>(frame, Points, Scalar(255, 255, 255));
person Niko    schedule 16.12.2012
comment
@Mr.Niko: твой код работает. Тем не менее, я хочу решить свои вопросы. Могу ли я использовать const Mat_‹Vec‹Type, 2› › точки в заголовке/объявлении функции? Eclipse проверяет это как ошибку. Значит, мат нельзя передавать как тип шаблона?? - person TSL_; 16.12.2012
comment
Это также должно работать, если вы передаете объект этого типа, а не простой объект Mat. Можете ли вы уточнить ошибку, которую вы получаете? - person Niko; 17.12.2012
comment
Благодарю вас! это работает для меня сейчас. Это была просто моя глупая ошибка :D. Теперь я могу использовать как Mat_, так и InputArray - person TSL_; 17.12.2012