Calculating moments of an image

Moments moments(InputArray array, bool binaryImage=false )

Parameters:
  • array – Raster image (single-channel, 8-bit or floating-point 2D array) or an array ( 1xN or Nx1 ) of 2D points (Point or Point2f ).
  • binaryImage – If it is true, all non-zero image pixels are treated as 1’s. The parameter is used for images only.
  • moments – Output moments.
The function computes moments, up to the 3rd order, of a vector shape or a rasterized shape. The results are returned in the structure Moments defined as:
class Moments
{
public:
    Moments();
    Moments(double m00, double m10, double m01, double m20, double m11,
            double m02, double m30, double m21, double m12, double m03 );
    Moments( const CvMoments& moments );
    operator CvMoments() const;

    // spatial moments
    double  m00, m10, m01, m20, m11, m02, m30, m21, m12, m03;
    // central moments
    double  mu20, mu11, mu02, mu30, mu21, mu12, mu03;
    // central normalized moments
    double  nu20, nu11, nu02, nu30, nu21, nu12, nu03;
}
In case of a raster image, the spatial moments Moments:: mji are computed as:
\texttt{m} _{ji}= \sum _{x,y}  \left ( \texttt{array} (x,y)  \cdot x^j  \cdot y^i \right )
The central moments \texttt{Moments::mu}_{ji} are computed as:
\texttt{mu} _{ji}= \sum _{x,y}  \left ( \texttt{array} (x,y)  \cdot (x -  \bar{x} )^j  \cdot (y -  \bar{y} )^i \right )
where (\bar{x}, \bar{y}) is the mass center:
\bar{x} = \frac{\texttt{m}_{10}}{\texttt{m}_{00}} , \; \bar{y} = \frac{\texttt{m}_{01}}{\texttt{m}_{00}}
The normalized central moments Moments:: nuji are computed as:
\texttt{nu} _{ji}= \frac{\texttt{mu}_{ji}}{\texttt{m}_{00}^{(i+j)/2+1}} .
The code provided below is slight modification of code given in OpenCV documentation.

Steps:

  1. Load image
  2. Convert to gray-scale.
  3. Remove noise by blurring with a Gaussian filter
  4. Detect edges using canny
  5. Find contours (findContours)
  6. Get the moments(Moments)
  7. Draw contours 
  8. Calculate the area with the moments 00 and compare with the result of the OpenCV function

Functions:

 

Example:

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

using namespace cv;
using namespace std;


RNG rng(12345);

void find_moments( Mat src );

int main( )
{
    /// Load source image, convert it to gray and blur it
    Mat src, gray;;
    src = imread("shapes.jpg", 1 );
    cvtColor( src, gray, CV_BGR2GRAY );
    blur( gray, gray, Size(3,3) );

    namedWindow( "Source", CV_WINDOW_AUTOSIZE );
    imshow( "Source", src );

    find_moments( gray );

    waitKey(0);
    return(0);
}

void find_moments( Mat gray )
{
    Mat canny_output;
    vector<vector<Point> > contours;
    vector<Vec4i> hierarchy;

    /// Detect edges using canny
    Canny( gray, canny_output, 50, 150, 3 );
    /// Find contours
    findContours( canny_output, contours, hierarchy, CV_RETR_TREE, 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( canny_output.size(), CV_8UC3 );
    for( int i = 0; i< contours.size(); i++ )
    {
        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 );
    }

    /// Show in a window
    namedWindow( "Contours", CV_WINDOW_AUTOSIZE );
    imshow( "Contours", drawing );

    /// Calculate the area with the moments 00 and compare with the result of the OpenCV function
    printf("\t Info: Area and Contour Length \n");
    for( int i = 0; i< contours.size(); i++ )
        printf(" * Contour[%d] - Area (M_00) = %.2f - Area OpenCV: %.2f - Length: %.2f \n", i, mu[i].m00, contourArea(contours[i]), arcLength( contours[i], true ) );

}
-------------

9 comments:

  1. This comment has been removed by a blog administrator.

    ReplyDelete
  2. Programming is really hard to understand. But thanks to your article. It's really a great help for me especially that I'm a beginners for this lessons. Keep it up. And please post more examples about this.


    Bob
    www.gofastek.com

    ReplyDelete
  3. Great job, but why don't you let us see the image you've used as an input and the output (both image and text)? I'd be interested in those to see if it's worth to try or not / in which cases could it be useful, etc. Anyway, thanks for the tutorial :)

    ReplyDelete
  4. You should provide Output in your article. Thanks

    ReplyDelete
  5. can you provide this in python

    ReplyDelete
  6. How to counting pixel in contour? Thank

    ReplyDelete
  7. Compre documentos en línea, documentos originales y registrados.
    Acerca de Permisodeespana, algunos dicen que somos los solucionadores de problemas, mientras que otros se refieren a nosotros como vendedores de soluciones. Contamos con cientos de clientes satisfechos a nivel mundial. Hacemos documentos falsos autorizados y aprobados como Permiso de Residencia Español, DNI, Pasaporte Español y Licencia de Conducir Española. Somos los fabricantes y proveedores de primer nivel de estos documentos, reconocidos a nivel mundial.

    Comprar permiso de residencia,
    permiso de residenciareal y falso en línea,
    Compre licencia de conducir en línea,
    Compre una licencia de conducir española falsa en línea,
    Comprar tarjeta de identificación,
    Licencia de conducir real y falsa,
    Compre pasaporte real en línea,

    Visit Here fpr more information. :- https://permisodeespana.com/licencia-de-conducir-espanola/
    Address: 56 Guild Street, London, EC4A 3WU (UK)
    Email: contact@permisodeespana.com
    WhatsApp: +443455280186

    ReplyDelete
  8. أسباب ومخاطر تسرب المياه اولا: سبب تسرب المياه وهناك اسباب عديدة لتسرب المياه ومنها مشاكل مواسير المياه الداخلية. تخصص في المنزل نفسه ، أو تشققات وكسور في السياج فوقك ، لذلك سوف تتأثر به. ثانيًا: الضرر الناتج عن تسرب المياه في جميع أنواع التسربات يختلف التلف من نوع إلى آخر ولا يمكن تركه وفي حال تركه فترة طويلة ستجلب لك الكثير من المشاكل والسبب هو أن تسرب المياه يتفاعل مع مواد البناء ويلعب دوراً. البقع الموجودة على الحائط يكون لون هذه البقع اسود او اخضر حسب زمن التسرب لان الماء يتفاعل مع الاسمنت دهان الجدران وتسبب البقع والعفن مما يجعل الجدران هشة ولهذا تتعرض الجدران للتشقق وتحطم

    شركة العطار للخدمات المنزلية

    ReplyDelete
  9. إن ترميم المنزل من الأمور المهمة التي يجب القيام بها ، ولإعادة المنزل إلى حالته السابقة ، فإنه يتأثر بالعوامل البيئية المختلفة ، مثل البرد الشديد أو البرد الشديد ، والأمطار وتسرب المياه ، وما إلى ذلك ، والتي تغيير مشهد وطبيعة المنزل .. وهذا أجمل من ترك المنزل إلى مكان حديث. تصبح عملية الترميم معالجة للمنزل ، تقضي على التلف والشقوق الناتجة عن أسباب طبيعية وغير طبيعية للمنزل ، حتى ضياع قطعة كبيرة من الجمال. الغرض من الترميم هو الادخار لمدة عام واحد فيما يتعلق بهيكل المبنى وحالة المرض الذي سببته المؤسسة القضائية على المبنى.

    شركة منزل الشموخ لخدمات المنزل

    ReplyDelete