2012-12-16 36 views
3

我有一些使用OpenCV Mat的例程。这是其中之一:是否有访问OpenCV元素的模板方法?

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的元素。但是,这是非常具体的。当矩阵的元素类型不同时,该功能无法工作。 在这种情况下可以编写排序模板函数吗?这与Mat的元素类型无关?

谢谢

Edit01:

如果它像

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

不过它不工作了: (

+0

这听起来像你要像'的Point2D roundedElement(垫,行,列)',它会检查什么类型的函数它是矩阵,使用适当的'at '这种类型的方法,然后返回四舍五入的结果。这听起来正确吗? –

+0

@ Mr.Vaughn:我试图用edit01 –

+0

来更清楚一些,你可以做这样的事情,但是你需要检查'points'的数据类型,然后调用drawCircles(img,Mat_ (points),c1 ),U是适当的类型。 –

回答

3

首先:您的设计似乎有点破碎给我。如果“点”不过是包含2D矢量的1×n矩阵,则用一个矢量代替它是更合适的。 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)); 
+0

@ Mr.Niko:你的代码有效。我仍然想解决我的问题。我可以在函数头/声明中使用“const Mat_>点”吗? Eclipse检查这是一个错误。所以Mat不能作为模板类型传递? –

+0

如果您传递该类型的对象而不是普通的“Mat”对象,那么该工作方式也应该如此。你能对你得到的错误更具体吗? – Niko

+0

谢谢!它现在适用于我。这只是我自己愚蠢的错误:D。现在我可以同时使用Mat_或InputArray –