Cấu tạo tự nhiên của mắt nhạy với 3 màu Red-Green-Blue. Dựa vào đó các thiết bị hiển thị màu đa số đều cấu tạo để phù hợp với mắt người. Các hệ màu khác được sử dụng chủ yếu cho in ấn, xử lý dữ liệu hoặc cần hiển thị màu đẹp hơn.
Ví dụ: màn hình LCD máy tính cấu tạo mỗi pixel màu từ 3 kênh màu, để thay đổi giá trị của pixel màu người ta thay đổi giá trị của từng kênh.
Ảnh nhị phân và ảnh xám
Ảnh nhị phân và ảnh xám được tạo bởi 1 kênh màu, mỗi pixel được tạo bởi 1 màu duy nhất. Các hệ màu khác được tạo từ nhiều kênh màu, có nghĩa là tách từng kênh ra ta sẽ được ảnh xám. Lưu ý OpenCV sắp kênh màu theo thứ tự B-G-R
1 2 3 4 5 6 7 8 |
cv::Mat src = cv::imread("image.jpg", CV_LOAD_IMAGE_COLOR); cv::Mat bgr[3]; cv::split(src, bgr); cv::imshow("blue", bgr[0]); cv::imshow("green", bgr[1]); cv::imshow("red", bgr[2]); |
Tuy rằng code tách ra 3 kênh màu B-G-R, nhưng khi display thì tất cả đều là ảnh xám.
Hệ màu RGB
Hình bên dưới là các pixel được phóng lớn, có các màu red-green-blue được lặp lại, cứ 3 màu được 1 pixel
Hình ảnh đa số cấu tạo từ 3 kênh màu Red-Green-Blue. Tuỳ theo từng trường hợp sử dụng mà có thêm kênh thứ tư là kênh Alpha (độ trong suốt). Khi tách mỗi kênh màu ta được 1 ma trận các giá trị từ [0;255] với 8 bits, tương tự là [0;65535] với 16 bits,….
Code để tách 1 kênh màu, cụ thể là màu green:
1 2 3 4 5 6 7 8 9 10 |
cv::Mat src = cv::imread("img.jpg", CV_LOAD_IMAGE_COLOR); cv::Mat bgr[3], green; cv::split(src, bgr); bgr[0] = 0; //delete blue channel bgr[2] = 0; //delete red channel cv::merge(bgr, 3, green); cv::imshow("green", green); //green channel |
Hàm cv::merge dùng để merge nhiều kênh màu vào 1 ảnh, số 3 có nghĩa là input có 3 kênh màu.
Hệ màu HSV
Hệ màu HSV dùng để xử lý màu rất thuận tiện, vì mỗi màu sẽ có 1 giá trị Hue [0;360], còn Value và Saturation chỉ thị độ sáng và độ bão hoà của màu. Hệ màu này được ứng dụng để theo dõi đối tượng theo màu
Có vài nơi gọi là HSB, Value được thay bằng Brightness nhưng ngữ nghĩa như nhau. Code bên dưới dùng để convert từ BGR sang HSV, còn các phép biến đổi cũng tương tự:
1 2 3 4 5 |
cv::Mat src = cv::imread("img.jpg", CV_LOAD_IMAGE_COLOR); cv::Mat hsv; cv::cvtColor(src, hsv, CV_BGR2HSV); cv::imshow("hsv", hsv); |
Hệ màu HSL
Hệ màu HSL viết tắt của Hue, Saturation, và Luminance. Nó cũng tương tự như HSV và cũng phù hợp cho việc lọc màu.
Code bên dưới dùng để convert từ BGR sang HSL
1 2 3 4 5 |
cv::Mat src = cv::imread("img.jpg", CV_LOAD_IMAGE_COLOR); cv::Mat hls; cv::cvtColor(src, hls, CV_BGR2HLS); cv::imshow("hls", hls); |
Hệ màu CMYK
Hệ màu CMYK chủ yếu dùng cho in ấn nên không xét nhiều trong lập trình xử lý ảnh. Để chuyển từ BGR sang CMYK dùng code bên dưới ( Nguồn)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
// RGB to CMYK conversion void rgb2cmyk(cv::Mat& img, std::vector<cv::Mat>& cmyk) { // Allocate cmyk to store 4 componets for (int i = 0; i < 4; i++) { cmyk.push_back(cv::Mat(img.size(), CV_8UC1)); } // Get rgb std::vector<cv::Mat> rgb; cv::split(img, rgb); // rgb to cmyk for (int i = 0; i < img.rows; i++) { for (int j = 0; j < img.cols; j++) { float r = (int)rgb[2].at<uchar>(i, j) / 255.; float g = (int)rgb[1].at<uchar>(i, j) / 255.; float b = (int)rgb[0].at<uchar>(i, j) / 255.; float k = std::min(std::min(1- r, 1- g), 1- b); cmyk[0].at<uchar>(i, j) = (1 - r - k) / (1 - k) * 255.; cmyk[1].at<uchar>(i, j) = (1 - g - k) / (1 - k) * 255.; cmyk[2].at<uchar>(i, j) = (1 - b - k) / (1 - k) * 255.; cmyk[3].at<uchar>(i, j) = k * 255.; } } } // Test rgb2cmyk function int main(int argc, char** argv) { // TODO: change filename cv::Mat src = cv::imread("c:\\filename.jpg"); std::vector<cv::Mat> dst; rgb2cmyk(src, dst); // Display results cv::imshow("src", src); cv::imshow("c", dst[0]); cv::imshow("m", dst[1]); cv::imshow("y", dst[2]); cv::imshow("k", dst[3]); cv::waitKey(); return 0; } |