2

So I am trying to segment individual cells from a loaded image using Python/OpenCV. My code currently is able to mask the cells, but I would like to segment individual cells and save them as separate images.

raw image

masked image

So the output would be one of those single cells you see in the above (purposes for downstream use with 2D convnet)

img_dir = '/path'
img = cv2.imread(img_dir, 0)
plt.imshow(img, cmap = 'gray', interpolation = 'bicubic') # swap hot 
for gray

# draw a contour image with fixed threshold 50
fig = plt.figure()
ax = fig.add_subplot(111)
ax.contourf(img, levels=[0, 10, 20, 30,  40, 50, 60, 70, 80, 120], 
colors='k')
plt.show()

res = cv2.resize(img,None,fx=0.5, fy=0.5, interpolation = 
cv2.INTER_CUBIC)
Dan Mašek
  • 17,852
  • 6
  • 57
  • 85
inz-haque
  • 21
  • 6
  • Are all the black spots in the 'masked image' cells? Or does it need to be cleaned further? – Shawn Mathew Jul 06 '17 at 17:58
  • You might need to use "clustering" : http://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_ml/py_kmeans/py_kmeans_opencv/py_kmeans_opencv.html – Ofer Sadan Jul 06 '17 at 18:09
  • Do you just want a window around a single cell (bounding box), or a modified image where the surrounding cells are erased and replaced by the background ? –  Jul 06 '17 at 19:08
  • @ShawnMathew all the black spots are masked cells (there are also clumps of cells which you can see, but these have white spaces in them which I'm not too sure on how to remove) – inz-haque Jul 06 '17 at 21:10
  • @YvesDaoust a bounding box I think would be ideal, as I want to pass these individual cells into a 2D convolutional neural net (having the stuff around the cells present in the bounding box might be better for training the CNN – inz-haque Jul 06 '17 at 21:10
  • @Batman: I think it's the opposite. For proper training, you will need to show samples of the desired shapes, but also surrounded by all possible configurations of neighboring cells (otherwise these will pollute the classification). This is impractical. –  Jul 06 '17 at 21:16
  • @YvesDaoust ah okay, that makes sense. What steps would you recommend for an ideal approach? – inz-haque Jul 06 '17 at 21:52
  • I would probably copy the desired blob from the mask to a small image, and create a "safety magin" around it by erosion. Then I would copy the image pixels facing the mask, and fill the rest with the background color. –  Jul 06 '17 at 22:00
  • It seems that there is a lighter halo aroud the cells. Then you have the option of copying pixels not extending outside the halo and fill the rest with the halo color, or copying up to the background color and filling the rest with that color. –  Jul 06 '17 at 22:02

1 Answers1

0

Actually in this problem, segmentation is the process of separating the cells from the background which you already accomplished.

Being left with a binary image you have to perform a blob detection. After optionally filtering out everything that is of unwanted size or shape you are left with a list of blobs, each representing a cell I guess.

http://docs.opencv.org/trunk/dd/d49/tutorial_py_contour_features.html

https://www.learnopencv.com/blob-detection-using-opencv-python-c/

You then compute the so bounding rect of each of those blobs and use that rectangle to create a roi to crop the subimages.

How to crop an image in OpenCV using Python

Piglet
  • 27,501
  • 3
  • 20
  • 43