OpenCV

Tìm Hiểu Cấu Trúc Lưu Trữ Hình Ảnh Mat Trong OpenCV

Trong những bài viết trước mình đã hướng dẫn các bạn cơ bản về thư viện OpenCV. Trong các bài viết đó chúng ta có sử dụng cấu trúc dữ liệu Mat để lưu trữ data của hình ảnh. Và để hiểu rõ hơn về cấu trúc dữ liệu này sẽ hướng dẫn cho các bạn cách mà OpenCV lưu trữ data của hình ảnh trong cấu trúc dữ liệu này như thế nào cũng như cách sử dụng nó linh hoạt và dễ dàng nhất.

Giới thiệu

Trong những bài viết trước mình đã hướng dẫn các bạn cơ bản về thư viện OpenCV. Trong các bài viết đó chúng ta có sử dụng cấu trúc dữ liệu Mat để lưu trữ data của hình ảnh. Và để hiểu rõ hơn về cấu trúc dữ liệu này sẽ hướng dẫn cho các bạn cách mà OpenCV lưu trữ data của hình ảnh trong cấu trúc dữ liệu này như thế nào cũng như cách sử dụng nó linh hoạt và dễ dàng nhất.

Cấu trúc dữ liệu Mat

Chúng ta hãy nhìn qua hình dưới đây để thấy cách mà con người và máy tính cùng “nhìn” một hình ảnh. Cách mà con người nhìn chính là hình ảnh thực của nó. Phía máy tính chỉ hiểu hình ảnh ở những con số như hình ở dưới. Vì hình ảnh là một hình chữ nhật nên thông thường sẽ được hình dung dưới một Matrix chính vì vậy mà OpenCV xây dựng class Mat để lưu trữ thông tin hình ảnh cho gần gũi với người sử dụng.

mat_opencv_ss_1

 

Và dưới đây là hình mô phỏng ma trận lưu hình ảnh

matrix_in_opencv_ss2

Ma trận sẽ gồm các dòng và các cột. Hình dùng như chiều cao của hình ảnh sẽ bằng đúng số rows của matrix và chiều rộng của hình ảnh sẽ bằng đúng số cột của matrix. Và phần tử [row 0, colum 0] chính là đại diện cho 1 pixel của hình ảnh.

Và dưới đây là hình ảnh thực tế hơn về cách lưu hình ảnh ứng với bảng màu BGR. Chúng ta thấy tại phần tử thứ [row 0, column 0] là giá trị màu sắc của một pixel của hình ảnh. Và nó được lưu  với không gian màu BGR nên mỗi pixel sẽ có 3 kênh màu kế tiếp nhau là B Blue, G Green, R Red. Và đa số mỗi kênh màu sẽ được biểu diễn bằng 8bit unsinged char (uint8_t). Tương tự với các phần tử khác trong ma trận cũng có cấu trúc lưu trữ tương đương với phần tử [row 0, column 0].

matrix_opencv_ss_3

Sử dụng Mat trong OpenCV

Constructor và ý nghĩa của chúng

Lớp Mat trong OpenCV năm trong modules core của bộ thư viện OpenCV và năm trong namespace cv của bộ thư viện. Nếu chúng ta không khai báo sử dụng namespace cv ở đầu chương trình thì trong chương trình sử dụng phải bắt buộc có tiền tố cv đứng với đầu.

Ví dụ muốn sử dụng Mat phải khai báo là cv::Mat mat;

Các contructor thường sử dụng với Mat

Tham số thứ nhất chính là số dòng của ma trận hay nói cách khác là chiều cao của hình ảnh.

Tham số thứ hai chính là số cột của trận hay cũng nói cách khác chính là chiều rộng của hình ảnh.

Tham số type thứ ba là tham số mà chúng ta nên quan tâm và hiểu rõ nó và type có cấu trức hư dưới đây

CV_[Số bit cho 1 channel][Kiểu có dấu, không dấu, số thực]C[Số channel]

Ví dụ như

CV_8UC1: Có nghĩa là mỗi có 1 channel dùng 8bit không dấu để biểu diễn

CV_8UC3: Có nghĩa là mội pixel (một điểm ảnh) sẽ có 3 channel và ứng mới mỗi channel sẽ dùng 8bit không dấu để biểu diễn. (RGB, BRG,….).

CV_8UC4: Có nghĩa là mội pixel (một điểm ảnh) sẽ có 4 channel và ứng mới mỗi channel sẽ dùng 8bit không dấu để biểu diễn. (ARGB, BRGA).

Tương tự như constructor trên như thay vì truyền vào rows và cols thì chúng ta truyền vào size với với format Size(cols, rows)

Giống như contructor thứ nhất với đối số thứ ba là một option. Giá trị s có ý nghĩa là sẽ khởi tạo giá trị cho các phần tử trong Mat.

Constructor này tương tự như Constructor trên.

Các phương thức thường dùng với Mat

Phương thức trả về đối tượng Mat có dữ liệu giống với mat

Giống như phương thức trên nhưng phương thức này chúng ta phải truyền vào tham số là một OutputArray

Ví dụ

Tiếp theo chúng ta sẽ đi qua 3 phương thức khởi tạo các giá trị đặc biệt là zeros, ones, eyes.

Phương thức tạo một mat có các phần tử bằng giá trị 0, các tham số giống với tham số của Constructor. Phương thức này trả về một đối tượng Mat.

Giống phương thức trên thay vì truyền vào rows và cols thì chúng ta truyền vào size có format là Size(cols, rows).

Ví dụ:

Kết quả xuất ra là:

Hay ví dụ

Các bạn thấy rằng chúng hai trường hợp trên chúng ta truyền vào rows và cols bằng nhau như khác type thì kết quả như sau:

type = CV_8UC1: Thì matrix sẽ là 6 rows và 6 column

type = CV_8UC3: thì matrix sẽ là 6 rows và 18 column, hiểu ở mức độ liên quan đên hình ảnh thì mỗi pixel sẻ sử dụng 3 kênh màu. Kích thước column và 18 nhưng thực tế chiều rộng của hình ảnh vẫn là 6.

Phương thức này sẽ trả về một Mat có các phần tử mang giá trị 1.

Ví dụ

Kết quả

Phương thức static này khởi tạo một Mat có các phần tử trên đường chéo chính có giá trị 1 và các phần tử còn lại mang giá trị 0.

Ví dụ

Kết quả

Một ví dụ khác

Và kết quả

Chúng ta thấy rằng khi sử dụng phương thức eye này thì chỉ các phần thử có M[i, j] với i = j thì phần thử đó có giá trị bằng 1 còn lại các phần tử khác đều mang giá trị 0.

Tạo hình ảnh sử dụng Mat

Kết quả sau khi chạy chương trình

mat_opencv_ss4

Hoặc random các phần tử trong matrix trong khoảng 0, 255

Và kết quả khi show R trên Windows

mat_opencv_ss5

Bạn có thể chạy thử đoạn mã dưới đây để hiểu hơn về Mat trong thư viện OpenCV

Kết luận

Trong bài viết này mình giới thiệu cho các bạn về cấu trúc dữ liệu lưu trữ hình ảnh Mat sử dụng trong OpenCV. Ngoài việc sử dụng cấu trúc dữ liệu này để lưu trữ data hình ảnh thì cấu trúc dữ liệu này được sử dụng khá nhiều trong việc tính toán và sử dụng các bộ lọc (filter) trong OpenCV mà chúng ta sẽ tìm hiểu ở bài viết sau.

3 thoughts on “Tìm Hiểu Cấu Trúc Lưu Trữ Hình Ảnh Mat Trong OpenCV”

  1. Mình có 1 camera IDS với thư viện ueye.h, hình ảnh của camera được lưu trong vùng nhớ của nó dưới dạng sequence. Cho mình hỏi trong OPenCV có hàm nào để chuyển từ dạng đó về MAT để xử lí trong openCV được không?
    Cảm ơn Bạn!!!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.