简体   繁体   中英

Using OpenCV Contours in Python to Analyze fluorescent cell image

I am trying to use Contours in OpenCV to count fluorescent cells and calculate the total fluorescent area. After exploring options in Scikit Image and after trying blob detection, this seemed the simplest method for my image type. Unfortunately, I cannot seem to get the contours to draw around the cells. Any idea what I'm doing wrong?

import cv2
import numpy as np

#import image
image = cv2.imread('Microcystis1.png')
cv2.imshow('image',image)
cv2.waitKey(0)

#Convert image to Grayscale
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
cv2.imshow('grayscale',gray)
cv2.waitKey(0)

#Threshold Binary
ret,thresh1 = cv2.threshold(gray,45,255,cv2.THRESH_BINARY)
cv2.imshow('binary',thresh1)
cv2.waitKey(0)

#Detect contours
contours, hierarchy = cv2.findContours(thresh1,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)

#Draw contours
img = cv2.drawContours(thresh1, contours, -1, (0,255,0), 3)
cv2.imshow('contours',img)
cv2.waitKey(0)

#Analyze and Report Contours
cnt = contours[0]
area = cv2.contourArea(cnt)
print("Total Area: ", area)
print("Cell Count: ", len(cnt))

Here is how the images are being processed...

在此处输入图像描述

And my output:

Total Area:  16.0
Cell Count:  14

You do not need to get contours. You can simply count the number of non-zero pixels (white pixels) in your thresholded image in Python/OpenCV. See

area = cv2.countNonZero(thresh)

https://docs.opencv.org/4.1.1/d2/de8/group__core__array.html#gaa4b89393263bb4d604e0fe5986723914

You are drawing contours on a grayscale image. If you zoom closely you will see that they are being drawn. To view them completely you can two options:

  1. If you want to draw them on thresh1 only as shown in the question, then change the color from (0, 255, 0) to (255, 255, 255). This will ensure contours in white color.
  2. If you want them in some other color like green as you would have obtained using (0, 255, 0) then you can create a NumPy array of zeros and draw the contours on it.
h, w = thresh1.shape
img = np.zeros((w, h), dtype=np.uint8)
cv2.drawContours(img, contours, -1, (0,255,0), 3)

Now display img and it should have green contours.

In order to find the total number of contours and their respective area you need to get a flat list of contours, not a hierarchical one: https://docs.opencv.org/4.3.0/d3/dc0/group__imgproc__shape.html#ga819779b9857cc2f8601e6526a3a5bc71

cv2.RETR_TREE tells the algo to group things together.

cv2.RETR_LIST tells the aglo to give you a flat list of all the individual points.

I believe that's why you're seeing the total area of 16.0 for 14 cells.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM