图像矩 Image Moments

什么叫图像矩

主要指几何矩,还存在复数矩

几何矩像素值与像素位置积的求和

中心距

中心归一化矩

矩一般对二值图像提取的轮廓再进行特征提取

 

图像的中心位置,使用图像的一阶矩除零阶矩m10和m01表示1阶矩,0+1=1,m00表示0阶矩

x0=m10/m00,y0=m01/m00

矩存储在moments数据结构中

 

怎样根据图像轮廓计算矩

提取图像边缘

发现轮廓

计算每个轮廓对象的矩

计算每个对象的中心、弧长和面积

 

API

moments()//算出所有前三阶的矩

InputArray array 输入数据

bool binaryImage 是否为二值图像

 

contourArea()//求出面积

InputArray contour 输入轮廓数据

bool oriented 默认为false,返回绝对值

 

arclength()//画曲线

InputArray curve 输入曲线数据

bool closed 是否为封闭曲线

 

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

using namespace std;
using namespace cv;

Mat gray_pic;
Mat src, dst;
int threshold_value = 80;
int threshold_max = 255;
void Demo_Moments(int, void*);
int main(int argc, char**argv)
{
    src = imread("2.jpg");
    namedWindow("output window", CV_WINDOW_AUTOSIZE);
    imshow("input window", src);
    cvtColor(src, gray_pic, COLOR_BGR2GRAY);
    //blur(gray_pic, gray_pic, Size(3, 3), Point(-1, -1));
    GaussianBlur(gray_pic, gray_pic, Size(3, 3), 0, 0);
    createTrackbar("Threshold value", "output window", &threshold_value, threshold_max, Demo_Moments);
    Demo_Moments(0, 0);
    waitKey(0);
    return 0;
}

void Demo_Moments(int, void*)
{
    //Mat binary_output;
    Mat canny_output;
    vector<vector<Point>> contours;
    vector<Vec4i>hierachy;
    //threshold(gray_pic, binary_output, threshold_value, threshold_max, THRESH_BINARY);
    Canny(gray_pic, canny_output, threshold_value, threshold_value * 2, 3, false);
    findContours(canny_output, contours, hierachy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0,0));
    imshow("binray", canny_output);

    vector<Moments> contours_moments(contours.size());
    /*
    vector<vector<Point>> contours_ploy(points.size());
    vector<Rect> ploy_Rect(points.size());//矩形
    vector<Point2f>ccs(points.size());//圆心
    vector<float>radius(points.size());//半径

    vector<RotatedRect> minRects(points.size());//旋转矩形
    vector<RotatedRect> myellipse(points.size());//旋转椭圆
    */
    vector<Point2f> ccs(contours.size());
    for (size_t i = 0; i < contours.size(); ++i)
    {
        contours_moments[i] = moments(contours[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 t = 0; t < contours.size(); ++t)
    {
        //筛选掉小轮廓
        if (contours[t].size() < 50)
        {
            continue;
        }
        cout << "center point x: " << ccs[t].x << " y:" << ccs[t].y << endl;
        cout << "contours " << t << " area " << contourArea(contours[t]) << " arc length " << arcLength(contours[t],true) << endl;
        
        //绘制中心点
        drawContours(src, contours, t, Scalar(0, 255, 0), 2, 8, hierachy, 0, Point(0, 0));

        circle(src, ccs[t], 1, Scalar(0, 0, 255), 1, 8);
    }

    //imshow("output img", dst);
    imshow("output window", src);
    
}

 

 

 

 

 

posted @ 2020-07-22 22:56  Wangtn  阅读(428)  评论(0编辑  收藏  举报