I often take pictures of cells because of my work, so I analyzed the cell images with the Python version of OpenCV.
With a memorial meaning.
This time, we will try to find the ratio of cultured cells covering the adhesive surface of the culture vessel (cell occupancy area ratio or confluency), so-called "cell confluence".
In short, the cell occupancy in the microscopic image is quantified by image analysis.
Please comment if you have any opinions or if you would like to do more like this.
A photomicrograph of cells called mesenchymal stem cells (MSCs).
At first glance, the confluence (cell occupancy in the image) is about 30-40%.
Load the ** OpenCV ** library for image analysis using Python.
Also, load ** NumPy **.
#Library
import cv2
import numpy as np
The ** imread () ** function reads the image data in color, and the ** cvtColor () ** function grayscales it.
** cvtColor () ** The first argument of the function is the input image (color image).
Since the data acquired by the ** imread () ** function is in BGR format, specify cv2.COLOR_BGR2GRAY
as the second argument.
#Loading color images
img = cv2.imread('cell.jpg', 1)
#Grayscale
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
Binarize the image.
That is, if the pixel value is larger than the threshold value, a certain value (white) is assigned, and if not, another value (black) is assigned.
There seem to be various methods for binarization, but I tried using the one called "Otsu's binarization".
Use the ** threshold () ** function to binarize.
** threshold () ** The first argument of the function must be an input image and a grayscale image.
The second argument is the threshold, which is used to identify the pixel value.
The third argument is the maximum value assigned to pixels with a value greater than or equal to the threshold.
As mentioned above, OpenCV has several threshold processing methods, which are specified by the 4th argument.
This time, we will use the method of "binarization of Otsu", so we will use cv2.THRESH_BINARY + cv2.THRESH_OTSU
.
#Binarization of Otsu
ret,th = cv2.threshold(img_gray,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
The ** threshold () ** function returns two return values.
The second return value th
becomes a ** binarized image **.
Morphology conversion (expansion) is performed to remove noise in the image.
Depending on the size of the kernel (5x5 size this time), all pixels near the boundary of the object change from black (0) to white (1) and disappear. If even one pixel with a pixel value of ‘1’ is included in the kernel, the pixel value of the pixel of interest in the output image will be ‘1’.
#Kernel settings
kernel = np.ones((5,5),np.uint8)
#Morphology transformation (expansion)
th_dilation = cv2.dilate(th,kernel,iterations = 1)
Before morphology conversion (** th **)
After morphology conversion (** th_dilation **)
The black area inside the cell could be converted into a white area.
The contour is extracted based on the image from which noise has been removed by morphology conversion.
Use the ** findContours () ** function to extract contours.
** findContours () ** The first argument of the function is the image used for contour extraction. The second argument specifies the extraction mode, and the third argument specifies the contour approximation method.
** findContours () ** The return value of the function, contours
, contains the coordinate data of each contour in the Numpy array format.
Use contours
to draw contours on the original image with the ** drawContours () ** function.
When drawing the entire outline, specify the third argument of the ** drawContours () ** function to -1
.
[Outline: First Step](http://labs.eecs.tottori-u.ac.jp/sd/Member/oyamada/OpenCV/html/py_tutorials/py_imgproc/py_contours/py_contours_begin/py_contours_begin.html#contours-getting- started)
#Contour extraction
contours, hierarchy = cv2.findContours(th_dilation,
cv2.RETR_LIST,
cv2.CHAIN_APPROX_NONE)
#Draw contour on original image
img_contour = cv2.drawContours(img, contours, -1, (0, 255, 0), 3)
Get the total number of pixels with .size
.
Get the number of pixels in the white area, that is, the cell area with the ** countNonZero () ** function.
Total number of pixels-Calculate the white area and get the number of pixels in the black area (areas other than cells).
Finally, each ratio is displayed.
#Total number of pixels
whole_area = th_dilation.size
#Number of pixels in the white part
white_area = cv2.countNonZero(th_dilation)
#Number of pixels in the black part
black_area = whole_area - white_area
#Show each percentage
print('White_Area =' + str(white_area / whole_area * 100) + ' %')
print('Black_Area =' + str(black_area / whole_area * 100) + ' %')
result
White_Area =26.266264121542658 %
Black_Area =73.73373587845734 %
The result was that cell confluence was approximately 30%.
Finally, the original image with the contour added and the image used for the contour extraction are displayed.
#Image display
cv2.imshow('img', img)
cv2.imshow('th_dilation', th_dilation)
cv2.waitKey(0)
cv2.destroyAllWindows()
result
Original image + contour (** img **)
Image used for contour extraction (** th_dilation **)
#Library
import cv2
import numpy as np
#Loading color images
img = cv2.imread('cell.jpg', 1)
#Grayscale
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
#Binarization of Otsu
ret,th = cv2.threshold(img_gray,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)
#Kernel settings
kernel = np.ones((5,5),np.uint8)
#Morphology transformation (expansion)
th_dilation = cv2.dilate(th,kernel,iterations = 1)
#Contour extraction
contours, hierarchy = cv2.findContours(th_dilation,
cv2.RETR_LIST,
cv2.CHAIN_APPROX_NONE)
#Draw contour on original image
img_contour = cv2.drawContours(img, contours, -1, (0, 255, 0), 3)
#Total number of pixels
whole_area = th_dilation.size
#Number of pixels in the white area
white_area = cv2.countNonZero(th_dilation)
#Number of pixels in the black area
black_area = whole_area - white_area
#Show each percentage
print('White_Area =' + str(white_area / whole_area * 100) + ' %')
print('Black_Area =' + str(black_area / whole_area * 100) + ' %')
#Image display
cv2.imshow('img', img)
cv2.imshow('th_dilation', th_dilation)
cv2.waitKey(0)
cv2.destroyAllWindows()
Recommended Posts