เพื่อนๆเคยมีภาพขาวดำที่อยากเห็นมันเป็นเวอร์ชันมีสีไหม? วันนี้เราจะพาไปลองใช้เทคนิค Deep Learning กับ OpenCV มาปรับภาพเหล่านั้นให้มีชีวิตขึ้นมาด้วยสีสันแบบง่ายๆกัน!🎨

✨ ทำไมต้องใช้ Deep Learning ในการลงสี?
การลงสีภาพขาวดำฟังดูเหมือนเป็นเรื่องง่ายใช่ไหมล่ะ? แค่เลือกสีแล้วก็ระบายๆไป แต่ถ้าเราให้คอมพิวเตอร์ทำแทนล่ะ! แต่มันคงไม่รู้หรอกใช่ไหมว่า ท้องฟ้าควรจะเป็นสีฟ้า หรือใบไม้จะเป็นสีเขียว ตรงนี้แหละที่ Deep Learning จะเข้ามาช่วย! แทนที่เราจะนั่งสั่งคอมทีละจุดว่าตรงไหนต้องเป็นสีอะไร เราก็ให้มันเรียนรู้จากภาพสีจริงๆเยอะๆไปเลย แล้วมันจะค่อยๆเดาออกเองว่าภาพขาวดำที่มันเห็น ควรจะมีสีอะไรบ้างนั่นเอง

โดยในบทความนี้เราจะใช้เทคนิค Deep Learning ร่วมกับโมเดล Colorful Image Colorization ของคุณ Zhang และคณะ https://richzhang.github.io/colorization/ มาระบายสีภาพขาวดำของเรา!🎨

✨ โมเดล Colorful Image Colorization ทำงานยังไง?
🔍 ขั้นตอนที่ 1 : แปลงภาพจาก RGB เป็น Lab color space (แยกแสงกับสี)

  • L : เข้ารหัสความเข้มของแสง

  • a : เข้ารหัสชุดสีเขียว-แดง

  • b : เข้ารหัสชุดสีน้ำเงิน-เหลือง

โมเดลจะรับเฉพาะ L เข้าไป แล้วเดาว่าแต่ละจุดควรมีสีเขียว/แดง และน้ำเงิน/เหลือง ประมาณไหน

Deep Dream

🔍 ขั้นตอนที่ 2 : ทำนายสีจาก channel L ด้วย CNN
หลังจากได้ L แล้ว โมเดลที่ฝึกไว้จะใช้ CNN ในการทำนายช่อง a และ b โดยอิงจากรูปทรง เงา และตำแหน่งของภาพ เช่น เห็นรูปกลมๆอยู่ด้านบน อาจจะเดาว่านั่นคือพระอาทิตย์ ซึ่งอาจจะมีเฉดสีเหลืองเป็นหลัก🌞 เป็นต้น

🔍 ขั้นตอนที่ 3 : รวม L+a+b กลับมาเป็นภาพสี
เมื่อได้ค่า a และ b แล้ว เราจะนำมารวมกับ L เดิม จากนั้นจะแปลงจาก Lab color space กลับมาเป็น RGB เพื่อแสดงผลภาพสี

มาทุกคน เราจะพาไปดูวิธีทำกันเลย! 💫

ขั้นตอนที่ 1 เตรียมภาพขาวดำ

เตรียมภาพขาวดำของเพื่อนๆกันก่อน ส่วนเราขอเลือกใช้ภาพดอกไม้นี้แล้วกันนะ

ภาพขาวดำของดอกไม้

ขั้นตอนที่ 2 โหลดโมเดล

ให้โหลดโมเดล Colorful Image Colorization ที่จะใช้ Deep Learning ได้เลย https://drive.google.com/file/d/1Rfxzbe1hfjge9JyKB8d8vtjAkm-K8JDC/view โดยเราจะนำไฟล์ทั้ง 3 ไฟล์เข้ามาใช้นะ

  • colorization_release_v2.caffemodel
  • pts_in_hull.npy
  • colorization_deploy_v2.prototxt

ขั้นตอนที่ 3 นำ Library เข้า

มาเขียนโค้ดกันนนนนน👩‍💻
เราจะนำ Library เข้า Google Colab

  • numpy และ cv2 (OpenCV) ใช้จัดการข้อมูลรูปภาพ
  • cv2_imshow ใช้แสดงภาพใน Google Colab
import numpy as np
import cv2
from google.colab.patches import cv2_imshow

จากนั้นโหลดโมเดล Caffe ที่ฝึกไว้ล่วงหน้า

  • .prototxt เป็นโครงสร้างของโมเดล Layer ต่างๆ
  • .caffemodel เป็นน้ำหนักของโมเดลที่ฝึกมาแล้ว
  • และ pts_in_hull.npy คือชุดของจุดสี 313 เฉดใน a และ b ของ Lab color space
net = cv2.dnn.readNetFromCaffe
("colorization_deploy_v2.prototxt", "colorization_release_v2.caffemodel")
pts = np.load("pts_in_hull.npy")

ขั้นตอนที่ 4 เตรียมโมเดล

ต่อไปจะเป็นการเตรียมโมเดลให้พร้อมใช้งาน

  • ระบุเราจะใช้ layer ไหนของโมเดลในการปรับค่า
  • pts จะถูกปรับรูปร่างใหม่ให้โมเดลเข้าใจ
class8 = net.getLayerId("class8_ab")
conv8 = net.getLayerId("conv8_313_rh")
pts = pts.transpose().reshape(2, 313, 1, 1)
  • กำหนดจุดสีที่ใช้ในการทำนายสี
  • ใช้ค่าคงที่ 2.606 สำหรับการ Rebalancing เพื่อให้โมเดลทำนายสีหายากได้ดียิ่งขึ้น
net.getLayer(class8).blobs = [pts.astype("float32")]
net.getLayer(conv8).blobs = [np.full([1, 313], 2.606, dtype="float32")]

ขั้นตอนที่ 5 แปลงภาพจาก RGB เป็น Lab color space

ต่อไปเราจะทำการโหลดภาพขาวดำและแปลงภาพจาก RGB เป็น Lab color space

  • โหลดภาพขาวดำจาก path ที่เพื่อนๆใส่ไว้
  • ปรับค่าภาพให้อยู่ในช่วงที่โมเดลเข้าใจได้ 0-1
  • แปลงภาพจาก RGB เป็น Lab color space
image = cv2.imread("images/image1.jpg")
scaled = image.astype("float32") / 255.0
lab = cv2.cvtColor(scaled, cv2.COLOR_BGR2LAB)

ขั้นตอนที่ 6 ทำนายสี

เตรียม channel L และให้โมเดลทำนายสีกัน

  • ทำการ Resize ภาพเป็นขนาด 224x224 ตามที่โมเดลรองรับ
  • แยก channel L ออกมาใช้งาน
  • ลบ 50 เพื่อปรับค่าให้ตรงกับช่วงที่ใช้ตอนฝึกโมเดล
resized = cv2.resize(lab, (224, 224))
L = cv2.split(resized)[0]
L -= 50

ผลลัพธ์

ภาพ Resize

  • ส่ง L เข้าไปในโมเดล โมเดลจะทำนาย a และ b
  • เก็บแผนที่สีที่โมเดลทำนายได้ใน ab
net.setInput(cv2.dnn.blobFromImage(L))
ab = net.forward()[0, :, :, :].transpose((1, 2, 0))

ผลลัพธ์

ภาพทำนาย a

ภาพทำนาย b

ขั้นตอนที่ 7 รวม L+a+b กลับมาเป็นภาพสี และแสดงผล

มาถึงขั้นตอนสุดท้าย เราจะรวม L+a+b กลับมาเป็นภาพสี และแสดงผล

  • ปรับขนาดภาพ ab ให้เท่ากับภาพขาวดำต้นฉบับที่ใส่มาตอนแรก
  • รวม L+a+b ให้เป็นภาพในรูปแบบ Lab color space
ab = cv2.resize(ab, (image.shape[1], image.shape[0]))
L = cv2.split(lab)[0]
colorized = np.concatenate((L[:, :, np.newaxis], ab), axis=2)

ผลลัพธ์

ภาพรวม L+a+b

  • แปลงภาพ Lab color space กลับมาเป็นภาพ RGB
  • ตัดค่าที่เกินช่วง 0-1
  • แปลงค่ากลับมาเป็น 0-255 และชนิด uint8 เพื่อให้แสดงผลได้
colorized = cv2.cvtColor(colorized, cv2.COLOR_LAB2BGR)
colorized = np.clip(colorized, 0, 1)
colorized = (255 * colorized).astype("uint8")

จากนั้นเราก็จะได้ภาพสีแล้ววววววว เย้🥳

cv2_imshow(colorized)

ผลลัพธ์

ภาพสีของดอกไม้

ตัวอย่างการปรับภาพขาวดำสไตล์การ์ตูน Anime เป็นภาพสี

เนื่องจากที่ผ่านมาเป็นการใช้ภาพถ่ายจริงมาปรับเป็นภาพสี ดังนั้นในตัวอย่างต่อไปนี้ เราจะลองนำภาพขาวดำสไตล์การ์ตูน Anime มาลองปรับภาพสีดูบ้างกันดีกว่า!🎨

ภาพขาวดำสไตล์การ์ตูน Anime

โดยเราจะทำตามขั้นตอนเหมือนเดิมเลย แต่มีการเพิ่มเติมนิดหน่อยในขั้นตอนที่ 5

ขั้นตอนที่ 5 แปลงภาพจาก RGB เป็น Lab color space

เราจะทำการโหลดภาพขาวดำและแปลงภาพจาก RGB เป็น Lab color space เหมือนเดิม แต่ก่อนที่จะแปลงภาพจาก RGB เป็น Lab color space นั้น เราจะ...

  • แปลงภาพจาก RGB เป็น Grayscale (ขาวดำ 1 ช่อง)
  • เพิ่ม Contrast ภาพให้ชัดขึ้น จะช่วยแยกแสงเงาดีขึ้นเวลาทำนายสี
  • แปลงกลับจากภาพขาวดำเป็น RGB

✨ทำไมต้องเพิ่มโค้ดลงไปด้วยนะ?
เพราะภาพขาวดำสไตล์การ์ตูน Anime นั้นต่างจากภาพถ่ายจริงมาก ซึ่งอาจจะไม่แม่นยำมากนัก เพราะโมเดล Colorful Image Colorization ที่เราใช้ ถูกฝึกมาจากภาพถ่ายจริงที่มีแสงเงาและสีธรรมชาติ ไม่ใช่ลายเส้นการ์ตูน จึงต้องมีการแปลงเป็น Grayscale และปรับ Contrast ทำให้โมเดลเห็นได้ว่าตรงไหนมืด-สว่าง และสามารถเดาสีได้

image = cv2.imread("images/image1.jpg")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray_eq = cv2.equalizeHist(gray)
image = cv2.cvtColor(gray_eq, cv2.COLOR_GRAY2BGR)
scaled = image.astype("float32") / 255.0
lab = cv2.cvtColor(scaled, cv2.COLOR_BGR2LAB)

จากนั้นเราก็ทำตามขั้นตอนเดิมเลย!

โดยเมื่อเราทำมาถึงขั้นตอนที่ 7 ซึ่งเป็นขั้นตอนสุดท้าย

จะได้ภาพสีประมาณนี้ ซึ่งอาจจะเดาสีได้ไม่ค่อยแม่นยำสักเท่าไหร่

ผลลัพธ์

ภาพสีสไตล์การ์ตูน Anime

ส่วนภาพด้านล่างนี้ จะเป็นภาพสีสไตล์การ์ตูน Anime ที่ใช้โค้ดเดิม

ผลลัพธ์

ภาพสีสไตล์การ์ตูน Anime

โดยเราจะเห็นถึงความต่างของภาพทั้งสองภาพ ดูสิ! เพิ่มโค้ดแค่ 3 บรรทัดก็สามารถได้ภาพสีที่ดูดีขึ้นแล้ว🥳

สรุป :

สำหรับบทความนี้เราได้พาเพื่อนๆมาเติมสีสันให้กับภาพขาวดำด้วยเทคนิค Deep Learning กับ OpenCV ร่วมกับโมเดล Colorful Image Colorization โดยใช้ภาพถ่ายจริงและภาพขาวดำสไตล์การ์ตูน Anime✨ ใครอยากลองปรับหรือประยุกต์ต่อยอดจากนี้ก็ลองทำดูได้เลยน้า ง่ายนิดเดียว😉

References :

Colorful Image Colorization : https://richzhang.github.io/colorization/
Black and white image colorization with OpenCV and Deep Learning : https://www.geeksforgeeks.org/black-and-white-image-colorization-with-opencv-and-deep-learning/
Python การใช้ Deep Learning ปรับภาพขาวดำเป็นภาพสี BW to Color ร่วมกับ OpenCV : https://www.daydev.com/machine-learning/deep-learning-black-and-white-image-colorization-python-opencv.html
ภาพดอกไม้ : https://www.pinterest.com/pin/885661082960571527/
ภาพการ์ตูนสไตล์ Anime : https://th.pngtree.com/freebackground/black-and-white-photo-on-an-anime-girl-with-her-hood-up_3114037.html