I tried "morphology conversion" of images with Python + OpenCV

Introduction

Image processing does not always provide beautiful images. Images are often noisy. If there is noise, it may be removed using a technique called "smoothing" or "morphology conversion".

This time, we will use Python to perform morphological conversion of images using OpenCV.

What is morphology conversion?

** Morphology conversion ** is mainly to perform "** contraction " and " expansion **" processing on binary images. Morphology is the process of "morphology," or shape.

A "binary image" is a binarized image. Binarization is the process of converting an image into two gradations, white and black.

Preparation

The environment uses Google Colaboratory. The Python version is below.

import platform
print("python " + platform.python_version())
# python 3.6.9

Let's display the image

Now let's write the code. First, import OpenCV.

import cv2

In addition, import the following to display the image in Colaboratory.

from google.colab.patches import cv2_imshow

Prepare a sample image as well.

Now, let's display the prepared sample image.

img = cv2.imread(path) #path specifies where the image is placed
cv2_imshow(img)

image.png

The grayscaled image is below.

img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2_imshow(img_gray)

image.png

The binarized image of the grayscale image is as follows. This time, I set the threshold to 180.

threshold = 180
_, img_th = cv2.threshold(img_gray, threshold, 255, cv2.THRESH_BINARY)
cv2_imshow(img_th)

image.png

Furthermore, let's display a black-and-white inverted image of the binarized image. I will perform morphology conversion on this image.

img_bw = cv2.bitwise_not(img_th)
cv2_imshow(img_bw)

image.png

In addition, prepare an image with noise as an image to be used later. This time, I prepared two types of noise-containing images using Salt-and-pepper noise.

import numpy as np

row, col, ch = img.shape
img_s = img.copy()
img_p = img.copy()
pts_x = np.random.randint(0, col-1 , 1000)
pts_y = np.random.randint(0, row-1 , 1000)
img_s[(pts_y,pts_x)] = (255, 255, 255)
img_p[(pts_y,pts_x)] = (0, 0, 0)
imgs = cv2.hconcat([img_s, img_p])
cv2_imshow(imgs)

image.png

These images are also grayscale, binarized, and black and white inverted.

#grayscale
img_s = cv2.cvtColor(img_s, cv2.COLOR_BGR2GRAY)
img_p = cv2.cvtColor(img_p, cv2.COLOR_BGR2GRAY)
#Binarization
threshold = 180
_, img_s = cv2.threshold(img_s, threshold, 255, cv2.THRESH_BINARY)
_, img_p = cv2.threshold(img_p, threshold, 255, cv2.THRESH_BINARY)
#Black and white inversion
img_s = cv2.bitwise_not(img_s)
img_p = cv2.bitwise_not(img_p)
imgs = cv2.hconcat([img_s, img_p])
cv2_imshow(imgs)

image.png

Morphology transformation

Now, let's introduce how to perform morphological conversion on an image.

Import numpy in advance for use in the following.

import numpy as np

Erosion

With erosion, ** shrink the white areas **. As a result, the white areas become smaller and thinner, and the black areas increase. This is an effective process for removing white noise in an image or separating multiple connected objects.

Now, let's display the shrunk image side by side with the original image.

kernel = np.ones((3, 3), np.uint8)

img_ero = cv2.erode(img_bw, kernel, iterations=1)
imgs = cv2.hconcat([img_bw, img_ero])
cv2_imshow(imgs)

image.png

You can see that the white part is smaller and thinner than the original image.

cv2.erode has three arguments. The first argument is the target image. The second argument is what is called the kernel size. When one point of the image is decided, it shows how much area around it is included. Think of it as the size of a box. The third argument is what is called an iteration. Iteration means "iteration" and here specifies how many times the process should be performed. In the above, the contraction process is performed only once.

Now, let's display the shrink-processed image by changing the kernel size value in various ways.

kernel_1 = np.ones((1, 1), np.uint8)
kernel_2 = np.ones((3, 3), np.uint8)
kernel_3 = np.ones((5, 5), np.uint8)
img_1 = cv2.erode(img_bw, kernel_1, iterations=1)
img_2 = cv2.erode(img_bw, kernel_2, iterations=1)
img_3 = cv2.erode(img_bw, kernel_3, iterations=1)

imgs = cv2.hconcat([img_1, img_2, img_3])
cv2_imshow(imgs)

image.png

You can see that the larger the kernel size, the more it shrinks, and the white areas become smaller and thinner.

Next, let's display the image that has been shrunk by changing the iteration value.

kernel = np.ones((3, 3), np.uint8)

img_1 = cv2.erode(img_bw, kernel, iterations=1)
img_2 = cv2.erode(img_bw, kernel, iterations=3)
img_3 = cv2.erode(img_bw, kernel, iterations=5)
imgs = cv2.hconcat([img_1, img_2, img_3])
cv2_imshow(imgs)

image.png

Again, the shrinking process is repeated for the number of iterations, so the larger the value, the more shrinking.

Dilation

Dilation ** dilates the white areas **. This is the reverse of contraction. In other words, as a result, the black areas become smaller and thinner, and the white areas increase.

Now, let's display the expanded image side by side with the original image.

img_dil = cv2.dilate(img_bw, kernel, iterations = 1)
imgs = cv2.hconcat([img_bw, img_dil])
cv2_imshow(imgs)

image.png

You can see that the white part is thicker and larger than the original image.

The arguments for cv2.dilate are similar to the arguments for contraction cv2.erode.

Opening process

The opening process is the process of expanding after contracting. The white part can be made smaller by shrinking, and the size can be restored by expanding. Therefore, it is an effective process for removing ** white noise **.

Let's display the image with noise and the image with the opening process side by side.

img_opening = cv2.morphologyEx(img_p, cv2.MORPH_OPEN, kernel)
imgs = cv2.hconcat([img_p, img_opening])
cv2_imshow(imgs)

image.png

As a result of the opening process, you can see that the white noise has been removed.

Closing process (closing)

The closing process is the reverse of the opening process. The black part can be made smaller by expansion, and the size can be restored by contraction. Therefore, it is an effective process for removing ** black noise **.

Let's display the image with noise and the image with closing processing side by side.

img_closing = cv2.morphologyEx(img_s, cv2.MORPH_CLOSE, kernel)
imgs = cv2.hconcat([img_s, img_closing])
cv2_imshow(imgs)

image.png

As a result of the closing process, you can see that the black noise has been removed.

Morphology gradient

Morphology gradient is the process of taking the difference between an expanded image and a contracted image. This will result in the contouring of the object.

Let's display an image with a morphology gradient.

img_gradient = cv2.morphologyEx(img_bw, cv2.MORPH_GRADIENT, kernel)
cv2_imshow(img_gradient)

image.png

You can see that the outline of the object is taken.

Summary

This time, I used Python to perform morphological conversion of the image by OpenCV.

We introduced "contraction", "expansion", "opening process", "closing process", and "morphology gradient" as morphology conversions. In particular, opening processing and closing processing are effective methods for removing fine noise. Consider opening treatment for white noise and closing treatment for black noise.

There is also a method called "smoothing" as a noise removal method, so I think you should try this as well.

See below for more information on morphology transformations and smoothing.

-Morphological conversion -I tried "smoothing" the image with Python + OpenCV

Recommended Posts

I tried "morphology conversion" of images with Python + OpenCV
[OpenCV / Python] I tried image analysis of cells with OpenCV
I tried non-photorealistic rendering with Python + opencv
I tried to automatically collect images of Kanna Hashimoto with Python! !!
I tried "smoothing" the image with Python + OpenCV
I tried hundreds of millions of SQLite with python
I tried "differentiating" the image with Python + OpenCV
I tried "binarizing" the image with Python + OpenCV
I tried fp-growth with python
I tried scraping with Python
I tried gRPC with Python
I tried to extract features with SIFT of OpenCV
Try projective transformation of images using OpenCV with Python
I tried trimming efficiently with OpenCV
I tried web scraping with python.
I tried using GrabCut of OpenCV
Load gif images with Python + OpenCV
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 to find the entropy of the image with python
I tried running Movidius NCS with python of Raspberry Pi3
I tried a stochastic simulation of a bingo game with Python
I tried scraping the ranking of Qiita Advent Calendar with Python
Capturing images with Pupil, python and OpenCV
I tried sending an email with python.
I tried to create a list of prime numbers with python
I tried to fix "I tried stochastic simulation of bingo game with Python"
I tried a functional language with Python
[python, openCV] base64 Face recognition with images
[Python] Read images with OpenCV (for beginners)
#I tried something like Vlookup with Python # 2
I tried to make an image similarity function with Python + OpenCV
I tried to get the authentication code of Qiita API with Python.
I tried putting various versions of Python + OpenCV + FFmpeg environment on Mac
I tried to streamline the standard role of new employees with Python
I tried handwriting recognition of runes with scikit-learn
[Python / DynamoDB / boto3] List of operations I tried
I tried image recognition of CIFAR-10 with Keras-Learning-
Performance comparison of face detector with Python + OpenCV
I tried object detection using Python and OpenCV
I tried Flask with Remote-Containers of VS Code
I tried L-Chika with Raspberry Pi 4 (Python edition)
I tried Jacobian and partial differential with python
I tried to get CloudWatch data with Python
I tried using mecab with python2.7, ruby2.3, php7
I tried function synthesis and curry with python
I tried running faiss with python, Go, Rust
Wavelet transform of images with PyWavelets and OpenCV
I tried running Deep Floor Plan with Python 3.6.10.
I tried sending an email with SendGrid + Python
I tried using the image filter of OpenCV
Binarization with OpenCV / Python
I tried Python> autopep8
I tried Python> decorator
I tried to make a simple mail sending application with tkinter of Python
I tried to easily visualize the tweets of JAWS DAYS 2017 with Python + ELK
"Brute force of MD5 hash value of 6-digit password" I tried it with Python
I tried to automatically send the literature of the new coronavirus to LINE with Python
I tried to summarize how to use matplotlib of python