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')
exit()
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)):
areas.append(cv2.contourArea(contours[i]))
mass_centres_x = []
mass_centres_y = []
for i in range(0, len(contours)):
M = cv2.moments(contours[i], 0)
mass_centres_x.append(int(M['m10']/M['m00']))
mass_centres_y.append(int(M['m01']/M['m00']))
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)
cv2.waitKey(0)