-4

This is Wendy.Image processing related question. I have to select the bubbles properly to analyze its size and calculate the velocity among image sequences.

original image
enter image description here

image sequences enter image description here//enter image description here//enter image description here

In the picture,the largest shape is a droplet,and inside the droplet contains lots of tiny bubbles.

So far, the questions are: 1.Because the shape of bubbles are broken, few contours are detected. At the same time, lots of edges detected. How can I fill out the edges to be contours ( like a coin, I just want the outline of each bubble and don't want to get the lines inside bubbles)

current progress
enter image description here
enter image description here

code(detect contours)

gray=cv2.imread("1000.tif")
blurred = cv2.GaussianBlur(gray, (3,3), 0)
edged = cv2.Canny(blurred, 5, 60)
cv2.imshow('edged ', edged )
cv2.waitKey(0)
contours, hierarchy = cv2.findContours(edged,cv2.RETR_EXTERNAL,cv2.RETR_LIST)
img = gray.copy()
cv2.drawContours(img,contours,-1,(0,255),1)  
cv2.imwrite("contours.tif", img)
cv2.imshow("contours", img)  
cv2.waitKey(0)  

code(fill holes)

im_floodfill = edged.copy()
h, w = edged.shape[:2]
mask = np.zeros((h+2, w+2), np.uint8)
cv2.floodFill(im_floodfill, mask, (0,0), 255)
im_floodfill_inv = cv2.bitwise_not(im_floodfill)
im_out = edged | im_floodfill_inv
cv2.imshow("Thresholded Image", edged)
cv2.imshow("Floodfilled Image", im_floodfill)
cv2.imshow("Inverted Floodfilled Image", im_floodfill_inv)
cv2.imshow("Foreground", im_out)
cv2.waitKey(0)
cv2.imwrite("fill.jpg", im_out)

the result will be
enter image description here

  1. The velocity of the bubbles is my objective. I've tried to put the binary image sequences into Iamgej and used the "trackmate" (a tool for automated, and semi-automated particle tracking). It has a fixed bubble size setting to track, however, the size of the bubbles is quite different in my case, so is there any method to track bubbles moving?

If this isn't clear enough please let me know and I can try and be more specific. Thank you for your time.

Wendy
  • 1
  • 1
  • 1
    Could you clarify what it is that you want to detect and track? What is "the vapor"? I see a large gray shape, and I see bubbles inside this shape. Which one of those two do you need to track? – Cris Luengo Aug 16 '20 at 04:56
  • Hi,thanks for reply. In the picture,the largest shape is a droplet,and inside the droplet contains lots of tiny bubbles.I have to track the bubbles and analyze their velocity in each pictures – Wendy Aug 16 '20 at 06:35
  • how many images do you have in total? Maybe it is faster and better to label it manually. What quality do you need in the end? – Micka Aug 16 '20 at 17:10

1 Answers1

0

Here is one way in Python/OpenCV.

  • Read the input
  • Convert to gray
  • Threshold
  • Fill the holes with morphology close
  • Get the contours and the largest contour (though presumably just one)
  • Draw the contour on a copy of the input
  • Save the results

Input:

enter image description here

import cv2
import numpy as np

# read image
img = cv2.imread('vapor.jpg')

# convert to grayscale
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

# threshold
#thresh = cv2.threshold(gray,5,255,cv2.THRESH_BINARY)[1]
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)[1]

# apply close morphology to fill white circles
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (45,45))
thresh_cleaned = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)

# get largest contour
contours = cv2.findContours(thresh_cleaned, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]
big_contour = max(contours, key=cv2.contourArea)

# draw contour
result = img.copy()
cv2.drawContours(result,[big_contour],0,(0,0,255),1) 

# save image with points drawn
cv2.imwrite('vapor_thresh.jpg',thresh)
cv2.imwrite('vapor_cleaned_thresh.jpg',thresh_cleaned)
cv2.imwrite('vapor_contour.jpg',result)

cv2.imshow("thresh", thresh)
cv2.imshow("thresh_cleaned", thresh_cleaned)
cv2.imshow("contour", result)
cv2.waitKey(0)
cv2.destroyAllWindows()

Threshold image:

enter image description here

Morphology filled image:

enter image description here

Contour image:

enter image description here

fmw42
  • 46,825
  • 10
  • 62
  • 80
  • Hi,thanks for advice:) the shape you analyzed is the droplet, but my target is to analyze the small bubbles inside – Wendy Aug 16 '20 at 06:53