Ask Your Question

Particle analyze in binary image

asked 2017-12-22 03:14:20 -0500

refa gravatar image

Hi I have started Opencv recently. I have not found particle analyze function for counting, measuring of area, determination of center of mass . . . particles in a output binary like in Labview or Matlab. For example in enclosed file I want calculate bellow parameters for all of particle: 1- particle quantity 2-are of each particle 3- x, y position of center of mass for each particle 4- . . . Could you please help me about this function in OpenCV library?

image description

edit retag flag offensive close merge delete

4 answers

Sort by ยป oldest newest most voted

answered 2017-12-22 06:04:30 -0500

procton gravatar image

You can do the following:

  1. find contours on this image, which is already binarized with black background so it's ready for contouring (

  2. for each contour there are APIs to calculate perimeter, area and center of mass (moments)

  3. Of course you will easily be able to count contours

edit flag offensive delete link more

answered 2017-12-22 10:26:13 -0500

sjhalayka gravatar image

updated 2018-01-04 09:56:25 -0500

Here is a C++ and Python code to get the contours, particle count, particle area, and particle centres. It's an implementation of procton's algorithm, so make sure to mark their answer as correct. Let me know if you're a Python coder instead.

#include <opencv2/opencv.hpp>
using namespace cv;
#pragma comment(lib, "opencv_world331.lib")

#include <iostream>
#include <vector>
using namespace std;

int main(void)
    Mat frame = imread("particles.png", CV_LOAD_IMAGE_GRAYSCALE);

    if (frame.empty())
        cout << "Error loading image file" << endl;
        return -1;

    threshold(frame, frame, 127, 255, THRESH_BINARY);

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

    findContours(frame, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));

    vector<double> areas(contours.size());

    for (int i = 0; i < contours.size(); i++)
        areas[i] = contourArea(contours[i]);

    vector<Point2d> mass_centres(contours.size());

    for (int i = 0; i < contours.size(); i++)
        const Moments mu = moments(contours[i], false);
        mass_centres[i] = Point2d(mu.m10 / mu.m00, mu.m01 / mu.m00);

    cout << "Num particles: " << contours.size() << endl;

    for (int i = 0; i < contours.size(); i++)
        cout << "area " << (i + 1) << ": " << areas[i] << endl;

    for (int i = 0; i < contours.size(); i++)
        cout << "centre " << (i + 1) << ": " << mass_centres[i].x << " " << mass_centres[i].y << endl;

    return 0;

Here is the Python code:

import cv2
import numpy

frame = cv2.imread('blobs.png')

if frame is None:
    print('Error loading image')

frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
ret, frame = cv2.threshold(frame, 127, 255, cv2.THRESH_BINARY)

frame, contours, hierarchy = cv2.findContours(frame, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

areas = []

for i in range(0, len(contours)):

mass_centres_x = []
mass_centres_y = []

for i in range(0, len(contours)):
    M = cv2.moments(contours[i], 0)

print 'Num particles: ', len(contours)

for i in range(0, len(contours)):
    print 'Area', (i + 1), ':', areas[i]

for i in range(0, len(contours)):
    print 'Centre',(i + 1),':', mass_centres_x[i], mass_centres_y[i]    

cv2.imshow("Frame", frame)

edit flag offensive delete link more


can we please have the python code for this as well? Thank you

juarez717 gravatar imagejuarez717 ( 2018-01-03 10:23:22 -0500 )edit

I'll work on it tonight, and get back to you tomorrow with the code.

sjhalayka gravatar imagesjhalayka ( 2018-01-03 10:37:08 -0500 )edit

thank you very much!

juarez717 gravatar imagejuarez717 ( 2018-01-03 10:42:19 -0500 )edit

I had some spare time today, so I posted the Python code here for you. Check my updated answer.

sjhalayka gravatar imagesjhalayka ( 2018-01-03 11:19:00 -0500 )edit

if you can also incorporate the calculation of Nodularity of the particles, and the roundness it would be gladly appreciate it. Or recommended resources to look at for this. Thanks again.

juarez717 gravatar imagejuarez717 ( 2018-01-03 11:22:27 -0500 )edit

I'm not sure what you mean by nodularity. Also not sure how to calculate the roundness. Best of luck.

Please upvote my answer if you find it helpful. :)

sjhalayka gravatar imagesjhalayka ( 2018-01-03 11:25:05 -0500 )edit

thank you very much

juarez717 gravatar imagejuarez717 ( 2018-01-03 11:26:06 -0500 )edit

@sjhalayka Typo error remove semi-colon at the end areas.append(cv2.contourArea(contours[i])). And also add bracket for print......... print( 'Num particles: ', len(contours)). And more them too.

supra56 gravatar imagesupra56 ( 2018-01-03 20:33:44 -0500 )edit

@supra56 Thanks for the typo corrections... I'm using Python 2.7. I should upgrade to 3.

sjhalayka gravatar imagesjhalayka ( 2018-01-04 09:57:52 -0500 )edit

@juarez717 -- Can you please define nodularity to me?

sjhalayka gravatar imagesjhalayka ( 2018-01-05 18:44:22 -0500 )edit

answered 2017-12-22 21:52:58 -0500

Tetragramm gravatar image

As neat as contours are, you probably want to use connectedComponentsWithStats

You pass it the binary image and it returns the number of white spots. The stats it returns include width, height, X and Y centroid, and area. In other words, exactly what you want, in one function call.

edit flag offensive delete link more

answered 2018-01-05 00:24:06 -0500

refa gravatar image

Thanks a lot for your attention to my request and project

edit flag offensive delete link more


You're welcome. How about you up-vote some of the answers here that helped you.

sjhalayka gravatar imagesjhalayka ( 2018-01-05 17:19:57 -0500 )edit

Question Tools



Asked: 2017-12-22 03:14:20 -0500

Seen: 4,874 times

Last updated: Jan 05 '18