Bộ lọc gauss trong xử lý ảnh
4. Lọc Gaussian Bài viết này sẽ giới thiệu cách sử dụng tích chập trong OpenCV và một số bộ lọc cơ bản để thực hiện lọc hình ảnh ví dụ như làm mờ hoặc tăng độ sắc nét cho ảnh gốc. Bài viết gồm các nội dung chính sau: Trước khi bắt đầu vào từng phần cụ thể, hãy quan sát đoạn code mẫu dùng để lọc ảnh. Chi tiết chức năng từng đoạn code sẽ được giới thiệu ở các phần tương ứng. Python
C++
1. Giới thiệu về mặt nạ tích chập (convolution kernel) trong xử lý ảnh Trong xử lý ảnh, mặt nạ tích chập là một ma trận 2D được sử dụng để lọc ảnh. Còn được gọi là ma trận tích chập, mặt nạ tích chập thường là ma trận vuông MxN, trong đó cả M và N đều là số nguyên lẻ (ví dụ: 3 × 3, 5 × 5, 7 × 7, v.v.). Xem ma trận ví dụ 3 × 3 ở dưới. Các mặt nạ như vậy có thể được sử dụng để thực hiện các phép toán trên mỗi pixel của hình ảnh để đạt được hiệu ứng mong muốn (như làm mờ hoặc làm sắc nét hình ảnh). Lý do cần làm mờ ảnh: – Làm giảm một số loại nhiễu nhất định trong hình ảnh. Vì lý do này, làm mờ thường được gọi là làm mịn. – Để xóa phông nền như thực hiện chế độ chụp chân dung (Portrait) ở trên máy ảnh của thiết bị di động. 2. Sử dụng mặt nạ để làm mờ hoặc tăng độ nét của ảnh Việc lọc ảnh gốc được thực hiện bằng cách tích chập mặt với ảnh. – Giả sử rằng tâm của mặt nạ được đặt trên một pixel cụ thể (p), trong một hình ảnh. – Sau đó, nhân giá trị của mỗi phần tử trong mặt nạ (1 trong trường hợp ma trận mặt nạ ví dụ ở phần 1), với phần tử pixel tương ứng (tức là cường độ pixel của nó) trong ảnh gốc. – Tính tổng kết quả của các phép nhân đó và tính giá trị trung bình. – Cuối cùng, thay thế giá trị của pixel (p) bằng giá trị trung bình mà vừa tính toán. Bây giờ chúng ta tìm hiểu cách triển khai áp dụng mặt nạ tích chập để làm mờ hoặc làm sắc nét ảnh trong OpenCV. (Bạn cũng có thể truy cập tại đây để xem hướng dẫn và chạy tất cả các ví dụ mà không cần phải cài đặt bất cứ gì trên máy tính của mình). Hình ảnh dưới đây sẽ được sử dụng cho tất cả các ví dụ tiếp theo. 3. Sử dụng mặt nạ đồng nhất (Identity Kernel) trong OpenCV Trước khi giới thiệu cách làm mờ và làm sắc nét ảnh bằng mặt nạ, trước tiên hãy tìm hiểu về mặt nạ đồng nhất. Mặt nạ đồng nhất là một ma trận vuông, trong đó phần tử ở giữa là 1 và tất cả các phần tử khác bằng 0: Ma trận đồng nhất đặc biệt vì khi nhân nó với bất kỳ ma trận nào khác sẽ trả về ma trận ban đầu. Trong đoạn code bên dưới, chúng ta sẽ sử dụng Mặt nạ đồng nhất ở trên để thể hiện việc lọc sẽ không thay đổi hình ảnh ban đầu. Bắt đầu bằng cách khai báo OpenCV và Numpy: Python
C++
Tiếp theo ta có đoạn code thực hiện các việc sau: – Đọc hình ảnh gốc – Xác định mặt nạ đồng nhất, sử dụng mảng NumPy 3 × 3 – Sử dụng hàm filter2D() trong OpenCV để thực hiện thao tác lọc tuyến tính – Hiển thị ảnh gốc và ảnh đã lọc, sử dụng imshow() – Lưu hình ảnh đã lọc, sử dụng imwrite() Cú pháp của hàm filter2D(): filter2D(src, ddepth, kernel) Hàm yêu cầu ba đối số đầu vào: – Đối số đầu tiên là hình ảnh gốc – Đối số thứ hai là ddepth, cho biết độ sâu của hình ảnh thu được. Giá trị -1 cho biết rằng hình ảnh kết quả sẽ có cùng độ sâu với ảnh gốc – Đối số cuối cùng là mặt nạ áp dụng cho việc lọc Python
C++
4. Làm mờ ảnh (blurring) sử dụng mặt nạ tích chập 2D tùy biến Tiếp theo, bài viết sẽ trình bày cách làm mờ hình ảnh. Chúng ta sẽ cần xác định một mặt nạ tùy chỉnh và sử dụng hàm filter2D() trong OpenCV để áp dụng thao tác lọc trên ảnh nguồn. Bắt đầu bằng cách xây dựng một mặt nạ 5 × 5, chỉ bao gồm số 1, rồi chia mặt nạ cho 25. Tại sao vậy? Trước khi áp dụng bất kỳ phép tích chập nào cho một hình ảnh, sử dụng ma trận tích chập 2D, thì cần đảm bảo rằng tất cả các giá trị đều được chuẩn hóa. Điều này được thực hiện bằng cách chia mỗi phần tử của mặt nạ cho số phần tử trong mặt nạ, trong trường hợp này là 25. Điều này đảm bảo tất cả các giá trị nằm trong phạm vi [0,1]. Bây giờ sử dụng hàm filter2D() để lọc hình ảnh. Hàm này có thể được sử dụng để lọc ảnh, với bất kỳ mặt nạ nào do người dùng xác định. Python
C++
5. Làm mờ ảnh sử dụng hàm có sẵn trong OpenCV Chúng ta cũng có thể làm mờ hình ảnh bằng cách sử dụng hàm blur() có sẵn trong OpenCV. Hàm này được sử dụng để làm mờ hình ảnh mà không cần xác định cụ thể mặt nạ. Chỉ cần chỉ định kích thước mặt nạ ksize, sau đó, hàm sẽ tạo ra một mặt nạ có kích thước như khai báo và áp dụng nó vào hình ảnh gốc. Đoạn code bên dưới sử dụng hàm blur() sẽ tạo ra đầu ra giống như ví dụ trên (sử dụng hàm filter2d()). Python
C++
6. Áp dụng bộ lọc Gauss để làm mờ ảnh Trong phần này, chúng ta sẽ tìm hiểu cách sử dụng bộ lọc Gaussian trong OpenCV để làm mờ hình ảnh. Bản chất của bộ lọc Gaussian là thực hiện phép toán trung bình có trọng số, trái ngược với trung bình đồng nhất được mô tả trong mục 3. Cụ thể bộ lọc Gaussian làm mờ trọng số các giá trị pixel, dựa trên khoảng cách của chúng từ tâm mặt nạ. Các điểm ảnh xa trung tâm hơn có ít ảnh hưởng hơn đến mức trung bình có trọng số. Để thực hiện bộ lọc Gaussian thì sử dụng hàm GaussianBlur() với cú pháp sau: GaussianBlur(src, ksize, sigmaX[, dst[, sigmaY[, borderType]]]) Hàm GaussianBlur() yêu cầu bốn đối số đầu vào: – Đối số đầu tiên chỉ định hình ảnh gốc muốn lọc. – Đối số thứ hai là ksize, xác định kích thước của mặt nạ Gaussian. Trong đoạn code ví dụ đang sử dụng kích thước 5 × 5. – Hai đối số cuối cùng là sigmaX và sigmaY, cả hai đều được đặt là 0. Đây là độ lệch chuẩn của mặt nạ Gaussian, theo hướng X (ngang) và Y (dọc). Mặc định giá trí của sigmaY là 0. Nếu đặt sigmaX bằng 0, thì độ lệch chuẩn được tính từ kích thước mặt nạ (chiều rộng và chiều cao tương ứng). Các đối số này cũng là các giá trị dương khác lớn hơn 0. Python 0C++ 1
7. Áp dụng bộ lọc trung vị (Median) để làm mờ ảnh Trong OpenCV có hỗ trợ hàm medianBlur() có chức năng áp dụng bộ lọc trung vị để làm mờ ảnh. Đối với bộ lọc trung vị, mỗi pixel trong ảnh gốc được thay thế bằng giá trị trung bình của các pixel ảnh trong vùng mặt nạ. Cú pháp của hàm medianBlur(): medianBlur(src, ksize) Hàm có 2 đối số: – Đối số đầu tiên là hình ảnh gốc – Đối số thứ 2 là kích thước mặt nạ, phải là số nguyên dương và lẻ Python 2C++ 3Xem kết quả làm mờ sử dụng bộ lọc trung vị thể hiện ở hình bên dưới. Có thể thấy rằng đối với cùng một kích thước mặt nạ, hiệu quả làm mờ của bộ lọc trung vị nổi bật hơn bộ lọc Gaussian. Bộ lọc trung vị thường được sử dụng để giảm nhiễu dạng ‘salt and pepper’ trong ảnh.
8. Tăng độ nét (sharpening) của ảnh bằng mặt nạ tích chập 2D tùy biến Mặt nạ tích chập 2D cũng có thể được dùng làm sắc nét hình ảnh. Đầu tiên xác định một mặt nạ 2D tùy chỉnh, sau đó sử dụng hàm filter2D() để áp dụng phép toán tích chập cho hình ảnh. Đoạn code mẫu ở dưới xây dựng một mặt nạ 3 × 3 để làm sắc nét ảnh. Python 4C++ 5Kết quả được thể hiện ở hình bên dưới. Hình ảnh được làm sắc nét bên phải cho thấy những vết nứt trên gỗ mà trước đây không thể nhìn thấy được.
9. Áp dụng lọc song phương (Bilateral Filtering) trong OpenCV Mặc dù làm mờ cũng được xem là một cách hiệu quả để giảm nhiễu trong hình ảnh, nhưng thường không nên làm mờ toàn bộ hình ảnh, vì các chi tiết quan trọng và các cạnh sắc nét có thể bị mất. Trong những trường hợp như vậy, bộ lọc song phương có thể hiệu quả hơn. – Phương pháp này lọc một cách có lựa chọn để làm mờ các pixel có cường độ tương tự trong một vùng lân cận. Các cạnh được giữ nguyên. – Phương pháp này cho phép kiểm soát không chỉ kích thước không gian của bộ lọc mà còn cả mức độ bao gồm các pixel lân cận trong đầu ra được lọc. Điều này được thực hiện, dựa trên sự thay đổi về cường độ màu của chúng và cũng như khoảng cách từ pixel được lọc. Lọc song phương về cơ bản áp dụng phương pháp làm mờ Gaussian 2D (có trọng số) cho hình ảnh, đồng thời xem xét sự thay đổi về cường độ của các pixel lân cận để giảm thiểu việc làm mờ gần các cạnh (mà muốn giữ nguyên). Điều này có nghĩa là dạng của mặt nạ phụ thuộc vào nội dung hình ảnh cục bộ, tại mọi vị trí pixel. Ví dụ chúng ta đang cần lọc một vùng trong hình ảnh, gần một cạnh. Bộ lọc làm mờ Gaussian đơn giản sẽ làm mờ cạnh vì nó nằm gần vùng được lọc (gần tâm của bộ lọc Gaussian). Nhưng bộ lọc song phương có thể phân biệt được cạnh, bởi vì nó cũng xem xét sự khác biệt về cường độ pixel. Vì vậy, nó sẽ tính toán trọng lượng thấp hơn nhiều cho các pixel nằm dọc theo cạnh, do đó giảm ảnh hưởng của chúng lên vùng được lọc. Các vùng có cường độ đồng đều hơn sẽ bị mờ nặng hơn, vì chúng không liên kết mạnh với các cạnh. Trong OpenCV, hàm bilateralFilter() được sử dụng để thực thi bộ lọc song phương. Hàm có cú pháp như sau: bilateralFilter(src, d, sigmaColor, sigmaSpace) Hàm có 4 đối số: – Đối số đầu tiên của hàm là ảnh gốc. – Đối số tiếp theo d, xác định đường kính của vùng lân cận pixel được sử dụng để lọc. – Hai đối số tiếp theo, sigmaColor và sigmaSpace xác định độ lệch chuẩn của phân bố cường độ màu (1D) và phân bố không gian (2D) tương ứng. + Tham số sigmaSpace xác định phạm vi không gian của mặt nạ, theo cả hướng x và y (giống như bộ lọc mờ Gaussian). + Tham số sigmaColor xác định phân phối Gaussian một chiều, chỉ định mức độ mà sự khác biệt về cường độ pixel có thể được chấp nhận. Giá trị cuối cùng (có trọng số) cho một pixel trong hình ảnh kết quả phụ thuộc trọng số không gian và cường độ của nó. Vì vậy, – Các pixel tương tự và gần pixel được lọc sẽ có ảnh hưởng – Pixel ở xa pixel được lọc sẽ có ít ảnh hưởng (do không gian Gaussian) – Các pixel có cường độ khác nhau sẽ có ít ảnh hưởng (do cường độ màu Gaussian), ngay cả khi chúng ở gần tâm của mặt nạ Python 6C++ 7Kết quả bộ lọc song phương được thể hiện ở hình dưới đây. Các vùng có cường độ điểm ảnh đồng đều hơn đã được làm mịn (làm mờ), trong khi vẫn giữ được các vết nứt nhỏ (các cạnh) trên gỗ. Lọc song phương là một kỹ thuật rất hiệu quả, nhưng có nhược điểm là tốn kém về mặt tính toán (đặc biệt là đối với kích thước mặt nạ lớn). Vì vậy, tùy thuộc vào ứng dụng cụ thể mà lựa chọn bộ lọc cho phù hợp.
Kết luận Bài viết đã giới thiệu về tích chập và cách sử dụng để lọc hình ảnh như làm mờ hoặc làm sắc nét hình ảnh. Ngoài ra trình bày cách sử dụng hàm filter2D() trong OpenCV để thực hiện lọc với các mặt nạ tích chập 2D tùy biến. Sau đó đã giới thiệu một số bộ lọc quan trọng được xây dựng sẵn trong OpenCV bộ lọc Gaussian, bộ lọc trung vị và bộ lọc song phương. Các đoạn code mẫu cùng với hình ảnh kết quả đã làm rõ hơn hoạt động của các bộ lọc này. Biên dịch: Thảo Nguyễn Để cập nhật tin tức công nghệ mới nhất và các sản phẩm của công ty AIoT JSC, vui lòng truy cập link: http://aiots.vn hoặc linhkienaiot.com |