Tóm tắt: Trong sản xuất điện ảnh và nội dung số, nhiều lỗi hình ảnh ở khâu hậu kỳ như hiện tượng dải màu bậc thang (banding) hay viền tách nền răng cưa bắt nguồn từ các thông số số hóa được chọn ngay khi ghi hình. Bài viết hệ thống hóa ba khái niệm nền tảng của ảnh số gồm độ phân giải, độ sâu bit và không gian màu (RGB, YCbCr, lấy mẫu màu, gam màu), đồng thời xây dựng một mô phỏng bằng ngôn ngữ Python để định lượng hiện tượng banding. Kết quả mô phỏng cho thấy với một dải chuyển màu hẹp chiếm 15% dải sáng, sau khi kéo giãn tương phản, dữ liệu 8-bit chỉ còn 40 bậc màu, trong khi 10-bit giữ được 154 bậc và 12-bit giữ được 616 bậc. Từ đó, bài viết đề xuất một số khuyến nghị lựa chọn định dạng ghi hình cho sinh viên và người làm phim, đồng thời cung cấp mã nguồn mở phục vụ giảng dạy tin học ứng dụng trong các trường nghệ thuật.
Từ khóa: ảnh số; độ sâu bit; không gian màu; lấy mẫu màu; banding; Python; sản xuất điện ảnh.
1. ĐẶT VẤN ĐỀ
Quá trình chuyển đổi từ phim nhựa sang công nghệ số đã thay đổi căn bản quy trình sản xuất điện ảnh. Ngày nay, từ khâu ghi hình, dựng phim, chỉnh màu, kỹ xảo đến phát hành, hình ảnh đều tồn tại dưới dạng dữ liệu số. Tuy nhiên, trong đào tạo tại các trường nghệ thuật, người học thường tiếp cận phần mềm ở mức thao tác giao diện mà chưa được trang bị hiểu biết về bản chất của dữ liệu ảnh số.
Một tình huống điển hình: nhóm sinh viên ghi hình cảnh hoàng hôn trên sông Hồng bằng máy ảnh ghi video 8-bit. Trên màn hình máy quay, bầu trời chuyển màu mượt mà. Khi đưa vào phần mềm DaVinci Resolve, kéo tương phản và tăng độ bão hòa, bầu trời xuất hiện các dải màu bậc thang rõ rệt. Nguyên nhân không nằm ở phần mềm hay kỹ năng chỉnh màu, mà ở các thông số số hóa được chọn trước khi ghi hình.
Xuất phát từ thực tế đó, bài viết hướng tới ba mục tiêu: (i) hệ thống hóa các khái niệm nền tảng về ảnh số dưới góc nhìn ứng dụng trong sản xuất phim; (ii) xây dựng mô phỏng định lượng hiện tượng banding bằng ngôn ngữ Python; (iii) đề xuất khuyến nghị thực tiễn về lựa chọn định dạng ghi hình và cung cấp mã nguồn phục vụ giảng dạy. Đây là bài mở đầu trong chuỗi nghiên cứu về ứng dụng tin học trong lĩnh vực Sân khấu – Điện ảnh và sản xuất nội dung số.
2. CƠ SỞ LÝ THUYẾT
2.1. Biểu diễn ảnh số dưới dạng ma trận
Cảm biến máy quay là một lưới gồm hàng triệu phần tử cảm quang, mỗi phần tử đo cường độ ánh sáng tại một vị trí và chuyển thành giá trị số. Sau quá trình xử lý (giải mảng lọc màu Bayer, cân bằng trắng, áp đường cong gamma), mỗi điểm ảnh (pixel) mang ba giá trị tương ứng ba kênh màu đỏ (R), xanh lục (G) và xanh lam (B) [5], [6].
Về mặt toán học, một ảnh màu là một mảng ba chiều kích thước H × W × 3, trong đó H là số hàng (chiều cao), W là số cột (chiều rộng). Hình 1 minh họa một ảnh kích thước 640 × 360 pixel và vùng phóng to 6 × 6 pixel, trong đó mỗi ô là một bộ ba giá trị (R, G, B).

2.2. Độ phân giải và dung lượng dữ liệu
Độ phân giải là số pixel theo chiều ngang nhân với số pixel theo chiều dọc của khung hình. Lĩnh vực truyền hình và Internet sử dụng tỷ lệ khung hình 16:9 theo các khuyến nghị của ITU [1], [2]; lĩnh vực chiếu phim kỹ thuật số sử dụng các chuẩn của tổ chức Digital Cinema Initiatives (DCI) với khung hình rộng hơn [4]. Bảng 1 và Hình 2 tổng hợp các chuẩn phổ biến.
Bảng 1. Các chuẩn độ phân giải phổ biến
|
Chuẩn |
Kích thước (pixel) |
Tổng số pixel |
Phạm vi sử dụng |
|
HD |
1280 × 720 |
0,92 triệu |
Web, phát trực tuyến tiết kiệm băng thông |
|
Full HD |
1920 × 1080 |
2,07 triệu |
Truyền hình, YouTube, đồ án sinh viên |
|
DCI 2K |
2048 × 1080 |
2,21 triệu |
Rạp chiếu (gói DCP 2K) |
|
UHD 4K |
3840 × 2160 |
8,29 triệu |
Truyền hình 4K, dịch vụ phát trực tuyến |
|
DCI 4K |
4096 × 2160 |
8,85 triệu |
Rạp chiếu, máy quay điện ảnh |
Nguồn: Tổng hợp từ ITU-R BT.709-6, BT.2020-2 và DCI Specification [1], [2], [4].

Dung lượng một khung hình chưa nén được xác định theo công thức (1):
S = (W × H × c × b) / 8(1)
Trong đó S là dung lượng tính bằng byte, c là số kênh màu, b là số bit trên mỗi kênh. Với khung hình Full HD, 3 kênh, 8 bit, ta có S = 6.220.800 byte, xấp xỉ 6,2 MB. Ở tốc độ 25 hình/giây, một phút ghi hình tương ứng 1.500 khung, tức khoảng 9,3 GB dữ liệu chưa nén. Con số này lý giải vì sao video luôn phải được nén và vì sao việc quản lý lưu trữ là bài toán thường trực của các đơn vị hậu kỳ.
2.3. Độ sâu bit và lượng tử hóa
Nếu độ phân giải cho biết có bao nhiêu điểm ảnh, thì độ sâu bit (bit depth) cho biết mỗi điểm ảnh ghi được bao nhiêu mức giá trị. Với b bit, mỗi kênh có 2b mức (Bảng 2). Quá trình làm tròn một giá trị liên tục x ∈ [0, 1] về mức gần nhất gọi là lượng tử hóa, được mô tả bởi công thức (2):
Qb(x) = round(x × (2b − 1)) / (2b − 1)(2)
Bảng 2. Các mức độ sâu bit thường gặp
|
Độ sâu |
Số mức mỗi kênh |
Tổng số màu (3 kênh) |
Thường gặp ở |
|
8-bit |
256 |
≈ 16,7 triệu |
Máy ảnh phổ thông, điện thoại, web, JPEG |
|
10-bit |
1.024 |
≈ 1,07 tỷ |
Máy quay bán chuyên nghiệp, ProRes 422, HDR |
|
12-bit |
4.096 |
≈ 68,7 tỷ |
Máy quay điện ảnh, định dạng RAW, DCP |
Tổng số 16,7 triệu màu của ảnh 8-bit tưởng như dư thừa. Tuy nhiên, một vùng chuyển màu như bầu trời chỉ chiếm một khoảng hẹp trong dải giá trị, có thể chỉ vài chục mức trên mỗi kênh. Khi chỉnh màu, thao tác kéo giãn tương phản trải khoảng hẹp đó ra toàn dải sáng – tối, khiến các mức rời rạc hiện ra thành những “bậc thang” mà mắt người nhận biết rõ. Đây chính là hiện tượng banding [5].
2.4. Không gian màu
a) Hệ màu RGB và biểu đồ tần suất (histogram). Tách một ảnh màu theo từng kênh sẽ thu được ba ảnh đơn sắc; vùng càng sáng trong ảnh kênh R thì thành phần đỏ càng lớn. Histogram thống kê số lượng pixel tại mỗi mức giá trị 0–255, là công cụ quen thuộc để đánh giá phơi sáng trong quay phim và chỉnh màu (Hình 3).

b) Hệ màu YCbCr và lấy mẫu màu. Hệ thị giác người nhạy với độ sáng hơn nhiều so với sắc màu. Các hệ thống video khai thác đặc điểm này bằng cách chuyển RGB sang YCbCr, trong đó Y là thành phần độ sáng, Cb và Cr là hai thành phần màu. Theo khuyến nghị ITU-R BT.709 [1], phép chuyển đổi được xác định bởi các công thức (3), (4), (5):
Y = 0,2126R + 0,7152G + 0,0722B(3)
Cb = (B − Y) / 1,8556(4)
Cr = (R − Y) / 1,5748(5)
Hệ số của kênh G lớn nhất phản ánh độ nhạy cao nhất của mắt người với vùng sóng xanh lục. Sau khi tách, thiết bị giữ thành phần Y ở mọi pixel nhưng có thể giảm số mẫu màu, gọi là lấy mẫu màu (chroma subsampling), như minh họa ở Hình 4 và Bảng 3.

Bảng 3. So sánh các kiểu lấy mẫu màu
|
Kiểu lấy mẫu |
Dữ liệu so với 4:4:4 |
Ảnh hưởng thực tế |
|
4:4:4 |
100% |
Tốt nhất cho kỹ xảo, tách nền, đồ họa |
|
4:2:2 |
≈ 67% |
Chuẩn hậu kỳ chuyên nghiệp, tách phông xanh tốt |
|
4:2:0 |
50% |
Phổ biến ở điện thoại, máy ảnh, phát trực tuyến; viền tách nền dễ răng cưa |
c) Gam màu (gamut). Mỗi chuẩn chọn ba màu gốc R, G, B với tọa độ khác nhau trên giản đồ sắc độ CIE 1931; tam giác nối ba màu gốc là tập hợp các màu chuẩn đó biểu diễn được. Rec.709 dùng cho truyền hình HD có gam màu hẹp nhất; DCI-P3 dùng cho rạp chiếu [3]; Rec.2020 dùng cho UHD và HDR có gam màu rộng nhất [2] (Hình 5). Khi phần mềm diễn giải sai gam màu của tệp, hình ảnh bị nhạt hoặc lệch màu, một lỗi thường gặp khi xuất phim lên các nền tảng trực tuyến.

3. PHƯƠNG PHÁP NGHIÊN CỨU
3.1. Công cụ
Thực nghiệm được thực hiện bằng ngôn ngữ Python 3 với ba thư viện mã nguồn mở: NumPy cho tính toán mảng [7], Pillow cho đọc và ghi ảnh, Matplotlib cho trực quan hóa [8]. Các thư viện này miễn phí, chạy được trên máy tính cấu hình phổ thông, phù hợp với điều kiện phòng máy tại các trường nghệ thuật.
3.2. Thiết kế thí nghiệm mô phỏng banding
Thí nghiệm mô phỏng thao tác chỉnh màu trên một vùng bầu trời theo ba bước:
-
Bước 1 – Tạo dải chuyển màu: sinh 1.000 giá trị liên tục phân bố đều trong đoạn [0,30; 0,45], tương ứng một vùng chiếm 15% dải sáng.
-
Bước 2 – Lượng tử hóa: áp công thức (2) với b lần lượt bằng 6, 8, 10 và 12 bit, mô phỏng việc ghi hình ở các độ sâu bit khác nhau.
-
Bước 3 – Kéo giãn tương phản: ánh xạ tuyến tính đoạn [0,30; 0,45] về [0; 1] theo công thức x‘ = (x − 0,30) / 0,15, mô phỏng thao tác grading; sau đó đếm số giá trị phân biệt còn lại.
Đại lượng đo là số bậc màu phân biệt sau khi kéo giãn. Số bậc càng ít, các dải bậc thang càng rộng và càng dễ nhận thấy bằng mắt thường.
3.3. Chuẩn bị môi trường chạy chương trình
Để người đọc có thể tự chạy lại toàn bộ thực nghiệm, phần này hướng dẫn cài đặt môi trường trên máy tính cá nhân. Người đọc có thể chọn một trong hai phương án: cài đặt trên máy (phương án A) hoặc chạy trực tuyến không cần cài đặt (phương án B). Bảng 4 liệt kê các phần mềm cần thiết.
Bảng 4. Phần mềm cần thiết để chạy mã nguồn
|
Phần mềm |
Vai trò |
Nguồn tải / lệnh cài |
Chi phí |
|
Python 3.10 trở lên |
Trình thông dịch chạy mã |
python.org/downloads |
Miễn phí |
|
NumPy, Pillow, Matplotlib |
Thư viện tính toán, đọc ảnh, vẽ biểu đồ |
pip install numpy pillow matplotlib |
Miễn phí |
|
Visual Studio Code (khuyến nghị) |
Trình soạn thảo mã, chạy chương trình |
code.visualstudio.com + tiện ích Python của Microsoft |
Miễn phí |
|
Google Colab (thay thế) |
Chạy Python trực tuyến trên trình duyệt |
colab.research.google.com |
Miễn phí (cần tài khoản Google) |
Phương án A – Cài đặt trên máy tính:
-
Cài Python. Truy cập python.org/downloads, tải bản Python 3 mới nhất cho hệ điều hành đang dùng. Trên Windows, ở màn hình đầu tiên của trình cài đặt cần đánh dấu ô Add python.exe to PATH trước khi bấm Install Now; trên macOS, chạy tệp .pkg tải về và làm theo hướng dẫn.
-
Kiểm tra cài đặt. Mở cửa sổ dòng lệnh (Windows: gõ cmd trong ô tìm kiếm Start; macOS: mở ứng dụng Terminal), gõ lệnh python –version (macOS: python3 –version). Nếu màn hình hiện dạng Python 3.x.x là cài đặt thành công.
-
Cài thư viện. Trong cửa sổ dòng lệnh, gõ lệnh dưới đây và chờ quá trình tải hoàn tất (cần kết nối Internet; macOS dùng pip3 thay cho pip): pip install numpy pillow matplotlib
-
Cài trình soạn thảo. Tải Visual Studio Code tại code.visualstudio.com; sau khi mở, vào mục Extensions (Ctrl+Shift+X), tìm và cài tiện ích Python của Microsoft. Người mới có thể dùng tạm IDLE, trình soạn thảo có sẵn khi cài Python.
-
Tạo tệp mã nguồn. Tạo một thư mục làm việc, ví dụ D:\ThucHanh\Bai1. Trong VS Code chọn File → Open Folder mở thư mục này, tạo tệp mới tên bai1_anh_so.py và chép mã nguồn ở Phụ lục vào. Đặt một ảnh bất kỳ, đổi tên thành anh_mau.jpg, vào cùng thư mục.
-
Chạy chương trình. Bấm nút ▷ (Run Python File) ở góc trên bên phải VS Code, hoặc gõ trong cửa sổ dòng lệnh tại thư mục làm việc:
cd D:\ThucHanh\Bai1
python bai1_anh_so.py
Kết quả số được in ra màn hình; hai tệp histogram.png và kenh_Y.png được tạo trong thư mục làm việc.
Phương án B – Chạy trực tuyến bằng Google Colab: truy cập colab.research.google.com, đăng nhập tài khoản Google, chọn New notebook. Colab đã có sẵn cả ba thư viện nên không cần cài đặt. Bấm biểu tượng thư mục ở thanh bên trái để tải ảnh anh_mau.jpg lên, dán mã nguồn vào ô lệnh và bấm Shift+Enter để chạy. Phương án này phù hợp với phòng máy không có quyền cài phần mềm hoặc khi học trên điện thoại, máy tính bảng.
Một số lỗi thường gặp và cách khắc phục:
-
‘python’ is not recognized…: chưa đánh dấu Add python.exe to PATH khi cài. Chạy lại trình cài đặt, chọn Modify và bổ sung, hoặc dùng lệnh py thay cho python trên Windows.
-
ModuleNotFoundError: No module named ‘numpy’: chưa cài thư viện hoặc VS Code đang dùng một bản Python khác. Chạy lại lệnh pip install ở bước 3; trong VS Code bấm Ctrl+Shift+P, chọn Python: Select Interpreter để chọn đúng bản Python.
-
FileNotFoundError: … anh_mau.jpg: tệp ảnh không nằm cùng thư mục với tệp mã hoặc sai tên. Kiểm tra lại tên tệp, lưu ý phần đuôi .jpg bị Windows ẩn đi.
Chữ tiếng Việt trong mã bị lỗi hiển thị: lưu tệp mã với bảng mã UTF-8 (mặc định trong VS Code).
3.4. Cài đặt thuật toán
Đoạn mã dưới đây cài đặt hàm lượng tử hóa và vòng lặp thí nghiệm. Mã nguồn đầy đủ, bao gồm đọc ảnh, tách kênh, vẽ histogram và chuyển đổi RGB sang YCbCr, được trình bày ở Phụ lục.
import numpy as np
def luong_tu_hoa(x, bit):
muc = 2 ** bit – 1
return np.round(x * muc) / muc
day_mau = np.linspace(0.30, 0.45, 1000) # dải chuyển màu hẹp
for bit in (6, 8, 10, 12):
sau_grading = (luong_tu_hoa(day_mau, bit) – 0.30) / 0.15
print(bit, “bit:”, len(np.unique(sau_grading)), “bậc màu”)
Mã nguồn không sử dụng vòng lặp qua từng pixel mà áp phép tính cho toàn bộ mảng cùng lúc (vector hóa). Cách tiếp cận này nhanh hơn vòng lặp Python thông thường hàng trăm lần và là nguyên tắc cốt lõi khi xử lý ảnh, video bằng lập trình [7].
Mã nguồn không sử dụng vòng lặp qua từng pixel mà áp phép tính cho toàn bộ mảng cùng lúc (vector hóa). Cách tiếp cận này nhanh hơn vòng lặp Python thông thường hàng trăm lần và là nguyên tắc cốt lõi khi xử lý ảnh, video bằng lập trình [7].
4. KẾT QUẢ VÀ THẢO LUẬN
4.1. Dung lượng dữ liệu theo định dạng ghi hình
Áp dụng công thức (1), Bảng 5 cho thấy dung lượng dữ liệu chưa nén tăng rất nhanh theo độ phân giải và độ sâu bit.
Bảng 5. Dung lượng dữ liệu chưa nén theo định dạng
|
Định dạng |
Tốc độ khung hình |
Dung lượng/khung |
Dung lượng/phút |
|
Full HD, 8-bit, RGB |
25 hình/giây |
6,2 MB |
9,3 GB |
|
UHD 4K, 10-bit, RGB |
25 hình/giây |
31,1 MB |
46,7 GB |
|
DCI 4K, 12-bit, RGB |
24 hình/giây |
39,8 MB |
57,3 GB |
Từ Full HD 8-bit lên DCI 4K 12-bit, dung lượng mỗi phút tăng hơn 6 lần. Điều này đặt ra yêu cầu tương ứng về thẻ nhớ, ổ lưu trữ và băng thông mạng trong quy trình sản xuất, đồng thời là tiền đề để nghiên cứu các kỹ thuật nén video ở bài viết tiếp theo.
4.2. Kết quả mô phỏng hiện tượng banding
Kết quả chạy chương trình được tổng hợp ở Bảng 6 và minh họa trực quan ở Hình 6.
Bảng 6. Số bậc màu còn lại sau khi kéo giãn tương phản
|
Độ sâu bit |
Số mức mỗi kênh |
Số bậc màu còn lại |
Đánh giá thị giác |
|
6-bit |
64 |
10 |
Dải bậc thang rất rõ |
|
8-bit |
256 |
40 |
Banding nhận thấy rõ trên vùng trời |
|
10-bit |
1.024 |
154 |
Chuyển màu gần như liền mạch |
|
12-bit |
4.096 |
616 |
Liền mạch, dư địa chỉnh màu lớn |

Kết quả cho thấy số bậc màu còn lại tỷ lệ với tích của số mức lượng tử và độ rộng vùng chuyển màu (xấp xỉ 2b × 0,15). Ở 8-bit, vùng trời chỉ còn 40 bậc; khi được trải ra toàn màn hình rộng 1.920 pixel, mỗi bậc rộng khoảng 48 pixel, đủ lớn để mắt người nhận ra ranh giới. Ở 10-bit, số bậc tăng gần 4 lần, bề rộng mỗi bậc giảm còn khoảng 12 pixel, và dải màu trông gần như liền mạch. Điều này lý giải tình huống nêu ở phần Đặt vấn đề.
4.3. Khuyến nghị thực tiễn
Từ cơ sở lý thuyết và kết quả mô phỏng, bài viết đề xuất một số khuyến nghị cho sinh viên và người làm phim:
-
Với cảnh có mảng chuyển màu lớn (bầu trời, tường trơn, khói sân khấu) và dự kiến chỉnh màu mạnh, nên ưu tiên ghi hình 10-bit trở lên.
-
Khi buộc phải ghi 8-bit, cần phơi sáng và cân bằng trắng chính xác ngay tại hiện trường để hậu kỳ chỉ phải hiệu chỉnh nhẹ.
-
Cảnh quay phông xanh, phông lục nên ghi ở chế độ lấy mẫu màu tối thiểu 4:2:2 để bảo toàn thông tin màu tại đường biên chủ thể.
- Khi xuất bản phẩm, có thể bổ sung một lượng nhiễu hạt nhỏ (kỹ thuật dithering) để che bớt banding; đồng thời kiểm tra khai báo gam màu của tệp xuất để tránh lệch màu trên nền tảng phát hành.
5. KẾT LUẬN
Bài viết đã hệ thống hóa ba khái niệm nền tảng của ảnh số gồm độ phân giải, độ sâu bit và không gian màu, gắn với các tình huống cụ thể trong sản xuất điện ảnh. Thông qua mô phỏng bằng Python, bài viết định lượng được hiện tượng banding: với cùng một vùng chuyển màu hẹp, dữ liệu 8-bit chỉ còn 40 bậc màu sau chỉnh màu, trong khi 10-bit và 12-bit lần lượt giữ được 154 và 616 bậc.
Về mặt đào tạo, cách tiếp cận kết hợp lý thuyết, trực quan hóa và lập trình giúp người học ngành nghệ thuật hiểu bản chất dữ liệu thay vì chỉ ghi nhớ thao tác phần mềm. Mã nguồn đi kèm có thể được sử dụng trực tiếp trong các học phần tin học ứng dụng. Hướng nghiên cứu tiếp theo của chuỗi bài viết là các kỹ thuật nén video (codec, container, bitrate), quản lý màu theo hệ thống ACES và tự động hóa quy trình hậu kỳ bằng lập trình.
TÀI LIỆU THAM KHẢO
[1]International Telecommunication Union (2015), Recommendation ITU-R BT.709-6: Parameter values for the HDTV standards for production and international programme exchange, ITU, Geneva.
[2]International Telecommunication Union (2015), Recommendation ITU-R BT.2020-2: Parameter values for ultra-high definition television systems for production and international programme exchange, ITU, Geneva.
[3]Society of Motion Picture and Television Engineers (2011), SMPTE RP 431-2: D-Cinema Quality – Reference Projector and Environment, SMPTE, New York.
[4]Digital Cinema Initiatives (2020), Digital Cinema System Specification, Version 1.4, DCI LLC.
[5]Poynton, C. (2012), Digital Video and HD: Algorithms and Interfaces, 2nd ed., Morgan Kaufmann, Waltham.
[6]Gonzalez, R. C., Woods, R. E. (2018), Digital Image Processing, 4th ed., Pearson, New York.
[7]Harris, C. R. et al. (2020), “Array programming with NumPy”, Nature, 585, pp. 357–362.
[8]Hunter, J. D. (2007), “Matplotlib: A 2D graphics environment”, Computing in Science & Engineering, 9(3), pp. 90–95.
PHỤ LỤC: MÃ NGUỒN CHƯƠNG TRÌNH THỰC NGHIỆM
Chương trình dưới đây đã được chạy thử với Python 3, NumPy, Pillow và Matplotlib. Cách cài đặt môi trường và chạy chương trình xem mục 3.3. Lưu mã vào tệp bai1_anh_so.py, đặt ảnh anh_mau.jpg cùng thư mục rồi chạy lệnh python bai1_anh_so.py.
“””Bài 1 – Ảnh số được tạo ra thế nào. Cài đặt: pip install numpy pillow matplotlib”””
import numpy as np
from PIL import Image
import matplotlib.pyplot as plt
# 1. Đọc ảnh thành ma trận số
img = np.array(Image.open(“anh_mau.jpg”).convert(“RGB”))
cao, rong, kenh = img.shape
print(f”Kích thước: {rong}x{cao}, {kenh} kênh, kiểu dữ liệu {img.dtype}”)
print(“Pixel ở giữa ảnh (R, G, B):”, img[cao // 2, rong // 2])
# 2. Tính dung lượng khung hình chưa nén
def dung_luong_khung(rong, cao, kenh=3, bit=8):
return rong * cao * kenh * bit / 8 # byte
for ten, w, h, b in [(“Full HD 8-bit”, 1920, 1080, 8), (“UHD 4K 10-bit”, 3840, 2160, 10)]:
mb = dung_luong_khung(w, h, bit=b) / 1e6
print(f”{ten}: {mb:.1f} MB/khung, {mb * 25 * 60 / 1000:.1f} GB/phút @25fps”)
# 3. Tách kênh và vẽ histogram
fig, ax = plt.subplots(1, 3, figsize=(12, 3))
for i, (ten, mau) in enumerate([(“R”, “red”), (“G”, “green”), (“B”, “blue”)]):
ax[i].hist(img[…, i].ravel(), bins=256, range=(0, 255), color=mau)
ax[i].set_title(f”Histogram kênh {ten}”)
plt.tight_layout(); plt.savefig(“histogram.png”)
# 4. Mô phỏng banding: lượng tử hóa về n bit rồi kéo tương phản
def luong_tu_hoa(x, bit):
muc = 2 ** bit – 1
return np.round(x * muc) / muc
day_mau = np.linspace(0.30, 0.45, 1000) # dải chuyển màu hẹp như bầu trời
for bit in (6, 8, 10, 12):
sau_grading = (luong_tu_hoa(day_mau, bit) – 0.30) / 0.15 # kéo giãn ra 0..1
print(f”{bit}-bit: còn {len(np.unique(sau_grading))} bậc màu sau khi kéo tương phản”)
# 5. Chuyển RGB sang YCbCr theo Rec.709
def rgb_sang_ycbcr(rgb):
rgb = rgb.astype(np.float64) / 255
R, G, B = rgb[…, 0], rgb[…, 1], rgb[…, 2]
Y = 0.2126 * R + 0.7152 * G + 0.0722 * B
Cb = (B – Y) / 1.8556
Cr = (R – Y) / 1.5748
return np.stack([Y, Cb, Cr], axis=-1)
ycc = rgb_sang_ycbcr(img)
Image.fromarray((ycc[…, 0] * 255).astype(np.uint8)).save(“kenh_Y.png”)
print(“Đã lưu kênh độ sáng Y: kenh_Y.png”)
Lê Khắc Tuấn
Giảng viên, Bộ môn Ngoại ngữ – Tin học, Khoa Kiến thức cơ bản
Trường Đại học Sân khấu – Điện ảnh Hà Nội