zoukankan      html  css  js  c++  java
  • 图像的矩 图像的轮廓面积和长度

    1. 矩的概念

    图像识别的一个核心问题是图像的特征提取,简单描述即为用一组简单的数据(图像描述量)来描述整个图像,这组数据越简单越有代表性越好。良好的特征不受光线、噪点、几何形变的干扰。图像识别发展几十年,不断有新的特征提出,而图像不变矩就是其中一个。

    矩是概率与统计中的一个概念,是随机变量的一种数字特征。设XX为随机变量,cc为常数,kk为正整数。则量E[(xc)k]E[(x−c)k]称为XX关于cc点的kk阶矩。

    比较重要的有两种情况:

    1. c=0c=0。这时ak=E(Xk)ak=E(Xk)称为XX的kk阶原点矩

    2. c=E(X)c=E(X)。这时μk=E[(XEX)k]μk=E[(X−EX)k]称为XX的kk阶中心矩。

    一阶原点矩就是期望。一阶中心矩μ1=0μ1=0,二阶中心矩μ2μ2就是XX的方差Var(X)Var(X)。在统计学上,高于4阶的矩极少使用。μ3μ3可以去衡量分布是否有偏。μ4μ4可以去衡量分布(密度)在均值附近的陡峭程度如何。

    针对于一幅图像,我们把像素的坐标看成是一个二维随机变量(X,Y)(X,Y),那么一幅灰度图像可以用二维灰度密度函数来表示,因此可以用矩来描述灰度图像的特征。

    不变矩(Invariant Moments)是一处高度浓缩的图像特征,具有平移、灰度、尺度、旋转不变性。M.K.Hu在1961年首先提出了不变矩的概念。1979年M.R.Teague根据正交多项式理论提出了Zernike矩。下面主要介绍这两种矩特征的算法原理与实现。

    2. Hu矩

    一幅M×NM×N的数字图像f(i,j)f(i,j),其p+qp+q阶几何矩mpqmpq和中心矩μpqμpq为:

    mpq=i=1Mj=1Nipjqf(i,j)mpq=∑i=1M∑j=1Nipjqf(i,j)
     
    μpq=i=1Mj=1N(ii¯)p(jj¯)qf(i,j)μpq=∑i=1M∑j=1N(i−i¯)p(j−j¯)qf(i,j)

    其中f(i,j)f(i,j)为图像在坐标点(i,j)(i,j)处的灰度值。i¯=m10/m00,j¯=m01/m00i¯=m10/m00,j¯=m01/m00

    若将m00m00看作是图像的灰度质量,则(i¯,j¯)(i¯,j¯)为图像的质心坐标,那么中心矩μpaμpa反映的是图像灰度相对于其灰度质心的分布情况。可以用几何矩来表示中心矩,0~3阶中心矩与几何矩的关系如下:

    μ00=Mi=1Nj=1(ii¯)0(jj¯)0f(i,j)=m00μ00=∑i=1M∑j=1N(i−i¯)0(j−j¯)0f(i,j)=m00

    μ10=Mi=1Nj=1(ii¯)1(jj¯)0f(i,j)=0μ10=∑i=1M∑j=1N(i−i¯)1(j−j¯)0f(i,j)=0

    μ01=Mi=1Nj=1(ii¯)0(jj¯)1f(i,j)=0μ01=∑i=1M∑j=1N(i−i¯)0(j−j¯)1f(i,j)=0

    μ11=Mi=1Nj=1(ii¯)1(jj¯)1f(i,j)=m11y¯m10μ11=∑i=1M∑j=1N(i−i¯)1(j−j¯)1f(i,j)=m11−y¯m10

    μ20=Mi=1Nj=1(ii¯)2(jj¯)0f(i,j)=m20y¯m01μ20=∑i=1M∑j=1N(i−i¯)2(j−j¯)0f(i,j)=m20−y¯m01

    μ02=Mi=1Nj=1(ii¯)0(jj¯)2f(i,j)=m02y¯m01μ02=∑i=1M∑j=1N(i−i¯)0(j−j¯)2f(i,j)=m02−y¯m01

    μ30=Mi=1Nj=1(ii¯)3(jj¯)0f(i,j)=m302x¯m20+2x¯2m10μ30=∑i=1M∑j=1N(i−i¯)3(j−j¯)0f(i,j)=m30−2x¯m20+2x¯2m10

    μ12=Mi=1Nj=1(ii¯)1(jj¯)2f(i,j)=m122y¯m11x¯m02+2y¯2m10μ12=∑i=1M∑j=1N(i−i¯)1(j−j¯)2f(i,j)=m12−2y¯m11−x¯m02+2y¯2m10

    μ21=Mi=1Nj=1(ii¯)2(jj¯)1f(i,j)=m212x¯m11y¯m20+2x¯2m01μ21=∑i=1M∑j=1N(i−i¯)2(j−j¯)1f(i,j)=m21−2x¯m11−y¯m20+2x¯2m01

    μ03=Mi=1Nj=1(ii¯)0(jj¯)3f(i,j)=m032y¯m02+2y¯2m01μ03=∑i=1M∑j=1N(i−i¯)0(j−j¯)3f(i,j)=m03−2y¯m02+2y¯2m01

    为了消除图像比例变化带来的影响,定义规格化中心矩如下:

    ηpq=μpaμγ00,(γ=p+q2,p+q=2,3,)ηpq=μpaμ00γ,(γ=p+q2,p+q=2,3,…)

    利用二阶和三阶规格中心矩可以导出下面7个不变矩组(Φ1 Φ7)(Φ1 Φ7),它们在图像平移、旋转和比例变化时保持不变。

    Φ1=η20+η02Φ1=η20+η02

    Φ2=(η20η02)2+4η211Φ2=(η20−η02)2+4η112

    Φ3=(η203η12)2+3(η21η03)2Φ3=(η20−3η12)2+3(η21−η03)2

    Φ4=(η30+η12)2+(η21+η03)2Φ4=(η30+η12)2+(η21+η03)2

    Φ5=(η30+3η12)(η30+η12)[(η30+η12)23(η21+η03)2]+(3η21η03)(η21+η03)[3(η30+η12)2(η21+η03)2]Φ5=(η30+3η12)(η30+η12)[(η30+η12)2−3(η21+η03)2]+(3η21−η03)(η21+η03)[3(η30+η12)2−(η21+η03)2]

    Φ6=(η20η02)[(η30+η12)2(η21+η03)2]+4η11(η30+η12)(η21+η03)Φ6=(η20−η02)[(η30+η12)2−(η21+η03)2]+4η11(η30+η12)(η21+η03)

    Φ7=(3η21η03)(η30+η12)[(η30+η12)23(η21+η03)2]+]+(3η12η30)(η21+η03)[3(η30+η12)2(η21+η03)2]

    3. 利用OpenCV计算Hu矩

    opencv里对Hu矩的计算有直接的API,它分为了两个函数:moments()函数用于计算中心矩,HuMoments函数用于由中心矩计算Hu矩。

    Moments moments(InputArray array, bool binaryImage=false )

    参数说明

    • 输入参数:array是一幅单通道,8-bits的图像,或一个二维浮点数组(Point of Point2f)。binaryImage用来指示输出图像是否为一幅二值图像,如果是二值图像,则图像中所有非0像素看作为1进行计算。
    • 输出参数:moments是一个类

    4.contourArea()

    contour:是一个向量,二维点,可以是vector或Mat类型

    oriented:有默认值false,面向区域标识符,如果为true,该函数返回一个带符号的面积,其正负取决于轮廓的方向(顺时针还是逆时针)。根据这个特性可以根据面积的符号来确定轮廓的位置。如果是默认值false,则面积以绝对值的形式返回.

    该函数使用Green formula计算轮廓面积,返回面积和非零像素数量如果使用drawContours或fillPoly绘制轮廓,可能导致不同。

    5. arcLength()

     用于计算封闭轮廓的周长或曲线的长度

    curve:输入二维点集,可以是vector或Mat类型 
    closed:曲线是否封闭的标志位,true则封闭否则不封闭

     1 #include<opencv2/imgproc/imgproc.hpp>
     2 #include<opencv2/highgui/highgui.hpp>
     3 #include<iostream>
     4 
     5 using namespace cv;
     6 using namespace std;
     7 
     8 Mat src, grayImage;
     9 int Thresh = 100;
    10 int MaxThresh = 255;
    11 RNG rng(12345);
    12 Mat canny_output;
    13 vector<vector<Point>>contours;
    14 vector<Vec4i>hierarchy;
    15 
    16 void on_threshChange(int, void *);
    17  
    18 int main()
    19 {
    20     src = imread("D:/meinv.jpg");
    21 
    22     cvtColor(src, grayImage, COLOR_BGR2GRAY);
    23     blur(grayImage, grayImage, Size(3, 3));
    24 
    25     namedWindow("原图", CV_WINDOW_AUTOSIZE);
    26     imshow("原图", src);
    27 
    28     //创建滚动条并进行初始化
    29     createTrackbar("阈值", "原图", &Thresh, MaxThresh, on_threshChange);
    30     on_threshChange(0, 0);
    31     waitKey(0);
    32     return(0);
    33 }
    34 
    35 void on_threshChange(int, void*)
    36 {   
    37     //使用Canny检测边缘
    38     Canny(grayImage, canny_output, Thresh, Thresh * 2, 3);
    39     //找到轮廓
    40     findContours(canny_output, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));
    41     //计算矩
    42     vector<Moments>mu(contours.size());
    43     for (int i = 0; i < contours.size(); i++)
    44     {
    45         mu[i] = moments(contours[i], false);
    46     }
    47     //计算图像的质心
    48     vector<Point2f>mc(contours.size());
    49     for (int i = 0; i < contours.size(); i++)
    50     {
    51         mc[i] = Point2f(static_cast<float>(mu[i].m10 / mu[i].m00), static_cast<float>(mu[i].m01 / mu[i].m00));
    52     }
    53     //绘制轮廓
    54     Mat drawing = Mat::zeros(canny_output.size(), CV_8UC3);
    55     for (int i = 0; i < contours.size(); i++)
    56     {
    57         Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
    58         drawContours(drawing, contours, i, color, 2, 8, hierarchy, 0, Point());
    59         circle(drawing, mc[i], 4, color, -1, 8, 0);
    60     }
    61     //显示到窗口中
    62     namedWindow("轮廓图", WINDOW_AUTOSIZE);
    63     imshow("轮廓图", drawing);
    64 
    65     //用moments矩集计算轮廓面积并与opencv函数计算结果进行比较
    66     printf("	 Info: Area and Contour Length 
    ");
    67     for (int i = 0; i < contours.size(); i++)
    68     {
    69         printf("* Contour[%d] - Area(M_00)=%.2f-Area OpenCV:%.2f - Length:%.2f
    ", i, mu[i].m00, contourArea(contours[i]), arcLength(contours[i], true));
    70         Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
    71         drawContours(drawing, contours, i, color, 2, 8, hierarchy, 0, Point());
    72         circle(drawing, mc[i], 4, color, -1, 8, 0);
    73     }
    74 }

    效果图:

    本文参考自:https://blog.csdn.net/keith_bb/article/details/70197104

          http://www.cnblogs.com/ronny/p/3985810.html

  • 相关阅读:
    Hihocoder 1275 扫地机器人 计算几何
    CodeForces 771C Bear and Tree Jumps 树形DP
    CodeForces 778D Parquet Re-laying 构造
    CodeForces 785E Anton and Permutation 分块
    CodeForces 785D Anton and School
    CodeForces 785C Anton and Fairy Tale 二分
    Hexo Next 接入 google AdSense 广告
    如何统计 Hexo 网站的访问地区和IP
    Design and Implementation of Global Path Planning System for Unmanned Surface Vehicle among Multiple Task Points
    通过ODBC接口访问人大金仓数据库
  • 原文地址:https://www.cnblogs.com/carlber/p/9726347.html
Copyright © 2011-2022 走看看