计算点向量的平均值

10

我在OpenCV中有一个二维点的向量

std::vector<cv::Point2f> points;

我想要计算points中x和y坐标的平均值。类似于:

cv::Point2f mean_point; //will contain mean values for x and y coordinates
mean_point = some_function(points); 

在Matlab中这很简单。但我不确定是否可以利用一些高级OpenCV函数来完成相同的任务。有什么建议吗?


为什么不使用for循环? - Panzercrisis
1
我可以使用for循环。但是我想知道在OpenCV或std库中是否有高级函数可以完成相同的任务。 - Alexey
4个回答

15
< p > InputArray 在这里表现得很好。你可以直接调用。

cv::Mat mean_;
cv::reduce(points, mean_, 01, CV_REDUCE_AVG);
// convert from Mat to Point - there may be even a simpler conversion, 
// but I do not know about it.
cv::Point2f mean(mean_.at<float>(0,0), mean_.at<float>(0,1)); 

详情:

在新版的 OpenCV 中,引入了 InputArray 数据类型。这样一来,可以将矩阵(cv::Mat)或向量作为参数发送到 OpenCV 函数中。一个 vector<Vec3f> 将被解释为一个三通道的浮点矩阵,具有一行和列数等于向量大小的数量。由于没有复制数据,这种透明转换非常快速。

优点是您可以使用适合您的应用程序的任何数据类型,同时仍然可以使用 OpenCV 函数轻松进行数学运算。


谢谢!然而,使用cv::Point2f mean(mean_(0), mean_(1));将Mat转换为Point并没有起作用。 - Alexey
这一行代码应该是:cv::Point2f mean(mean_.at<float>(0), mean_.at<float>(1)); - Sam
测试过,它可以工作。双重检查cv::reduce(...)参数 - 应为cv::reduce(points, mean_, CV_REDUCE_AVG, 1);,谢谢。 - Alexey
1
也许定义已经改变了,但目前reduce是void reduce(InputArray src, OutputArray dst, int dim, int rtype, int dtype=-1 ) http://docs.opencv.org/modules/core/doc/operations_on_arrays.html#reduce - rtype在dim之后,所以应该是cv::reduce(points, mean_, 1, CV_REDUCE_AVG); 我认为还需要一些其他的更改才能使其正常运行,我会跟进的。 - Lucas Walter
将Mat转换为Point的更简单方法 - ezekiel

11

由于OpenCV的Point_已经定义了operator+,因此这应该很简单。首先我们对值进行求和:

cv::Point2f zero(0.0f, 0.0f);

cv::Point2f sum  = std::accumulate(points.begin(), points.end(), zero);

然后我们进行除法以获得平均值:

Point2f mean_point(sum.x / points.size(), sum.y / points.size());

...或者我们可以使用 Point_operator*

Point2f mean_point(sum * (1.0f / points.size()));

很不幸,至少在我看来,Point_没有定义 operator /,因此我们需要乘以其逆元素而不是除以其大小。


6

您可以使用STL的std::accumulate函数进行如下操作:

cv::Point2f sum = std::accumulate(
    points.begin(), points.end(), // Run from begin to end
    cv::Point2f(0.0f,0.0f),       // Initialize with a zero point
    std::plus<cv::Point2f>()      // Use addition for each point (default)
);
cv::Point2f mean = sum / points.size(); // Divide by count to get mean

看起来像是平均值,而不是均值。 - Boris Mocialov
3
区别在哪里?"Average" 是 "arithmetic mean" 的同义词。 - smocking

0

把它们全部加起来,然后除以总点数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接