ảnh màu và ảnh xám được lưu trữ khác nhau thế nào?
Ảnh là dữ liệu máy tính lưu trữ thông tin về màu sắc để truyền tải đến người dùng. Ảnh là dữ liệu do đó cũng tốn vùng nhớ, cũng có thể nén, có thể mất dữ liệu như những file khác. Và đặc biệt ảnh là loại dữ liệu quý giá giúp người dùng hiểu vấn đề nhanh hơn đọc chữ. Mỗi ảnh là một ma trận, với một pixel là 1 giá trị trong ma trận. Với ma trận có thể cộng trừ nhân chia, hoán vị, để biến đổi ma trận theo ý muốn. Và từ ma trận có thể chuyển đổi thành vecto và ngược lại (đại số tuyến tính và hình học). Các kiểu ảnh phổ biến là:
Như ảnh dưới ta thấy ảnh RGB được tạo thành từ 3 ma trận Từ định nghĩa suy ra được ảnh màu tốn không gian lưu trữ gấp 3 lần ảnh trắng đen và ảnh xám,
Ảnh nhị phânĐoạn code bên dưới đọc ảnh nhị phân có tên là hill.jpg và lấy một giá trị pixel trong ma trận tại dòng 3 cột 5 cv::Mat img = cv::imread("hill.jpg"); uchar p = img.at(3, 5); Ảnh màuDo ảnh màu có 3 kênh màu nên kết quả trả về lấy giá trị từ 3 ma trận. Đoạn code bên dưới đọc ảnh RGB có tên là hill.jpg và lấy một giá trị pixel trong ma trận tại dòng 3 cột 5 cv::Vec3b p = img.at(3, 5); Để gán ngược giá trị cho dòng 3 cột 5 với giá trị ngẫu nhiên: img.at(3, 5) = cv::Vec3b(112, 113, 114); Và tùy theo độ sâu màu mà mỗi Mat lại có 1 kiểu giá trị khác nhau. Độ sâu màu thể hiện sự chân thực của màu sắc, nếu ảnh chỉ có 8 bit màu chỉ hiển thị được 256 màu như các game thời xưa, ảnh 16 bit màu sẽ đẹp hơn 1 chút, ảnh 24 bit, sẽ càng đẹp và chân thực hơn: Ảnh xámĐể tạo ảnh xám từ ảnh màu chúng ta lấy giá trị trung bình của các kênh màu, sau đó gán ngược lại để được ảnh xám. for (int row = 0; row < img.rows; row++) for (int col = 0; col < img.cols; col++) cv::Vec3b p = img.at(row, col); int avg = (p[0] + p[1] + p[2]) /3; img.at(row, col) = cv::Vec3b(avg, avg, avg); 3 kênh màu cùng chung giá trị thì lãng phí bộ nhớ, do đó hàm chuyển sang ảnh xám sẽ loại bỏ bớt 2 kênh màu không cần thiết. Để có hình ảnh được đẹp nhất gười ta không chia đều mà tính theo công thức sau: Chuyển đổi giữa các kiểu ảnhChuyển đổi ảnh màu thành ảnh xám và ảnh xám thành trắng đen là làm mất dữ liệu, do đó không thể chuyển ngược lại. Còn chuyển đổi giữa các hệ màu với nhau thì không mất dữ liệu nên chuyển đổi qua lại được. Và các hàm này opencv đã cung cấp sẵn, chỉ cần gọi hàm và truyền tham số mong muốn. Chuyển ảnh màu thành ảnh xám: cv::cvtColor(matBgr, matGray, cv::COLOR_BGR2GRAY);
Chuyển ảnh RGB sang HSV cv::cvtColor(matBgr, matGray, cv::COLOR_BGR2HSV); Còn chuyển từ ảnh xám sang nhị phân thì phải phân ngưỡng. Do đó không thể chuyển từ ảnh màu sang trắng đen được mà phải chuyển sang ảnh xám trung gian. Đọc thêm Lý thuyết về phân đoạn ảnh để biết cách tạo ra ảnh nhị phân. |