ตัวอย่างนี้คุณจะได้เรียนรู้วิธีปรับภาพขาวดำให้เป็นภาพสี Black & White เป็น Colorโดยใช้ OpenCV, Deep Learning และ Python
บทเรียนก่อนหน้า:
- Python กับ OpenCV เทคนิคการทำ Inpainting ตกแต่งภาพที่เสียหาย
- Review: บริการ AI for Thai จำป้ายทะเบียนรถ T-LPR ด้วย Python กัน
- การทำ Face Detection บน Video ด้วย Python และ OpenCV
- Object Detection ตรวจจับวัตถุด้วย Python และ TensorFlow ร่วมกับ MatplotLib
- Python กับ OpenCV ดึงฐานข้อมูล Face Recognition ผ่านระบบ Firebase
รอบนี้เราจะใช้ Deep Learning กันซึ่งเราจะใช้ Model มาช่วยในการระบายสีของภาพที่เป็นภาพขาวดำให้กลายเป็นภาพสี (เทคนิค BW2Color) โดยเราจะต้องศึกษากระบวนการที่ว่า เราจะทำให้ภาพขาวดำเป็นภาพสีด้วย Deep Learning ได้อย่างไร
เทคนิคคงต้องใช้ Model ของ Zhang และคณะ จาก Conference นี้: http://richzhang.github.io/colorization/
- Zhang, Isola, Efros. Colorful Image Colorization. In ECCV, 2016 (oral). (hosted on arXiv)>
มันมีเรื่องของอัลกอริทึม Deep Dream ที่ว่าด้วยภาพและสี การทำให้สีของภาพขาวดำอาศัยการรับรู้แบบ “unbelievable” แน่นอนมันเชื่อไม่ได้หากเทียบสามัญสำนึกของมนุษย์ด้วยจากข้อมูลใน Model ผลลัพธ์ที่ได้อาจจะเป็นสีที่ใกล้เคียง หรือไม่ได้ตรงกับการรับรู้แต่อย่างใด อาจจะไม่ใช่สีที่แท้จริง แต่เป็นการเติมเต็มในรูปแบบของสีที่มนุษย์ยอมรับได้ว่ามันเป็นภาพที่ตกแต่งสีแล้ว
Zhang ใช้วิธีการนำเข้าชุดข้อมูล ImageNet และแปลงรูปภาพทั้งหมดจากพื้นที่สี RGB เป็น Lab color space เช่นเดียวกับพื้นที่สี RGB พื้นที่สี Lab มีสามช่องทาง (R=Red, G=Green, B=Blue) แต่ Lab แตกต่างจากพื้นที่สี RGB Lab จะเข้ารหัสข้อมูลชุดสีแตกต่างกัน:
- L เข้ารหัสความเข้มของแสงเท่านั้น (Lightness Intensity) หรือ Luminance เป็นการกำหนดความสว่างซึ่งมีค่าตั้งแต่ 0 ถึง 100 ถ้ากำหนดที่ 0 จะกลายเป็นสีดำ แต่ถ้ากำหนดที่ 100 จะกลายเป็นสีขาว
- a จะเข้ารหัสชุดสีเขียว – แดง (encodes green-red)
- b เข้ารหัสชุด สีน้ำเงิน – เหลือง (encodes blue-yellow)
กระบวนการของ Lab Color ของ Zhang ก็ Based มาจาก ระบบสีแบบ Lab ตามมาตรฐานของ CIE ซึ่งไม่ขึ้นอยู่กับอุปกรณ์ใดๆ ระบบสีแบบ Lab เป็นค่าสีที่ถูกกำหนดขึ้นโดย CIE (Commission Internationale d’ Eclarirage)ศึกษาได้ที่ https://en.wikipedia.org/wiki/CIELAB_color_space
กลับมากระบวนการนี้ แปลงภาพการฝึกอบรมทั้งหมดจากพื้นที่สี RGB เป็นพื้นที่สี Lab ใช้ช่อง L เป็นสัญญาณเข้าสู่ Train Network ทำการ Predict ช่อง ab รวม Channel L เข้ากับ ab แล้วจึงแปลงภาพ Lab กลับเป็น RGB
โหลด Model ที่จะใช้ Deep Learning ที่นี่: https://drive.google.com/file/d/1Rfxzbe1hfjge9JyKB8d8vtjAkm-K8JDC/view?usp=sharing
ทำการสร้าง โฟลเดอร์ชื่อ model แล้วแตก zip นำไฟล์ model ไปไว้ในโฟลเดอร์นั้นครับ เตรียมไฟล์รูปภาพขาวดำไว้ทดสอบบทเรียนนี้:
สร้างไฟล์ bw_to_color.py ขึ้นมาประกาศตัวแปร:
import numpy as np import cv2
ใช้ numpy และ OpenCV มาประมวลผลภาพ
net = cv2.dnn.readNetFromCaffe("model/colorization_deploy_v2.prototxt", "model/colorization_release_v2.caffemodel") pts = np.load("model/pts_in_hull.npy")
ทำการโหลด colorization_deploy_v2.prototxt ใน model มาเทียบ Caffe (คือเจ้า Caffe, http://caffe.berkeleyvision.org/ เป็นชุดคำสั่งสำหรับใช้งาน neural network deep learning ตระกูล convolutional neural network (CNN) ค่อนข้างง่าย และหาโหลดบทเรียนเพิ่มศึกษาได้ง่าย)
ไปเรียก readNetFromCaffe() มาทำงานผ่าน GPU
class8 = net.getLayerId("class8_ab") conv8 = net.getLayerId("conv8_313_rh") pts = pts.transpose().reshape(2, 313, 1, 1) net.getLayer(class8).blobs = [pts.astype("float32")] net.getLayer(conv8).blobs = [np.full([1, 313], 2.606, dtype="float32")]
เป็นคำสั่งในการ rebalancing ปรับสมดุลปริมาณของสี Channel a และ b โดยเชื่อม Convolutions รูปแบบ 1×1 ไปที่ละส่วน เข้าไปใน model
image = cv2.imread("images/crowd.jpg") scaled = image.astype("float32") / 255.0 lab = cv2.cvtColor(scaled, cv2.COLOR_BGR2LAB)
imread ทำการโหลดรูปภาพจาก Path ของเรา ทำการเริ่ม Preprocessing ประกอบด้วย การปรับความเข้มของพิกเซลให้อยู่ในช่วง [0, 1] และ การแปลงจาก BGR เป็นพื้นที่สี Lab
resized = cv2.resize(lab, (224, 224)) L = cv2.split(resized)[0] L -= 50
ประมวลผลภาพต่อเนื่อง ปรับขนาดภาพอินพุตเป็น 224 × 224 ซึ่งเป็นขนาด input ที่จำเป็นสำหรับ network ประมวลผลของ Channel L เป็นหลักก่อนหาค่า intensity และทำการลบค่าเฉลี่ย เมื่อได้ค่า L แล้วเราจะ Predict คาดการณ์ channel a,b ได้
ต่อมาคือการประมวลค่าสีใส่ในภาพ
net.setInput(cv2.dnn.blobFromImage(L)) ab = net.forward()[0, :, :, :].transpose((1, 2, 0)) ab = cv2.resize(ab, (image.shape[1], image.shape[0])) L = cv2.split(lab)[0] colorized = np.concatenate((L[:, :, np.newaxis], ab), axis=2) colorized = cv2.cvtColor(colorized, cv2.COLOR_LAB2BGR) colorized = np.clip(colorized, 0, 1) colorized = (255 * colorized).astype("uint8")
คือมัน Resize เพื่อ Predict ให้กับ channel a.b แล้ว เราก็ทำการแสดงผลภาพกันหน่อย
cv2.imshow("Original", image) cv2.imshow("Colorized", colorized) cv2.waitKey(0)
ตัวอย่างไฟล์ทั้งหมดของวันนี้:
import numpy as np import cv2 print("Load Model to Network") net = cv2.dnn.readNetFromCaffe("model/colorization_deploy_v2.prototxt", "model/colorization_release_v2.caffemodel") pts = np.load("model/pts_in_hull.npy") class8 = net.getLayerId("class8_ab") conv8 = net.getLayerId("conv8_313_rh") pts = pts.transpose().reshape(2, 313, 1, 1) net.getLayer(class8).blobs = [pts.astype("float32")] net.getLayer(conv8).blobs = [np.full([1, 313], 2.606, dtype="float32")] image = cv2.imread("images/crowd.jpg") scaled = image.astype("float32") / 255.0 lab = cv2.cvtColor(scaled, cv2.COLOR_BGR2LAB) resized = cv2.resize(lab, (224, 224)) L = cv2.split(resized)[0] L -= 50 'print("Post Process Coloring")' net.setInput(cv2.dnn.blobFromImage(L)) ab = net.forward()[0, :, :, :].transpose((1, 2, 0)) ab = cv2.resize(ab, (image.shape[1], image.shape[0])) L = cv2.split(lab)[0] colorized = np.concatenate((L[:, :, np.newaxis], ab), axis=2) colorized = cv2.cvtColor(colorized, cv2.COLOR_LAB2BGR) colorized = np.clip(colorized, 0, 1) colorized = (255 * colorized).astype("uint8") cv2.imshow("Original", image) cv2.imshow("Colorized", colorized) cv2.waitKey(0)
ทดสอบ Run ดูผลลัพธ์
ยากไปนิดถ้าจะพยายามให้มันเป๊ ที่บอกมันมากจาก Model และ Deep Learning ครับมีทางเดียวคือต้อง Train Model เอง
ลองอีกภาพโดยกาจาก Internet
เอามาทดสอบสิ
ลอง Taxi บ้าง
ใกล้เคียงนะครับแม้ว่าจริงๆ เราจะคาดหวังถึงสี เขียว เหลือง