2
$\begingroup$

Hi I try to detect the particle length size from this image
original  image

and I'd like to get the length size of the particle Like this below. and get the histogram of the size of the particle using centroid and detect the line like this below:

enter image description here

I have try to using watershed. But i still low knowledge on this code. What i want to ask are: 1. How to get segmentation like this picture as an example below so I can evaluate my segmentation.. I dont know how to display it (I will share my code)

enter image description here

  1. How to separate the particle that unite with other particle. I got this contour

enter image description here

Here it is my code:

from __future__ import print_function
from imutils import perspective
from imutils import contours
import numpy as np
import argparse
import imutils
import cv2
import scalar
import sys
from scipy.spatial import distance as dist
import scipy.ndimage as ndi
import matplotlib.pyplot as plt
from skimage import filters
from sklearn import cluster
from scipy import ndimage
from skimage.feature import peak_local_max
from skimage.morphology import watershed
from scipy.ndimage import label

img = cv2.imread("C:\\Users\\adiyu\Pictures\\snipping\\c3smeasure.png", 
cv2.IMREAD_COLOR)
kernel = np.array([[-1,-1,-1],[-1,9,-1], [-1,-1,-1]])
kernel2 = np.ones((3,3),np.uint8)

img=cv2.filter2D(img,-255, kernel)
img = cv2.medianBlur(img,3)
img_np = np.array(img)
img_np_rgb = cv2.cvtColor(img_np,cv2.COLOR_RGBA2RGB)


#Kmeans cluster using Opencv
Z = img.reshape((-1,3))

# convert to np.float32
Z = np.float32(Z)

# define criteria, number of clusters(K) and apply kmeans()
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10, 1.0)
K = 3
ret,label,center=cv2.kmeans(Z,K,None,criteria,10,cv2.KMEANS_PP_CENTERS)
# Now convert back into uint8, and make original image
center = np.uint8(center)


res = center[label.flatten()]
res2 = res.reshape((img.shape))
gray= cv2.cvtColor(res2,cv2.COLOR_BGR2GRAY)
gray = cv2.fastNlMeansDenoising(gray, None, 6,7,21)


cv2.imshow('res2',res2)
cv2.imshow('gray',gray)
thresh = cv2.threshold(gray, 100, 255, cv2.THRESH_BINARY_INV + 
cv2.THRESH_OTSU + cv2.THRESH_OTSU)[1]
cv2.imshow('thresh',thresh)
opening = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel, iterations=2)
cv2.imshow("opening", opening)
closing = cv2.morphologyEx(opening, cv2.MORPH_CLOSE,kernel2, iterations=2)
cv2.imshow("closing", closing)
fg = cv2.erode(closing,None,iterations = 2)
cv2.imshow("fg", fg)

# sure background area
sure_bg = cv2.dilate(opening,kernel,iterations=3)
cv2.imshow("sure_bg", sure_bg)
# Finding sure foreground area
dist_transform = cv2.distanceTransform(opening,cv2.DIST_L2,5)
ret, sure_fg = cv2.threshold(dist_transform,0.1*dist_transform.max(),255,0)

# Finding unknown region
sure_fg = np.uint8(sure_fg)
unknown = cv2.subtract(sure_bg,sure_fg)
cv2.imshow("unknown", unknown)

# Marker labelling
ret, markers = cv2.connectedComponents(sure_fg)

# Add one to all labels so that sure background is not 0, but 1
markers = markers+1

# Now, mark the region of unknown with zero
markers[unknown==255] = 0
markers = cv2.watershed(img,markers)
img[markers == -1] = [255,0,0]

cv2.imshow("img", img)

cv2.waitKey(0)
cv2.destroyAllWindows()enter preformatted text here

any suggestions are welcome..Thank U

$\endgroup$
2
$\begingroup$

Does it have to use python? For exploring your workflow and pipeline for a kind of image analysis, I would suggest getting ImageJ / FiJi. Use it together with the MorphoLibJ plugin to get more options on morphological segmentation. Once you determined your workflow you can code it in python to batch analyze.

Anyways, your workflow should look like this, regardless of which software you use:

  1. Segment particles either by rgb-thresholding or by converting to grayscale beforehand. An adaptive method is preferred. You can also use the contours you got. The aim is to produce a binary (black/white) image, where your particles are white and everything else is black (or the other way around).

  2. On this image you perform "distance transform watershed". Which is also doable with python.

  3. Perform optical checks on the resulting image to confirm that particles aren't over- or undersegmented. Refine parameters like the dynamics, the distance metric, seeding, etc. if needed.

  4. If correctly segmented perform particle analysis on the image. In ImageJ you can go "Analyze -> Set Measurements" and select variables to measure - for example Feret Diameter - Length. In python i am not experienced enough but I would go with this tutorial

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.