OpenCV30---图像矩(图像测量)

三十、图像矩(Image Moments)

1、矩的概念介绍

  • 几何矩
    • 几何矩
    • 中心矩
    • 中心归一化矩
      在这里插入图片描述
  • 轮廓中心 C e n t e r ( x 0 , y 0 ) Center(x_0, y_0) Center(x0,y0)
    x 0 x_0 x0 = m 10 m   00   \frac{m10}{m~00~} m 00 m10
    y 0 y_0 y0 = m 01 m   00   \frac{m01}{m~00~} m 00 m01

2、API介绍与使用cv::moments计算生成数据

  • 得到的结果是存储了几何矩、中心距、中心归一化矩的结果
    在这里插入图片描述
moments(
InputArray array,//输入数据
bool binaryImage=false//是否为二值图像
)
  • 得到轮廓的面积
contourArea(
InputArray contour,//输入轮廓数据
bool oriented//默认false,返回绝对值
)
  • 得到曲线的弧长
arcLength(
InputArray curve,//输入曲线数据
bool closed//是否是封闭曲线
)

3、步骤

  • 转灰度cvtColor
  • 提取图像边缘Canny
  • 发现轮廓findContours
  • 计算每个轮廓对象的矩moments
  • 计算每个对象的中心、弧长、面积contourArea arcLength

示例代码:

#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>

using namespace cv;
using namespace std;

int threshold_value = 80;
int threshold_max = 255;
RNG rng(12345);
void Threshold_Callback(int, void*);
char output_win[] = "rectangle demo";
Mat src, dst, src_gray;

int main (int argc, char** argv) {    
    src = imread("添加图片路径");
    if (!src.data) {
  	cout << "could not load image..." << endl;
  	return -1;
    }
    imshow("input image", src);
    namedWindow(output_win, WINDOW_AUTOSIZE);

    cvtColor(src, src_gray, COLOR_BGR2GRAY);
    GaussianBlur(src_gray, src_gray, Size(3, 3),0,0);
    
    createTrackbar("Threshold Value:", output_win, &threshold_value, threshold_max, Threshold_Callback);
    Threshold_Callback(0, 0);
    
    waitKey(0);
    return 0;
}

void Threshold_Callback(int, void*) {
    Mat canny_output;
    vector<vector<Point>> contours;
    vector<Vec4i> hierachy;
    
    Canny(src_gray, canny_output, threshold_value, threshold_value * 2, 3, false);
    findContours(canny_output, contours, hierachy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));
    
    vector<Moments> contours_moments(contours.size());
    vector<Point2f> ccs(contours.size());
    for (size_t i = 0; i < contours.size(); i++) {
  	contours_moments[i] = moments(contours[i]);//获得第i个轮廓的矩
  	ccs[i] = Point(static_cast<float>contours_moments[i].m10 / contours_moments[i].m00), static_cast<float>(contours_moments[i].m01 / contours_moments[i].m00));//计算轮廓的中心坐标
    }

    src.copyTo(dst);
    for (size_t i = 0; i < contours.size(); i++) {
  	if (contours[i].size() < 100) {//设置一个阈值,当轮廓点数大于某个阈值时,才视为轮廓
   	    continue;
        }
        Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
        printf("center point x : %.2f y : %.2f", ccs[i].x, ccs[i].y);
        printf("contours %d area : %.2f arc length : %.2f\n", i, contourArea(contours[i]), arcLength(contours[i], true));//计算轮廓的面积和弧长
        drawContours(dst, contours, i, color, 2, 8, hierachy, 0, Point(0, 0));
        circle(dst, ccs[i], 2, color, 2, 8);
        char buffer[20];
        sprintf_s(buffer, "(%.2f,%.2f)", ccs[i].y, ccs[i].x);
  	putText(dst, buffer, Point(ccs[i].x, ccs[i].y), FONT_HERSHEY_COMPLEX, 0.5, Scalar(0, 0, 255), 1, 8);//绘制圆心坐标   
    }

    imshow(output_win, dst);
    return ;
}

输出结果显示:

在这里插入图片描述
分析:根据图像矩,可以获得图像轮廓的中心坐标以及其对应的轮廓面积及弧长。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值