I have some routines working with OpenCV Mat. This is one of them:

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

which is used to draw circles on an image at given points.

I'm going fine with accessing Mat's element by matrixA.at(i,j). However, this is so specific. When the matrix's element type differs, the function cannot work. Is it possible to write sort-of template function in this case?? which is independent of Mat's element type??

Thank you

Edit01:

if it's something like

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

then it would be perfect. But I've done searching with OpenCV docs and don't think this is supported with OpenCV MAT. Or am I missing some points?

Edit02: This is my try:

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

and I call it with:

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

where Points is:

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

Still it does not work out :(

有帮助吗?

解决方案

First of all: Your design seems a bit broken to me. If "Points" is nothing but a 1xn matrix containing 2D vectors, it would be more appropriate to use a vector instead, e.g. std::vector<Point2f>.

However, with minor changes to your attempt the templated version should actually work:

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));
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top