Xử lý ảnh - Gradient của ảnh là gì?

  Apr 9, 2019      2m
   

OpenCV - tut 10: Image Gradient

Xử lý ảnh - Gradient của ảnh là gì?

Môi trường "hành sự"

  • Linux (bài viết sử dụng Ubuntu 16.04)
  • OpenCV (bài viết sử dụng OpenCV 3.4.1)
  • Python (bài viết sử dụng Python 3.5.5)
  • Ảnh mẫu để xử lý: girl_10.jpg

Bạn có thể download ảnh mẫu về:

girl_10.jpg (Nguồn: Lụm trên mạng)

girl 10

Gradient của ảnh là gì?

Trước tiên ta phải dịch từ Gradient trong tiếng Anh là gì đã, gradient nghĩa là độ dốc. Trong xử lý ảnh, độ dốc (tức gradient) đang nói đến ở đây chính là độ dốc về mức sáng. Hay nói cách khác chính là sự thay đổi các giá trị pixel trong ảnh.

Vùng ảnh trơn (smooth) thì các pixel trong vùng ảnh đó có giá trị xấp xỉ / gần bằng nhau, vì vậy khi tính toán đạo hàm sẽ gần bằng zero. Đạo hàm bằng 0 thể hiện không có biến thiên về giá trị (mức sáng) (tham khảo bài viết Ý nghĩa Đạo Hàm). Điều này có nghĩa là độ dốc của các pixel trong vùng ảnh trơn gần bằng zero. Đạo hàm dương tại một pixel thể hiện rằng biến thiên mức sáng đang ở chiều hướng đi lên, ngược lại đạo hàm âm tại một pixel cho biết biên thiên mức sáng tại đó đang giảm dần. Nói tóm gọn lại gradient của ảnh chính là đạo hàm ảnh.

Bộ lọc Laplacian và Sobel

Hai bộ lọc phổ biến để tính gradient của ảnh là bộ lọc Laplacian và Sobel.

OpenCV cũng đã hiện thực các hàm filter tính gradient cho Sobel và Laplacian, tài liệu:

gradient.py

import cv2
import numpy as np

def scale_to_0_255(img):
    min_val = np.min(img)
    max_val = np.max(img)
    new_img = (img - min_val) / (max_val - min_val) # 0-1
    new_img *= 255
    return new_img
    
img = cv2.imread('girl_10.jpg',0)

laplacian = cv2.Laplacian(img, cv2.CV_64F)
sobelx = cv2.Sobel(img, cv2.CV_64F, 1, 0, ksize=3)
sobely = cv2.Sobel(img, cv2.CV_64F, 0, 1, ksize=3)
sobelxy = cv2.Sobel(img, cv2.CV_64F, 1, 1, ksize=3)

print('[Before Scale] laplacian image min-max:', np.min(laplacian), '-', np.max(laplacian))

cv2.imwrite('before_scale-laplacian.jpg', laplacian)
cv2.imwrite('before_scale-sobelx.jpg', sobelx)
cv2.imwrite('before_scale-sobely.jpg', sobely)
cv2.imwrite('before_scale-sobelxy.jpg', sobelxy)

laplacian = scale_to_0_255(laplacian)
sobelx =scale_to_0_255(sobelx)
sobely = scale_to_0_255(sobely)
sobelxy = scale_to_0_255(sobelxy)
print('[After Scale] laplacian image min-max:', np.min(laplacian), '-', np.max(laplacian))

cv2.imwrite('laplacian.jpg', laplacian)
cv2.imwrite('sobelx.jpg', sobelx)
cv2.imwrite('sobely.jpg', sobely)
cv2.imwrite('sobelxy.jpg', sobelxy)

Lưu rằng sau khi áp dụng toán tử convolution, miền giá trị của các pixel có thể vượt ngưỡng 0-255. Do đó, ta cần scale miền giá trị về 0-255 để có thể visualize dưới dạng ảnh. Một số bạn không chú ý có thể bỏ lỡ điều này.

norm image for visualize gradient image

Với đoạn kết trên ta có thể visualize ảnh gradient sau khi áp dụng các bộ lọc. Kernel size cũng có ảnh hưởng đến kết quả ảnh sau khi convolve. Điều chỉnh kích thước của kernel size cần phù hợp với độ phân giải ảnh đầu vào.

Ảnh gradient có tác dụng là nổi rõ cạnh trong ảnh.


Cảm ơn bạn đã theo dõi bài viết. Hãy kết nối với tớ nhé!


Danh sách bài viết series OpenCV: