Xác định độ nhòe của ảnh ứng dụng trong lấy nét tự động (auto focus). Trong một số ứng dụng khác cũng cần tính độ nhòe của ảnh để kiểm tra chất lượng input.
Các bài toán cần xác định độ nhòe chủ yếu là nhận dạng hình ảnh. Khi ảnh nhòe sẽ làm mất đi các đặc trưng hoặc gây nhiễu. Do đó cần loại bỏ các ảnh bị nhòe trước khi xử lý.
Thí dụ nhận diện khuôn mặt, đọc biển số xe máy – xe hơi.
Lý thuyết
Về cảm quan của người bình thường, ảnh mờ sẽ có các vấn đề sau:
– Độ tương phản thấp (các pixel liền kề có giá trị không khác biệt nhiều)
– Có các đường kéo dài theo chiều chuyển động
Lý do gây ra nhòe là camera không bắt kịp chuyển động. Nói cách khác là FPS của camera thấp, nghĩa là thời gian phơi sáng cao. Trong khoảng thời gian phơi sáng đó vật thể chuyển động thì camera sẽ thu nhận rồi tổng hợp lại. Như vậy muốn bắt vật thể chuyển động nhanh cần có camera có FPS cao.
Camera có 30FPS thì thời gian phơi sáng là 1/30 giây. Với người đang di chuyển thì nên dùng camera có 30FPS trở lên để hình ảnh không bị nhòe.
Phơi sáng là khái niệm của nhiếp ảnh, tính từ lúc mở màn trập đến lúc đóng màn trập
Giải thuật
Theo lý thuyết, ảnh bị nhòe là ảnh có độ tương phản thấp. Độ tương phản thấp thì tìm được số cạnh ít (edge). Vậy dựa vào số edge mà phát hiện ảnh có nhòe hay không.
Nhìn các hình bên dưới, hình nào càng nhòe thì histogram càng ít nhấp nhô
Trong các giải thuật thì hàm Laplacian() được sử dụng nhiều nhất. Bản chất nó cũng là bộ lọc Sobel để tìm ra số cạnh, bạn có thể đọc thêm tại bài Làm mịn ảnh
Code
1 2 3 4 5 6 7 8 9 10 11 |
int CalcBlurryImage(cv::Mat matInput) { cv::Mat gray = TGMTimage::ConvertToGray(matInput); cv::Mat laplacianImage; cv::Laplacian(gray, laplacianImage, CV_64F); cv::Scalar mean, stddev; // 0:1st channel, 1:2nd channel and 2:3rd channel cv::meanStdDev(laplacianImage, mean, stddev, cv::Mat()); double variance = stddev.val[0] * stddev.val[0]; return variance; } |
Áp dụng function trên ta có được chỉ số khác nhau giữa các ảnh