Xin chào anh em Mì Ai và chúc mừng năm mới 2020. Chắc hẳn anh em làm xử lý ảnh sẽ thường xuyên phải làm việc với video. Thay vì xử lý 1 frame như khi làm việc với ảnh, anh em sẽ phải đọc lần lượt từng frame của video và đôi lúc anh em sẽ gặp tình trạng frame bị mờ. Khi frame bị mờ như vậy việc xử lý tiếp theo sẽ rất vất vả và nhiều khi không mạng lại kết quả mong muốn. Do đó, hôm nay mình sẽ chia sẻ cùng anh em một kỹ thuật phát hiện và xử lý ảnh bị mờ nhé.
Phần 1. Cách phát hiện frame bị mờ
Chưa xét đến video vội, chúng ta hãy cùng làm việc với bài toán đơn giản hơn là “Cho một ảnh đầu vào, phát hiện ảnh bị mờ hay không?”. Để làm được điều này chúng ta sử dụng một hàm đơn giản của OpenCV là
cv2.Laplacian(input_image, cv2.CV_64F).var()
Code language: CSS (css)
Lý thuyết về hàm này thì anh em đọc tai Paper này nếu như muốn ăn thêm cơm nhé : tại đây. Còn mình chỉ hiểu nôm na là nó nhân cái ảnh của ta với cái ma trận này để đo độ focus của ảnh (Mì ăn liền style ah):
[0 1 0]
[1 -4 1]
[0 1 0]
Code language: JSON / JSON with Comments (json)
Sau khi nhân xong sẽ trả ra cho anh em 1 con số và anh em chỉ cần định nghĩa cho mình 1 blur threshold, nếu như con số trả ra < threshold đó thì anh em kết luận là ảnh mờ và ngược lại.
Ví dụ bây giờ các bạn có thể clone git này về :
git clone https://github.com/thangnch/MiAI_Blur_Detection .
Code language: PHP (php)
và chạy thử đoạn code trong file blur_detect.py xem nhé:
import cv2
# Duong dan den file anh
image_file= "test02.jpg"
# Dinh nghia blur threshold
blur_threshold=100
# Doc anh tu file
image = cv2.imread(image_file)
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
# Tinh toan muc do focus cua anh
focus_measure = cv2.Laplacian(gray, cv2.CV_64F).var()
if focus_measure < blur_threshold:
text = "Blurry pix"
cv2.putText(image, "{} - FM = {:.2f}".format(text, focus_measure), (30, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 3)
else:
text = "Fine pix"
cv2.putText(image, "{} - FM = {:.2f}".format(text, focus_measure), (30, 50), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 3)
# Hien thi anh
cv2.imshow("Image", image)
key = cv2.waitKey(0)
Code language: PHP (php)
Mình có chạy thử với 2 ảnh thì đã phát hiện khá chuẩn:
Sau khi nhận biết được ảnh nào mờ rồi thì anh em có thể áp dụng các biện pháp Sharpen như thông thường.
Phần 2 – Phát hiện và kỹ thuật xử lý frame bị mờ từ video
Như vậy chúng ta đã biết cách xác định frame ảnh có bị mờ hay không. Vậy chúng ta cần làm gì khi trích xuất frame từ video ra (để nhận diện Biển số xe chẳng hạn) mà bị mờ.
Kỹ thuật mình hay sử dụng là thay vì lấy 1 frame và xử lý ngay thì mình thường lấy khoảng 5 frames liên tiếp sau đó viết một hàm nhỏ để check xem trong 5 frame đó, đâu là ảnh ít mờ nhất và mình sẽ pick ảnh đó để xử lý tiếp.
Ví dụ đoạn code sau:
def get_best_images(input_frames):
# Sap xep cac input_frames theo muc do Focus giam dan
input_frames = sorted(input_frames, key=lambda img : cv2.Laplacian(img[0], cv2.CV_64F).var(), reverse=True)
# Lay khung hinh co muc do focus tot nhat
best_image = input_frames[:1]
return best_image
Code language: PHP (php)
Các bạn có thể thử và sẽ thấy chất lượng ảnh đầu ra từ video tốt hơn nhiều( ta có thể chọn được ảnh tốt nhất mà) và anh em cũng dễ dàng xử lý tiếp hơn rất nhiều. Sau khi nhận biết được ảnh nào mờ rồi thì anh em có thể áp dụng các biện pháp Sharpen như thông thường.
Mình xin tạm dừng bài này tại đây, hi vọng anh em đã có thêm 1 trick nữa để phục vụ quá trình học tập, nghiên cứu AI, ML,DL…
Chúc mừng năm mới!
Hãy join cùng cộng đồng Mì AI nhé!
Fanpage: http://facebook.com/miaiblog
Group trao đổi, chia sẻ: https://www.facebook.com/groups/miaigroup
Website: https://miai.vn
Youtube: http://bit.ly/miaiyoutube
Thanks bài tham khảo về xử lý video của bác Tuan Long: tại đây và của Adrian Rosebrock tại đây.