[OpenCV / Python] I tried image analysis of cells with OpenCV

Introduction

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.

Reference URL

Image to use

MSC.jpg

A photomicrograph of cells called mesenchymal stem cells (MSCs).

At first glance, the confluence (cell occupancy in the image) is about 30-40%.

Required packages

Load the ** OpenCV ** library for image analysis using Python.

Also, load ** NumPy **.

#Library
import cv2
import numpy as np

Image loading and grayscale

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

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".

Image threshold processing

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 transformation (expansion)

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’.

Morphological transformation

#Kernel settings
kernel = np.ones((5,5),np.uint8)

#Morphology transformation (expansion)
th_dilation = cv2.dilate(th,kernel,iterations = 1)

Before morphology conversion (** th **) th.jpg

After morphology conversion (** th_dilation **) th_dilation.jpg

The black area inside the cell could be converted into a white area.

Contour extraction

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)

Black and white area calculation

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%.

Image display

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 **) img.jpg

Image used for contour extraction (** th_dilation **) th_dilation.jpg

Final script

#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

[OpenCV / Python] I tried image analysis of cells with OpenCV
I tried "gamma correction" of the image with Python + OpenCV
I tried "smoothing" the image with Python + OpenCV
I tried "differentiating" the image with Python + OpenCV
I tried "binarizing" the image with Python + OpenCV
I tried "morphology conversion" of images with Python + OpenCV
I tried to find the entropy of the image with python
I tried non-photorealistic rendering with Python + opencv
I tried to make an image similarity function with Python + OpenCV
I tried hundreds of millions of SQLite with python
I tried image recognition of CIFAR-10 with Keras-Learning-
I tried image recognition of CIFAR-10 with Keras-Image recognition-
I tried using the image filter of OpenCV
I tried fp-growth with python
I tried scraping with Python
Image editing with python OpenCV
I tried gRPC with Python
I tried scraping with python
I tried to extract features with SIFT of OpenCV
[Python] Using OpenCV with Python (Image Filtering)
I tried trimming efficiently with OpenCV
[Python] Using OpenCV with Python (Image transformation)
I tried web scraping with python.
I tried using GrabCut of OpenCV
Find image similarity with Python + OpenCV
Introduction to image analysis opencv python
I tried running prolog with python 3.8.2.
I tried SMTP communication with Python
I tried face recognition with OpenCV
Basic study of OpenCV with Python
I tried running Movidius NCS with python of Raspberry Pi3
I tried a stochastic simulation of a bingo game with Python
[Python] Easy reading of serial number image files with OpenCV
Image processing with Python (I tried binarizing it into a mosaic art of 0 and 1)
Basics of binarized image processing with Python
I tried scraping the ranking of Qiita Advent Calendar with Python
I tried multiple regression analysis with polynomial regression
I tried scraping Yahoo News with Python
I tried factor analysis with Titanic data!
I tried sending an email with python.
I tried to create a list of prime numbers with python
I tried to process the image in "sketch style" with OpenCV
Image processing with Python & OpenCV [Tone Curve]
Image acquisition from camera with Python + OpenCV
I tried to fix "I tried stochastic simulation of bingo game with Python"
I tried a functional language with Python
I tried recursion with Python ② (Fibonacci sequence)
Image processing with Python 100 knocks # 4 Binarization of Otsu (discriminant analysis method)
I tried to process the image in "pencil style" with OpenCV
I tried playing with the image with Pillow
Drawing with Matrix-Reinventor of Python Image Processing-
Analysis of X-ray microtomography image by Python
I tried simple image recognition with Jupyter
I tried to improve the efficiency of daily work with Python
Light image processing with Python x OpenCV
I tried to automatically collect images of Kanna Hashimoto with Python! !!
#I tried something like Vlookup with Python # 2
How to crop the lower right part of the image with Python OpenCV
I tried to get the authentication code of Qiita API with Python.
I tried fMRI data analysis with python (Introduction to brain information decoding)
I tried putting various versions of Python + OpenCV + FFmpeg environment on Mac