In image processing, you may want to detect specific information such as edges. Edges and noise are sudden changes in pixel values. One possible way to detect these is to "differentiate the image."
This time, we will use Python to differentiate the image with OpenCV.
First, let's talk about what differentiation is. Derivative is a "small change" and represents the rate of change. The derivative formula is as follows.
f'(x) = \lim_{h\rightarrow 0}\frac{f(x+h)-f(x)}{h}
Roughly speaking, think of it as representing ** how big the change is **.
The magnitude of the derivative can be expressed by the "slope". The smaller the change, the smaller the slope, and the larger the change, the larger the slope. An example of the differential graph is shown below.
The part with small change is a blue straight line, and the part with large change is a red straight line.
In image differentiation, by examining this slope, the part where the pixel value changes rapidly, that is, the edge is detected.
The environment uses Google Colaboratory. The Python version is below.
import platform
print("python " + platform.python_version())
# python 3.6.9
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. This time, we will use the free image from Pixabay.
Now, let's display the prepared sample image.
img = cv2.imread(path) #path specifies where the image is placed
cv2_imshow(img)
Also, in the differentiation of the image, a grayscale image is used, so prepare this.
Grayscale images can be viewed below.
img_gray = cv2.imread(path, 0)
cv2_imshow(img_gray)
Then, I will introduce how to differentiate the image.
First, let's introduce the Sobel filter. The Sobel filter is a one-time derivative, and I think it can be said to be the most basic derivative method for images.
Images using the Sobel filter can be viewed below.
img_sobel = cv2.Sobel(img_gray, cv2.CV_32F, 1, 0, ksize=3)
cv2_imshow(img_sobel)
cv2.Sobel has five arguments. For details, please refer to the official documents. If the third argument is 1, the derivative in the x direction is calculated, and if the fourth argument is 1, the derivative in the y direction is calculated. In the image above, the image differentiated in the x direction (horizontal direction) is displayed. The fifth 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.
Now, let's change the 3rd and 4th arguments and display the images differentiated in the x and y directions, respectively.
img_sobel_x = cv2.Sobel(img_gray, cv2.CV_32F, 1, 0, ksize=3)
img_sobel_y = cv2.Sobel(img_gray, cv2.CV_32F, 0, 1, ksize=3)
imgs = cv2.hconcat([img_sobel_x, img_sobel_y])
cv2_imshow(imgs)
The image on the left is differentiated in the x direction and the image on the right is differentiated in the y direction. It can be seen that the x-direction (horizontal) differentiation leaves the vertical edge, and the y-direction (vertical) differentiation leaves the horizontal edge.
As you can see, it is effective to use the Sobel filter when the edges are directional.
Next, I will introduce the Laplacian filter. The Laplacian filter is a double derivative and is effective when you want finer edge detection than the Sobel filter.
Just in case, the Laplacian equation (two-dimensional) is shown below.
\Delta f = \nabla \cdot \nabla f = \frac{\partial^2}{\partial^2 x}f + \frac{\partial^2}{\partial^2 y}f
Unlike the Sobel filter, you don't need to specify the direction of differentiation.
The image using the Laplacian filter is as follows.
img_lap = cv2.Laplacian(img_gray, cv2.CV_32F)
cv2_imshow(img_lap)
You can see that the Sobel filter can detect fine edges. It can also be used when the edges do not have a specific orientation and the Sobel filter is not enabled.
So far, we have used Sobel and Laplacian filters to detect edges. By differentiating the pixel values of an image, it is possible to detect edges that are sudden changes in pixel values.
However, not only edges but also ** noise is a sudden change in pixel value **. Images often contain a variety of noise. For such images, there is a way to remove noise by first performing ** smoothing **.
This time, we will try edge detection according to the following procedure.
--Grayscale --Noise is removed by smoothing (using Gaussian filter) --Edge detection by differentiating the image (using Laplacian filter)
img_gauss = cv2.GaussianBlur(img_gray, (3, 3), 3)
img_lap = cv2.Laplacian(img_gauss, cv2.CV_32F)
cv2_imshow(img_lap)
Canny Finally, I will introduce Canny's method. Canny is an algorithm for edge detection. Canny takes several steps to detect edges.
--Noise is removed by smoothing (using Gaussian filter) --Edge detection by differentiating the image (using Sobel filter) --Detects maximum values and removes non-edges --Two-step threshold processing
See below for more details. Edge detection by Canny method
Now let's display the image using Canny.
img_canny = cv2.Canny(img_gray, 100, 200)
cv2_imshow(img_canny)
The second and third arguments are the values used in the two-step threshold processing. The second argument specifies the minimum threshold value, and the third argument specifies the maximum threshold value.
This time, I used Python to differentiate the image with OpenCV.
I introduced the Sobel filter, Laplacian filter, and Canny method as methods for differentiating images. Please use it properly according to the characteristics of the edge you want to detect. Derivative is a method of detecting sudden changes in pixel values, but it responds not only to edges but also to noise. Therefore, if you want to detect only the edges, you need to remove noise in advance. For noise removal, consider smoothing.
See below for more information on image differentiation and smoothing.
-Image Gradient -Edge detection by Canny method -I tried to "smooth" the image with OpenCV using Python
Recommended Posts