目录
1--图形矩的概念
2--OpenCV API
3--代码实例
① 几何矩:计算公式如下所示,其中(i + j)的和表示矩的阶数,当(i + j) = 2时称为二阶几何矩;
② 中心距:计算公式如下所示,其中表示中心质点坐标;
③ 中心归一化矩:计算公式如下所示;
可以利用几何矩计算图像轮廓的中心,即质心位置,计算公式如下:
cv::Moments cv::moments(cv::InputArray array, bool binaryImage = false)
在利用 Opencv 计算图形矩时,通常的作法是对源图像进行提取轮廓,对提取的轮廓分别计算图形矩;
通过 Moments = cv::moments()计算图像矩,通过Moments.m00调用相应阶数的几何矩,具体可参考博客1;
# include
# include
# include
int threshold_value = 100;
int threshold_max = 255;
cv::Mat src;
cv::Mat gray;
cv::RNG rng(12345);
void Demo_moments(int, void*){
cv::Mat Canny_output;
std::vector> contours;
std::vector hierachy;
cv::Canny(src, Canny_output, threshold_value, threshold_value*2, 3, false);
cv::findContours(Canny_output, contours, hierachy, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE, cv::Point(0, 0));
std::vector contours_moments(contours.size());
std::vector ccs(contours.size());
for(size_t i = 0; i < contours.size(); i++){
contours_moments[i] = cv::moments(contours[i]); // 为每一个轮廓计算矩
ccs[i] = cv::Point(static_cast(contours_moments[i].m10 / contours_moments[i].m00), // 计算图像中心
static_cast(contours_moments[i].m01 / contours_moments[i].m00));
}
cv::Mat drawImg;
src.copyTo(drawImg);
for(size_t i = 0; i < contours.size(); i++){
cv::Scalar color = cv::Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255)); // 随机生成颜色
// 输出每一个轮廓的中心坐标
printf("center point x : %.2f y : %.2f \n", ccs[i].x, ccs[i].y);
// 计算每一个轮廓的面积和弧长
printf("contours %d area : %.2f arc length : %2f\n", i, cv::contourArea(contours[i]), cv::arcLength(contours[i], true));
cv::drawContours(drawImg, contours, i, color, 2, 8, hierachy, 0, cv::Point(0, 0));
cv::circle(drawImg, ccs[i], 2, color, 2, 8);
}
cv::imshow("output", drawImg);
}
int main(int argc, char** argv){
src = cv::imread("C:/Users/Liujinfu/Desktop/opencv_bilibili/test0101.jpg");
if (src.empty()){
printf("could not load image..\n");
return -1;
}
cv::imshow("input", src);
cv::cvtColor(src, gray, cv::COLOR_BGR2GRAY);
cv::GaussianBlur(gray, gray, cv::Size(3, 3), 0, 0);
cv::namedWindow("output");
cv::createTrackbar("Threshold", "output", &threshold_value, threshold_max, Demo_moments);
Demo_moments(0, 0);
cv::waitKey(0);
return 0;
}
上图中,绿色点即为对应轮廓的质心位置。