Aye*_*han 4 opencv image-processing visual-c++
是否有一些好的和更好的方法来找到opencv中的轮廓质心,而不使用内置函数?
虽然Sonaten的答案是完全正确的,但有一种简单的方法:使用专用的opencv函数:moment()
它不仅会返回质心,还会返回有关您的形状的更多统计信息.您可以发送轮廓或光栅形状(二进制图像),最适合您的需要.
编辑
示例(修改)来自"学习OpenCV",由gary bradsky撰写
CvMoments moments;
double M00, M01, M10;
cvMoments(contour,&moments);
M00 = cvGetSpatialMoment(&moments,0,0);
M10 = cvGetSpatialMoment(&moments,1,0);
M01 = cvGetSpatialMoment(&moments,0,1);
centers[i].x = (int)(M10/M00);
centers[i].y = (int)(M01/M00);
Run Code Online (Sandbox Code Playgroud)
您在当前代码段中得到的当然是边界框的质心。
“如果你有一堆点(二维向量),你应该能够通过平均这些点来获得质心:创建一个点将所有其他点的位置添加到其中,然后将该点的分量与累积位置除以总点数。” ——乔治·普罗芬扎提到
这确实是二维空间中任何给定物体的精确质心的正确方法。
在维基百科上,我们有一些寻找对象质心的通用形式。 http://en.wikipedia.org/wiki/Centroid
就我个人而言,我会问自己我需要从这个计划中得到什么。我想要一个彻底但性能要求较高的操作,还是想要做一些近似?我什至可以找到一个 OpenCV 函数来正确且有效地处理这个问题。
没有有效的示例,因此我在一个简单的 5 像素示例上以伪代码形式编写了一个完整的方法。
x_centroid = (pixel1_x + pixel2_x + pixel3_x + pixel4_x +pixel5_x)/5
y_centroid = (pixel1_y + pixel2_y + pixel3_y + pixel4_y +pixel5_y)/5
centroidPoint(x_centroid, y_centroid)
Run Code Online (Sandbox Code Playgroud)
循环 x 像素
Loop j times *sample (for (int i=0, i < j, i++))*
{
x_centroid = pixel[j]_x + x_centroid
y_centroid = pixel[j]_x + x_centroid
}
x_centroid = x_centroid/j
y_centroid = y_centroid/j
centroidPoint(x_centroid, y_centroid)
Run Code Online (Sandbox Code Playgroud)
本质上,您拥有以下类型的矢量轮廓
vector<vector<point>>
Run Code Online (Sandbox Code Playgroud)
在 OpenCV 2.3 中。我相信你在早期版本中有类似的东西,你应该能够使用这个“双向量”的第一个索引来遍历图片上的每个斑点,并遍历内部向量中的每个像素。
注意:您已将问题标记为 c++ Visual。我建议您在 OpenCV 2.3 中使用 c++ 语法而不是 c。使用 2.3 的第一个也是很好的理由是它更基于类,在本例中这意味着 Mat 类(而不是 IplImage)确实会泄漏内存。人们不必整天都编写销毁命令:)
我希望这可以帮助您解决问题。享受。