Những tông màu nâu đỏ và dải màu xám của các bức ảnh cũ mang một nét quyến rũ độc đáo, ghi lại những khoảnh khắc đông cứng theo thời gian. Tuy nhiên, chúng thường thiếu đi sự sống động tức thì của cảnh gốc. Hãy tưởng tượng việc thổi những sắc màu của cuộc sống trở lại vào những ký ức quý giá này, biến một bức chân dung đen trắng mờ ảo thành một cửa sổ tiết lộ thế giới của chủ thể với đầy đủ màu sắc. Quá trình biến đổi này, được gọi là tô màu ảnh (image colorization), từ lâu đã thu hút các nghệ sĩ và nhà sử học. Ngày nay, được thúc đẩy bởi những tiến bộ trong trí tuệ nhân tạo, đặc biệt là deep learning, việc tô màu tự động đang đạt được những kết quả từng chỉ có trong khoa học viễn tưởng.
Mang màu sắc đến một hình ảnh thang độ xám đặt ra một thách thức hấp dẫn. Một lượng thông tin đáng kể – dữ liệu màu sắc gốc – vốn đã bị mất khi hình ảnh được hiển thị ở dạng đơn sắc. Làm thế nào một thuật toán có thể biết được màu sắc thực sự của một bông hoa, một chiếc váy, hay bầu trời chỉ từ các giá trị độ sáng? Câu trả lời nằm trong những manh mối tinh tế ẩn chứa trong chính hình ảnh thang độ xám: kết cấu, hình dạng, ngữ cảnh, và sự tương tác của ánh sáng và bóng tối. Mặc dù việc xác định chính xác màu gốc có thể là không thể (bông hồng đó thực sự là màu đỏ thẫm, hay có lẽ là một sắc hồng?), mục tiêu chuyển sang tạo ra một sự tô màu hợp lý và thuyết phục về mặt thẩm mỹ. Mục đích là tạo ra một hình ảnh mà người quan sát sẽ thấy đáng tin, thậm chí có thể không phân biệt được với một bức ảnh màu gốc.
Các mô hình deep learning vượt trội trong việc khám phá các mẫu phức tạp và mối quan hệ thống kê trong các bộ dữ liệu khổng lồ. Bằng cách huấn luyện các mô hình này trên hàng triệu hình ảnh, so sánh các phiên bản thang độ xám với các bản gốc màu tương ứng, các thuật toán học cách liên kết các kết cấu và cấu trúc cụ thể với các màu sắc có khả năng xảy ra. Chúng học được rằng cỏ thường có màu xanh lá cây, bầu trời thường có màu xanh dương, và một số kết cấu nhất định tương ứng với vân gỗ hoặc vải. Nó giống như một phỏng đoán có cơ sở, nhưng là một phỏng đoán được thông báo bởi một bộ bách khoa toàn thư trực quan khổng lồ. Thuật toán không “biết” màu sắc thực sự theo nghĩa của con người, nhưng nó có thể đưa ra những dự đoán có xác suất cao dựa trên các mối tương quan đã học được.
Ngôn ngữ Màu sắc: CIELab và Mạng Nơ-ron
Để giải quyết bài toán tô màu bằng phương pháp tính toán, chúng ta cần một cách biểu diễn màu sắc phù hợp. Mặc dù RGB (Red, Green, Blue) phổ biến cho màn hình hiển thị, nó trộn lẫn thông tin độ sáng (luminance) và độ màu (chrominance). Một hệ thống thuận lợi hơn cho nhiệm vụ này là không gian màu CIELab. Mô hình này tách biệt màu sắc một cách tinh tế thành ba thành phần riêng biệt:
- L (Lightness): Kênh này biểu thị thông tin thang độ xám, từ đen tuyền đến trắng tinh. Về cơ bản, đây là dữ liệu đầu vào mà chúng ta đã có trong một hình ảnh đen trắng.
- a: Kênh này mã hóa phổ màu từ xanh lá cây (giá trị âm) đến đỏ (giá trị dương).
- b: Kênh này mã hóa phổ màu từ xanh dương (giá trị âm) đến vàng (giá trị dương).
Vẻ đẹp của CIELab nằm ở sự tách biệt này. Mô hình deep learning của chúng ta có thể tập trung vào việc dự đoán hai kênh độ màu (‘a’ và ‘b’) chỉ dựa trên kênh Độ sáng (‘L’) đầu vào. Nhiệm vụ cốt lõi trở thành: với thông tin thang độ xám (L), các giá trị ‘a’ và ‘b’ tương ứng có khả năng nhất cho mỗi pixel là gì?
Những nỗ lực ban đầu thường sử dụng Mạng Nơ-ron Tích chập (Convolutional Neural Networks - CNNs) – một loại kiến trúc deep learning đặc biệt thành thạo trong việc xử lý dữ liệu dạng lưới như hình ảnh. Các mạng này được huấn luyện trên các bộ dữ liệu hình ảnh lớn (như ImageNet) để trực tiếp dự đoán các giá trị ‘a’ và ‘b’ cho mỗi pixel, coi đó là một bài toán hồi quy (dự đoán các giá trị liên tục). Tuy nhiên, một cạm bẫy phổ biến đã xuất hiện: các kết quả tô màu thường trông nhợt nhạt hoặc bị giảm độ bão hòa. Tại sao? Hãy xem xét một đối tượng như quả táo. Nó có thể hợp lý là màu đỏ, xanh lá cây, hoặc thậm chí là màu vàng. Nếu mạng cố gắng lấy trung bình các khả năng này trong quá trình hồi quy, nó có thể chọn một màu nâu xỉn, thỏa hiệp thay vì một màu sắc rực rỡ, cụ thể. Hiệu ứng trung bình hóa này trên nhiều màu sắc hợp lý có xu hướng làm phai nhạt kết quả.
Bước ngoặt Mô hình: Tô màu như Phân loại
Để khắc phục vấn đề giảm độ bão hòa và tạo ra màu sắc sống động, chân thực hơn, một cách tiếp cận tinh vi hơn đã định hình lại vấn đề. Thay vì coi việc dự đoán màu sắc là hồi quy, nó được xem như một nhiệm vụ phân loại.
Đây là sự thay đổi về mặt khái niệm:
- Không gian Màu lượng tử hóa: Phổ liên tục của các giá trị ‘a’ và ‘b’ có thể được rời rạc hóa thành một tập hợp các “bin” hoặc lớp màu đại diện được xác định trước. Hãy coi nó như việc giảm một bảng màu rộng lớn xuống một tập hợp các tùy chọn màu riêng biệt, dễ quản lý nhưng vẫn toàn diện trong mặt phẳng ‘a’-‘b’.
- Dự đoán Xác suất: Đối với mỗi pixel trong ảnh thang độ xám đầu vào, CNN không dự đoán một giá trị ‘a’ và ‘b’ duy nhất. Thay vào đó, nó xuất ra một phân phối xác suất trên các bin màu đã được lượng tử hóa. Về cơ bản, nó nói rằng, “Đối với pixel này, có 70% khả năng nó thuộc về ‘bin màu đỏ rực rỡ #5’, 20% khả năng là ‘bin màu đỏ nhạt #2’, 5% khả năng là ‘bin màu nâu #12’,” và cứ thế.
- Giải quyết Sự mơ hồ: Cách tiếp cận xác suất này vốn đã xử lý được sự mơ hồ về màu sắc. Nếu một đối tượng có thể có nhiều màu (như quả táo), mạng có thể gán xác suất đáng kể cho một số bin màu khác nhau, phản ánh sự không chắc chắn này mà không cần dùng đến giá trị trung bình nhạt nhẽo.
- Giải mã thành Màu sắc Sống động: Bước cuối cùng liên quan đến việc chuyển đổi phân phối xác suất này trở lại thành một màu cụ thể, duy nhất cho mỗi pixel. Một cách tiếp cận ngây thơ có thể là chỉ cần chọn bin màu có xác suất cao nhất (mode). Tuy nhiên, để khuyến khích sự sống động và tránh vấn đề giảm độ bão hòa, các kỹ thuật như tính toán giá trị trung bình ủ nhiệt (annealed mean) của phân phối được sử dụng. Phương pháp này đặt trọng số nhiều hơn vào các dự đoán ít có khả năng xảy ra nhưng nhiều màu sắc hơn (độ bão hòa cao hơn), thực sự “phá vỡ thế cân bằng” nghiêng về sự sống động trong khi vẫn tôn trọng phân phối dự đoán tổng thể.
Khung phân loại này, kết hợp với thiết kế cẩn thận của hàm mất mát (loss function - thước đo được sử dụng để đánh giá hiệu suất của mô hình trong quá trình huấn luyện) dành riêng cho việc tô màu, cho phép mô hình học được mối quan hệ phức tạp giữa các đặc trưng thang độ xám và phân phối các màu sắc có khả năng xảy ra. Kết quả là những hình ảnh không chỉ được tô màu một cách hợp lý mà còn sở hữu sự phong phú và hấp dẫn về mặt thị giác thường thiếu trong các phương pháp dựa trên hồi quy trước đó.
Nhìn sâu bên trong: Quy trình Deep Learning Thực tế
Mặc dù việc huấn luyện một CNN phức tạp như vậy từ đầu là một nhiệm vụ đồ sộ đòi hỏi tài nguyên tính toán khổng lồ và bộ dữ liệu khổng lồ, việc tận dụng các mô hình tiền huấn luyện (pre-trained) giúp công nghệ này trở nên dễ tiếp cận. Hãy cùng xem qua các bước khái niệm liên quan đến việc sử dụng một mô hình deep learning tiền huấn luyện (cụ thể là mô hình được xây dựng bằng framework Caffe, như trong ví dụ gốc) để tô màu ảnh, được triển khai bằng Python và các thư viện phổ biến.
1. Lắp ráp Bộ công cụ:
Nền tảng thường bao gồm Python, một ngôn ngữ lập trình đa năng phổ biến trong khoa học dữ liệu và AI. Các thư viện chính đóng vai trò quan trọng:
- NumPy: Cần thiết cho các phép toán số hiệu quả, đặc biệt là xử lý các mảng đa chiều đại diện cho hình ảnh.
- OpenCV (cv2): Một thư viện mạnh mẽ cho các tác vụ thị giác máy tính. Nó cung cấp các hàm để đọc, ghi, thao tác và hiển thị hình ảnh, và quan trọng là bao gồm một mô-đun Mạng Nơ-ron Sâu (Deep Neural Network - DNN) có khả năng tải và chạy các mô hình được huấn luyện trong các framework khác nhau như Caffe, TensorFlow và PyTorch.
- Argparse: Một thư viện Python tiêu chuẩn để tạo giao diện dòng lệnh thân thiện với người dùng, cho phép người dùng dễ dàng chỉ định các tham số đầu vào như đường dẫn tệp hình ảnh.
- OS: Được sử dụng cho các tương tác hệ điều hành cơ bản, như xây dựng đường dẫn tệp theo cách hoạt động trên các hệ thống khác nhau (Windows, macOS, Linux).
2. Thu thập Trí tuệ Tiền huấn luyện:
Thay vì xây dựng mạng nơ-ron từng viên gạch, chúng ta sử dụng các tệp đại diện cho một mạng đã được huấn luyện để tô màu. Chúng thường bao gồm:
- Tệp Kiến trúc Mô hình (
.prototxt
cho Caffe): Tệp này định nghĩa cấu trúc của mạng nơ-ron – các lớp, loại của chúng, kết nối và tham số. Đó là bản thiết kế của mô hình. - Tệp Trọng số Đã huấn luyện (
.caffemodel
cho Caffe): Tệp này chứa các trọng số số học mà mạng đã học được trong quá trình huấn luyện mở rộng. Những trọng số này gói gọn “kiến thức” mà mô hình đã thu được về việc ánh xạ các đặc trưng thang độ xám sang xác suất màu. Đó là trí tuệ được chắt lọc. - Dữ liệu Lượng tử hóa Màu (
.npy
file): Tệp NumPy này thường lưu trữ các điểm trung tâm của các bin màu đã được lượng tử hóa được sử dụng trong phương pháp phân loại được mô tả trước đó. Nó hoạt động như bảng màu tham chiếu cho các xác suất màu được dự đoán.
Những tệp này đại diện cho đỉnh cao của quá trình huấn luyện có thể kéo dài hàng tuần hoặc hàng tháng trên phần cứng mạnh mẽ.
3. Tải Động cơ Tô màu:
Với các tệp cần thiết đã được định vị, mô-đun DNN của OpenCV cung cấp cơ chế để tải mạng tiền huấn luyện vào bộ nhớ. Hàm cv2.dnn.readNetFromCaffe
(hoặc các hàm tương đương cho các framework khác) nhận các tệp kiến trúc và trọng số làm đầu vào và khởi tạo mạng, làm cho nó sẵn sàng cho suy luận (inference - quá trình đưa ra dự đoán trên dữ liệu mới). Các điểm lượng tử hóa màu từ tệp .npy
cũng được tải, thường sử dụng NumPy.
4. Tinh chỉnh Thành phần Mạng (Nếu cần):
Đôi khi, các lớp cụ thể trong mạng tiền huấn luyện cần được điều chỉnh nhỏ trước khi suy luận. Trong bối cảnh mô hình tô màu dựa trên phân loại đã thảo luận:
- Điều chỉnh Lớp Đầu ra: Lớp cuối cùng chịu trách nhiệm xuất ra các dự đoán kênh ‘a’ và ‘b’ (ví dụ: được đặt tên là
class8_ab
trong mô hình tham chiếu) có thể cần được tải một cách rõ ràng với các tâm bin màu từ tệp.npy
. Điều này đảm bảo xác suất đầu ra của mạng ánh xạ chính xác đến bảng màu được xác định trước. Các điểm thường được định hình lại và chuyển đổi sang kiểu dữ liệu phù hợp (ví dụ: float32) trước khi được gán cho “blobs” của lớp (thuật ngữ của Caffe cho các vùng chứa dữ liệu). - Tái cân bằng Màu: Một lớp khác (ví dụ:
conv8_313_rh
) có thể được điều chỉnh để ảnh hưởng đến sự cân bằng giữa các màu khác nhau trong đầu ra, có khả năng tăng cường độ bão hòa hoặc sửa chữa các sai lệch đã học được trong quá trình huấn luyện. Điều này thường liên quan đến việc đặt các blob của lớp thành các giá trị đã học cụ thể (như giá trị2.606
được đề cập trong mã gốc, có khả năng bắt nguồn từ thực nghiệm hoặc trong quá trình huấn luyện).
Các bước này điều chỉnh mô hình tiền huấn luyện chung cho các sắc thái cụ thể của nhiệm vụ tô màu bằng cách sử dụng phương pháp phân loại.
5. Chuẩn bị Ảnh Đầu vào:
Ảnh thang độ xám đầu vào cần trải qua một số bước tiền xử lý trước khi được đưa vào mạng nơ-ron:
- Tải ảnh: Ảnh được đọc từ đường dẫn tệp được chỉ định bằng
cv2.imread
. Ngay cả khi đó là ảnh thang độ xám, OpenCV có thể tải nó dưới dạng ảnh BGR 3 kênh theo mặc định, sao chép giá trị xám trên các kênh. - Chuẩn hóa: Các giá trị pixel, thường nằm trong khoảng từ 0 đến 255, được chia tỷ lệ thành một phạm vi nhỏ hơn, thường là 0.0 đến 1.0, bằng cách chia cho 255.0. Việc chuẩn hóa này giúp ổn định quá trình học và suy luận của mạng.
- Chuyển đổi Không gian Màu: Ảnh được chuyển đổi từ không gian màu BGR mặc định sang không gian màu CIELab bằng
cv2.cvtColor
. Điều này rất quan trọng để tách kênh Độ sáng (L). - Thay đổi kích thước: Hầu hết các CNN tiền huấn luyện đều mong đợi ảnh đầu vào có kích thước cố định (ví dụ: 224x224 pixel, một tiêu chuẩn phổ biến bị ảnh hưởng bởi các bộ dữ liệu như ImageNet). Ảnh LAB được thay đổi kích thước tương ứng bằng
cv2.resize
. Việc chuẩn hóa này đảm bảo khả năng tương thích với kiến trúc của mạng. - Tách và Căn giữa Kênh L: Kênh Độ sáng (L) được trích xuất từ ảnh LAB đã thay đổi kích thước. Thông thường, các giá trị của nó (thường là 0-100 trong LAB) sau đó được căn giữa quanh số không bằng cách trừ đi một giá trị trung bình (ví dụ: 50). Việc căn giữa này là một thực hành phổ biến khác có thể cải thiện hiệu suất mạng.
Kênh L đã được tiền xử lý tỉ mỉ này giờ đã sẵn sàng để được trình bày cho mạng.
6. Bước Suy luận: Dự đoán Màu sắc:
Đây là nơi phép màu xảy ra:
- Tạo Blob: Kênh L đã xử lý (hiện là một mảng 2D) được chuyển đổi thành “blob”, một định dạng mảng 4 chiều mà mô-đun DNN mong đợi (
cv2.dnn.blobFromImage
). Định dạng này thường bao gồm các chiều cho kích thước lô (batch size), số kênh, chiều cao và chiều rộng. - Truyền Xuôi (Forward Pass): Blob được đặt làm đầu vào cho mạng đã tải bằng
net.setInput
. Sau đó, phương thứcnet.forward()
được gọi. Điều này kích hoạt quá trình tính toán: dữ liệu đầu vào chảy qua các lớp của mạng, trải qua các phép biến đổi được quy định bởi các trọng số đã học, cuối cùng tạo ra đầu ra dự đoán. Đối với mô hình tô màu của chúng ta, đầu ra đại diện cho các kênh ‘a’ và ‘b’ được dự đoán (hay đúng hơn là phân phối xác suất trên các bin màu). - Định hình lại Đầu ra: Đầu ra thô từ mạng cần được định hình lại và chuyển vị trở lại thành định dạng không gian 2D tương ứng với các kênh ‘a’ và ‘b’.
Mạng bây giờ đã tạo ra dự đoán tốt nhất của nó cho thông tin màu sắc dựa trên ảnh thang độ xám đầu vào.
7. Tái tạo Ảnh Màu:
Giai đoạn cuối cùng liên quan đến việc kết hợp thông tin màu được dự đoán với dữ liệu ảnh gốc:
- Thay đổi kích thước Kênh Dự đoán: Các kênh ‘a’ và ‘b’ được dự đoán (hiện có kích thước 224x224, khớp với đầu vào mạng) cần được thay đổi kích thước trở lại kích thước gốc của ảnh đầu vào bằng
cv2.resize
. Điều này đảm bảo thông tin màu sắc căn chỉnh chính xác với cấu trúc ảnh gốc. - Trích xuất Độ sáng Gốc: Quan trọng là, kênh Độ sáng (L) được trích xuất từ ảnh LAB gốc, kích thước đầy đủ (được tạo trong quá trình tiền xử lý trước khi thay đổi kích thước). Sử dụng kênh L gốc bảo tồn chi tiết và cấu trúc độ sáng ban đầu của ảnh, vốn sẽ bị suy giảm nếu sử dụng kênh L đã thay đổi kích thước.
- Ghép nối: Kênh L gốc được kết hợp (ghép nối) với các kênh ‘a’ và ‘b’ đã thay đổi kích thước, được dự đoán dọc theo trục kênh màu. Thao tác này tập hợp lại một ảnh LAB hoàn chỉnh, giờ đây với màu sắc được dự đoán.
- Chuyển đổi Trở lại Định dạng Hiển thị: Ảnh LAB kết quả được chuyển đổi trở lại không gian màu BGR bằng
cv2.cvtColor
, vì đây là định dạng tiêu chuẩn được mong đợi bởi hầu hết các hàm hiển thị ảnh (nhưcv2.imshow
). - Cắt và Chia tỷ lệ: Các giá trị pixel trong ảnh BGR, hiện đang ở phạm vi chuẩn hóa (có thể là 0.0 đến 1.0), được cắt để đảm bảo chúng nằm trong phạm vi hợp lệ này (các giá trị đôi khi có thể hơi vượt quá giới hạn do quá trình dự đoán). Sau đó, chúng được chia tỷ lệ trở lại phạm vi số nguyên 0-255 tiêu chuẩn cần thiết để hiển thị hoặc lưu dưới dạng tệp hình ảnh tiêu chuẩn.
8. Trực quan hóa:
Cuối cùng, các hàm như cv2.imshow
có thể được sử dụng để hiển thị ảnh thang độ xám gốc cùng với bản sao mới được tô màu của nó, cho phép so sánh trực quan ngay lập tức.
Thực thi Quy trình:
Thông thường, một script thực hiện các bước này sẽ được chạy từ dòng lệnh. Sử dụng thiết lập argparse
, người dùng sẽ cung cấp đường dẫn đến ảnh thang độ xám đầu vào làm đối số (ví dụ: python colorize_image.py --image my_photo.jpg
). Script sau đó thực thi các bước tải, tiền xử lý, suy luận và tái tạo, cuối cùng hiển thị hoặc lưu kết quả đã tô màu.
Quy trình làm việc này, tận dụng các mô hình tiền huấn luyện và các thư viện mạnh mẽ, biến lý thuyết phức tạp của việc tô màu bằng deep learning thành một công cụ thực tế có khả năng thêm màu sắc sống động, hợp lý vào các hình ảnh đơn sắc, bắc cầu hiệu quả giữa quá khứ và hiện tại.