Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

What does HuMoments tell me?

Hello,

I would like to compare two objects whether they are similar. So I read a lot about moments and HuMoments, but things are still not clear.

What do the seven Hu invariants say about the object? I read hu[0] is about length/area of the contour but what about the rest?

Also, the invariants are very very small numbers. Is this normal, or am I doing something wrong? How could I compare such small values?

Here, I have prepared an image where the length of the square and circle; and the area of the triangle and rectangle is the same. And indeed, hu[0] seems to be same.

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>

using namespace cv;
using namespace std;

Mat src; Mat srcGray;
RNG rng(12345);

int main()
{
    // Load source image and convert it to gray
    src = imread("source3.png", 1);

    // Convert image to gray and blur it
    cvtColor(src, srcGray, CV_BGR2GRAY);
    blur(srcGray, srcGray, Size(3, 3));

    Mat srcThresh;
    double otsu;

    otsu = threshold(srcGray, srcThresh, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);

    Mat cannyOut;
    Canny(srcGray, cannyOut, otsu, otsu * 1 / 2, 3, 1);

    // Find contours
    vector<vector<Point> > contours;
    vector<Vec4i> hierarchy;

    findContours(cannyOut, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));

    // Get the moments
    vector<Moments> mu(contours.size());
    for (int i = 0; i < contours.size(); i++)
    {
        mu[i] = moments(contours[i], false);
    }

    //  Get the mass centers:
    vector<Point2f> mc(contours.size());
    for (int i = 0; i < contours.size(); i++)
    {
        mc[i] = Point2f(mu[i].m10 / mu[i].m00, mu[i].m01 / mu[i].m00);
    }

    // Draw contours
    Mat drawing = Mat::zeros(cannyOut.size(), CV_8UC3);
    string sObjectNumber;          // string which will contain the result
    ostringstream sContourNumber;   // stream used for the conversion

    for (int i = 0; i< contours.size(); i++)
    {
        sContourNumber << i;
        sObjectNumber = sContourNumber.str();   // Convert int to string
        Point pCoordinates(mc[i].x + 3, mc[i].y - 3);   // Text's coordinates (A little bit off from mass center)
        Scalar color = Scalar(rng.uniform(0, 255), rng.uniform(0, 255), rng.uniform(0, 255));
        drawContours(drawing, contours, i, color, 2, 8, hierarchy, 0, Point());
        circle(drawing, mc[i], 4, color, -1, 8, 0);     // Draw mass center
        putText(drawing, sObjectNumber, pCoordinates, CV_FONT_HERSHEY_COMPLEX, 1, color, 2, 8); // Write object number
        sContourNumber.str("");     // Clear string
        sContourNumber.clear();     // Clear any error flags
    }

    double hu[7];
    for (int i = 0; i < contours.size(); i++)
    {
        cout << "Contour: " << i << " Area: " << contourArea(contours[i]) << " Length: " << arcLength(contours[i], true) << "\n";

        for (int j = 0; j < 7; j++)
        {
            HuMoments(mu[i], hu);
            cout << "Contour: " << i << " Hu: " << j << " Result: " << hu[j] << "\n";
        }
        cout << "\n";
    }

    imshow("Contours", drawing);

    waitKey(0);
    return(0);
}

Source image:

image description

Contours with mass center: image description

Console output:

Contour: 0 Area: 67074 Length: 1033.66
Contour: 0 Hu: 0 Result: 0.16665
Contour: 0 Hu: 1 Result: 5.22355e-011
Contour: 0 Hu: 2 Result: 4.22817e-010
Contour: 0 Hu: 3 Result: 4.4612e-011
Contour: 0 Hu: 4 Result: 6.12709e-021
Contour: 0 Hu: 5 Result: -3.2243e-016
Contour: 0 Hu: 6 Result: 1.94626e-029

Contour: 1 Area: 85407 Length: 1096.71
Contour: 1 Hu: 0 Result: 0.15916
Contour: 1 Hu: 1 Result: 1.05427e-008
Contour: 1 Hu: 2 Result: 5.92319e-008
Contour: 1 Hu: 3 Result: 1.91125e-014
Contour: 1 Hu: 4 Result: 2.98247e-025
Contour: 1 Hu: 5 Result: 1.03978e-018
Contour: 1 Hu: 6 Result: 5.69718e-025

Contour: 2 Area: 43494 Length: 988.632
Contour: 2 Hu: 0 Result: 0.198937
Contour: 2 Hu: 1 Result: 0.00266253
Contour: 2 Hu: 2 Result: 0.00473049
Contour: 2 Hu: 3 Result: 6.33451e-005
Contour: 2 Hu: 4 Result: -3.46696e-008
Contour: 2 Hu: 5 Result: -3.2684e-006
Contour: 2 Hu: 6 Result: -6.353e-010

Contour: 3 Area: 43193 Length: 873.657
Contour: 3 Hu: 0 Result: 0.203371
Contour: 3 Hu: 1 Result: 0.0135906
Contour: 3 Hu: 2 Result: 1.23219e-009
Contour: 3 Hu: 3 Result: 1.29646e-010
Contour: 3 Hu: 4 Result: 1.34589e-020
Contour: 3 Hu: 5 Result: -9.37756e-012
Contour: 3 Hu: 6 Result: -5.00391e-020