Search code examples
pythonopencvimage-processingscikit-image

How to find the average diameter of the drops, which are superimposed on a strip of size 260 mm x 6.2 mm using image processing?


How to find the average diameter of the drops in an image. The drops on the image are raindrops, and the strip on which drops are superimposed has a size of 260 mm x 6.2 mm. This strip length and breadth could be considered a reference (perspective) size and can be used to measure the drop diameter or length of the x and y axes in mm. Also, how to label each drop with its diameter?

image

image = cv2.imread("1.png")
gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
# create a binary thresholded image
_, binary = cv2.threshold(gray, 225, 255, cv2.THRESH_BINARY_INV)
# show it

# find the contours from the thresholded image
contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# draw all contours

for contour in contours:
    if (cv2.contourArea(contour) < 3000) & (cv2.contourArea(contour) > 4):
        image = cv2.drawContours(image, contours, -1, (1, 1, 1), 1)

        circles = image.copy()
        num_circles = len(contours)
        ave = 0
        rds = []
        center, radius = cv2.minEnclosingCircle(contour)
        cx = int(round(center[0]))
        cy = int(round(center[1]))
        rr = int(round(radius))
        # draw enclosing circle over beads
    #     cv2.circle(circles, (cx,cy), rr, (1,1,1), 1)
        # cumulate radii for average
        ave = ave + radius
        rds.append(rr)

# print average radius
ave_radius = ave / num_circles
print("average radius:", ave_radius)
print ("number of circles:", num_circles)

cv2.imwrite('beads_circles.jpg', circles)
plt.imshow(circles)
plt.show()

Here is the output

output


Solution

  • import numpy as np
    import matplotlib.pyplot as plt
    import cv2
    import glob
    import os
    
    img = cv2.imread("pip_ims/52.png")
    
    image = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
    # create a binary thresholded image
    _, binary = cv2.threshold(gray, 225, 255, cv2.THRESH_BINARY_INV)
    
    # find the contours from the thresholded image
    contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    dia_mm = []
    for contour in contours:
        #image = cv2.drawContours(image, contours, -1, (1, 1, 1), 3)
        area = cv2.contourArea(contour)
        dia = 2*(area/np.pi)**(0.5) # calculating diameter from area
        print(dia)
        diamm = dia*(6.2/64) # converting diameter from pixels to mm
        dia_mm.append(diamm)
        print(diamm)
    diameter = list(filter(lambda num: num != 0, dia_mm)) # removing zeros
    diameter = np.array(diameter)
    print(diameter.mean(), diameter.max(), diameter.min())