Một số phương pháp xử lý ảnh cơ bản (Phần 4)

Công nghệ

Một bức ảnh màu bao gồm các kênh màu: đỏ, xanh lá cây, và xanh dương. Bạn đọc hẳn không xa lạ với các tương tác với từng điểm ảnh thông qua thao tác với mảng, ma trận numpy. Tuy nhiên, làm thế nào để ta có thể chia hình ảnh ra thành các thành phần riêng biệt?

Và các bạn có thể đoán rằng, chia trong tiếng Anh là split. Do đó, hẳn có hàm cv2.split nào đó tồn tại để làm công việc này. Trước hết, chúng ta sẽ quan sát bức ảnh phong cảnh về mùa hè dưới đây, bao gồm màu đỏ của hoa phượng hay màu xanh nước biển của bình nước trên trần tòa nhà, vân vân và mây mây. So với bức ảnh gốc, các kênh màu có sự chuyển biến giá trị màu rõ rệt trong khoảng giá trị mà chúng biểu diễn. Chúng ta sẽ cùng phân tích đoạn mã dưới đây.

Dòng 1-12, chúng ta làm tương tự như các bài học trước. Tuy nhiên, ở dòng 14, ta sẽ sử dụng hàm cv2.split để chia giá trị kênh màu vào các biến tương ứng: r, g và b. Thông thường thì chúng ta sẽ nghĩ ngay tới thứ tự RGB, tuy nhiên, opencv lưu trữ ảnh RGB như mảng numpy ở trình tự ngược lại: trình tự BGR.

Dòng 16-19 hiển thị các bức ảnh lấy ra từ kênh màu tương ứng. Bên cạnh đó, bạn đọc có thể sử dụng cv2.merge – dòng 21, để ghép các kênh màu thành bức ảnh đọc vào ban đầu bằng cách truyền vào các giá trị lấy giá theo thứ tự tương ứng lúc ta đọc ảnh.

Một phương pháp khác để hiển thị kênh màu đó là chúng ta sẽ chỉ hiển thị giá trị thực của kênh màu. Trước hết, chúng ta vẫn sử dụng cv2.split để lấy ra các giá trị thành phần của bức ảnh. Sau đó, ta tạo lại bức ảnh với cài đặt toàn bộ các điểm ảnh khác ngoài giá trị kênh màu hiện tại thì đều bằng 0. Ở dòng 24, khởi tạo một ma trận z với kích thước là bức ảnh đang xét với giá trị tất cả các điểm ảnh là 0. Tiếp đó, để có thể tạo kênh màu đỏ được biểu diễn trong ảnh, ta gọi hàm cv2.merge để ghép kênh màu đỏ với hai kênh màu còn lại nhưng có giá trị điểm ảnh bằng 0. Ta thực hiện tương tự với các trường hợp còn lại ở dòng 26-27. Như vậy, ta thu được kết quả với kênh màu mà mỗi thành phần ảnh biểu diễn như sau:

Trong chuỗi bài học đọc về thị giác máy tính qua opencv và numpy, chúng ta mới chỉ tìm hiều về hệ màu RGB, tuy nhiên trong thực tế, có rất nhiều các hệ màu khác nhau được sử dụng rộng rãi. Hệ màu HSV – Hue-Saturation-Value, rất gần với cách mà còn người nghĩ và tiếp nhận màu sắc. Bên cạnh đó còn có hệ màu L*a*b*có thể điều chỉnh cách mà chúng ta cảm nhận màu sắc. OpenCV hỗ trợ rất nhiều hệ màu trong số đó. Và việc hiểu được cách con người cảm nhận màu sắc để áp dụng cho máy tính tiếp nhận vẫn còn là một trong những bài toán được nghiên cứu sôi nổi. Chi tiết hơn thì các bạn có thể tham khảo bài viết mở đầu của chuỗi bài này để có thêm góc nhìn về cách màu sắc hoạt động. Để không đi vào chi tiết quá trình cảm nhận màu sắc, chúng ta sẽ cùng nhau tìm hiểu về cách chuyển đổi hệ màu trong OpenCV. Ngoài ra, nếu bạn đọc nghĩ thị giác máy tính nên sử dụng một hệ màu khác ngoài RGB thì hãy thử nghiệm và thảo luận với mình nhé, còn đánh giá chi tiết sẽ được trình bày ở các bài đọc sau. Bây giờ, chúng ta sẽ tìm hiều về một số hàm hỗ trợ chuyển đổi hệ màu:

Dòng 1-13, ta thực hiện khai báo thư viện, định nghĩa tham số đầu vào, đọc và hiển thị hình ảnh. Tiếp đó, ở dòng 15, chúng ta chuyển đổi ảnh từ hệ màu RGB qua ảnh xám bằng cách cài đặt cờ cv2.COLOR_BGR2GRAY. Chuyển đổi qua hệ màu HSV và L*a*b* tương tự ở dòng 18-22. Kết quả đoạn mã thu được như sau:

Vai trò của hệ màu trong xử lý ảnh và thị giác máy tính vô cùng quan trong, tuy nhiên cũng khá phức tạp. Nếu bạn đọc vừa mới bắt đầu tu luyện bộ môn này, mình nghĩ rằng nghiên cứu xoay quanh hệ màu RGB không phải là ý tồi. Hẹn gặp lại bạn đọc ở bài học sau.