Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to count objects in image using python?

I am trying to count the number of drops in this image and the coverage percentage of the area covered by those drops. I tried to convert this image into black and white, but the center color of those drops seems too similar to the background. So I only got something like the second picture. Is there any way to solve this problem or any better ideas? Thanks a lot.

source image

converted image

like image 722
JIAHAO HUANG Avatar asked Jul 27 '16 17:07

JIAHAO HUANG


People also ask

How do I count items in a picture?

AI-enabled apps like CountThings from Photos, Object Counter By Camera, and iscanner count items for you automatically. All you need to do is to take the picture of items you want to count with your phone. The items in the picture will automatically be counted.

How do you find the object of an image in Python?

To actually detect objects, you need to call the detectObjectsFromImage() method. Pass the file path of your input image to the “input_image” parameter and the path to the output image (this image will contain the detected object, but it doesn't exist yet), to the “output_image_path” parameter.

How do I count images in a directory in Python?

Getting a count of files of a directory is easy as pie! Use the listdir() and isfile() functions of an os module to count the number of files of a directory.


2 Answers

You can fill the holes of your binary image using scipy.ndimage.binary_fill_holes. I also recommend using an automatic thresholding method such as Otsu's (avaible in scikit-image).enter image description here

from skimage import io, filters
from scipy import ndimage
import matplotlib.pyplot as plt

im = io.imread('ba3g0.jpg', as_grey=True)
val = filters.threshold_otsu(im)
drops = ndimage.binary_fill_holes(im < val)
plt.imshow(drops, cmap='gray')
plt.show()

For the number of drops you can use another function of scikit-image

from skimage import measure
labels = measure.label(drops)
print(labels.max())

And for the coverage

print('coverage is %f' %(drops.mean()))
like image 143
Emmanuelle Gouillart Avatar answered Oct 24 '22 06:10

Emmanuelle Gouillart


I used the following code to detect the number of contours in the image using OpenCV and python.

import cv2
import numpy as np
img = cv2.imread('ba3g0.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(gray,127,255,1)
contours,h = cv2.findContours(thresh,1,2)
for cnt in contours:
    cv2.drawContours(img,[cnt],0,(0,0,255),1)

Result For further removing the contours inside another contour, you need to iterate over the entire list and compare and remove the internal contours. After that, the size of "contours" will give you the count

like image 39
Saurav Avatar answered Oct 24 '22 04:10

Saurav