Computer Vision

Smoothing and Blurring

Blurring là hiện tượng bị “out of focus” khi chúng ta chụp ảnh và tất nhiên đây là điều không mong muốn. Tuy nhiên, blurring có vai trò rất quan trọng trong xử lý hình ảnh. Trong thực tế, khi áp dụng object detection, edge detection, thresholding và contour extraction, chúng ta thường sử dụng blurring để giảm nhiễu và loại bỏ các chi tiết thừa, giúp tập trung vào nội dung chính của bức ảnh.

Chúng ta sẽ nghiên cứu một số phương pháp blurring sau: Averaging, Gaussian, Median và bilateral.

AVERAGING

Trong phương pháp này, chúng ta sẽ định nghĩa một ma trận M x N, trong đó M, N phải là số lẻ. Ma trận này sẽ di chuyển từ trái sang phải, từ trên xuống dưới bức ảnh. Pixel nằm ở trung tâm của ma trận sẽ được thay bằng trung bình cộng của tất cả các pixels nằm trong ma trận.

Ma trận được định nghĩa ở trên được gọi là “convolution kernel” hoặc “kernel”.

Function: outputImage = cv2.blur(image, (WidthOfKernel, HeightOfKernel))

Example 1: Averaging blurring

import numpy as np
import cv2

image = cv2.imread("image_path")
cv2.imshow("Original", image)
blurred = np.hstack([cv2.blur(image, (3,3)),
                     cv2.blur(image, (5,5)),
                     cv2.blur(image, (7,7)),
                     cv2.blur(image, (9,9))])
cv2.imshow("Averaged", blurred)
cv2.waitKey(0)

Output:

averaging

Chúng ta thấy rằng, SizeofKernel càng lớn thì hình ảnh càng bị mờ, bức ảnh cuối cùng thực sự rất mờ, giống như bị rung tay khi chụp, hiệu ứng này được gọi là “motion blur”.


GAUSSIAN

Tương tự như phương pháp Averaging, nhưng thay vì tính trung bình các pixel xung quanh pixel trung tâm, chúng ta sẽ tính trung bình cùng với trọng số, tức là các pixel càng gần pixel trung tâm sẽ có ảnh hưởng lớn hơn các pixel ở xa. Kết quả nhận được là bức ảnh sẽ được làm mờ một cách tự nhiên hơn so với phương pháp Averaging.

Function: outputImage = cv2.GaussianBlur(image, (WidthOfKernel, HeightOfKernel), StandardDeviation)

Trong đó, Standard Deviation là độ lệch chuẩn, nếu Standard Deviation = 0 thì OpenCV sẽ tự động tính toán dựa trên kích thước của kernel.

Example 2: Gaussian blurring

import numpy as np
import argparse
import cv2

image = cv2.imread("image_path")
cv2.imshow("Original", image)
blurred = np.hstack([cv2.GaussianBlur(image, (3,3), 0),
                     cv2.GaussianBlur(image, (5,5), 0),
                     cv2.GaussianBlur(image, (7,7), 0)])
cv2.imshow("Gaussian", blurred)
cv2.waitKey(0)

Output:

gaussian

Với kết quả trên ta thấy rằng hình ảnh tuy bị làm mờ ít hơn so với phương pháp Averaging nhưng hiệu ứng tự nhiên hơn.

In general, recommend starting with a simple Gaussian blur and tuning your parameters as needed. While the Gaussian blur is slightly slower than a simple average blur (and only by a tiny fraction), a Gaussian blur tends to give much nicer results, especially when applied to natural images.


MEDIAN

Phương pháp Median blurring đạt hiệu quả cao nhất khi dùng để loại bỏ nhiễu muối tiêu.

Khi áp dụng Median blurring, chúng ta cũng định nghĩa một kernel K x K (với K là một số lẻ) và xem xét các pixel xung quanh pixel trung tâm. Tuy nhiên, chúng ta sẽ thay thế pixel trung tâm bởi trung vị (median) của các pixel lân cận, thay vì là trung bình (average) như phương pháp Averaging.

Averaging and Gaussian methods can compute means or weighted means for the neighborhood – this average pixel intensity may or may not be present in the neighborhood. But by definition, the median pixel must exist in our neighborhood. By replacing our central pixel with a median rather than an average, we can substantially reduce noise.

Function: outputImage = cv2.medianBlur(image, SizeofKernel)

Example 3: Median blurring

import numpy as np
import argparse
import cv2

image = cv2.imread("image_path")
cv2.imshow("Original", image)

blurred = np.hstack([cv2.medianBlur(image, 3),
                     cv2.medianBlur(image, 5),
                     cv2.medianBlur(image, 7)])
cv2.imshow("Median", blurred)
cv2.waitKey(0)

Output:

median

Ta thấy rằng trong các bức ảnh không còn “motion blur” như với phương pháp Averaging và Gaussian nữa, thay vào đó nhiễu và các chi tiết của hình ảnh đã bị loại bỏ. Kernel size càng lớn thì bức ảnh càng bị mất nhiều chi tiết, nhưng không tạo ra “motion blur”.

The median blur is by no means a “natural blur” like Gaussian smoothing. However, for damaged images or photos captured under highly sub-optimal conditions, a median blur can really help as a pre-processing step prior to passing the image along to other methods, such as thresholding and edge detection.


BILATERAL

Các phương pháp ở trên đều loại bỏ nhiễu và các chi tiết trong bức ảnh nhưng đồng thời làm mất đi sự sắc nét của bức ảnh. Để giảm nhiễu nhưng vẫn giữ cho bức ảnh sắc nét, chúng ta sử dụng Bilateral blurring.

Bilateral blurring accomplishes this by introducing two Gaussian distributions. The first Gaussian function only considers spatial neighbors, that is, pixels that appear close together in the (x, y) coordinate space of the image. The second Gaussian then models the pixel intensity of the neighborhood, ensuring that only pixels with similar intensity are included in the actual computation of the blur.

Nói chung, phương pháp Bilateral có khả năng giảm nhiễu trong khi vẫn duy trì được độ sắc nét của hình ảnh. Nhược điểm lớn nhất của nó là tốc độ xử lý chậm hơn nhiều so với các phương pháp trên.

Function: outputImage = cv2.bilateralFilter(image, KernelSize, sigmaColor, sigmaSpace)

Trong đó:

  • sigmaColor: giá trị càng lớn thì càng nhiều màu sắc của các pixel lân cận được xem xét để tính toán blur.
  • sigmaSpace: giá trị càng lớn thì càng nhiều pixel ở xa pixel trung tâm có ảnh hướng đến việc tính toán blur.

Sigma values: For simplicity, you can set the 2 sigma values to be the same. If they are small (< 10), the filter will not have much effect, whereas if they are large (> 150), they will have a very strong effect, making the image look “cartoonish”.

Filter size: Large filters (d > 5) are very slow, so it is recommended to use d=5 for real-time applications, and perhaps d=9 for offline applications that need heavy noise filtering.

Example 4: Bilateral blurring

import numpy as np
import argparse
import cv2

image = cv2.imread("image_path")
cv2.imshow("Original", image)
blurred = np.hstack([cv2.bilateralFilter(image, 5, 51, 51),
                     cv2.bilateralFilter(image, 7, 71, 71),
                     cv2.bilateralFilter(image, 9, 91, 91)])
cv2.imshow("Bilateral", blurred)
cv2.waitKey(0)

Output:

bilateral

Như chúng ta thấy, các bức ảnh đã được loại bỏ nhiễu nhưng vẫn giữ được sự sắc nét.


SUMMARY

Qua bài viết này chúng ta đã tìm hiểu về các phương pháp blurring. Cảm ơn các bạn đã theo dõi.

Thân ái và quyết thắng.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s