SKCONAN

อ่านไฟล์ภาพด้วย OpenCV และ Pillow

January 07, 2019

title

บทความก็จะมาเล่าวิธีการอ่านไฟล์รูปภาพโดยใช้ Python โดยปกติผมจะใช้ library ที่ชื่อว่า OpenCV ในการทำ Image processing แต่บางครั้งการอ่านไฟล์ภาพ .gif ก็ไม่สามารถใช้คำสั่ง cv2.imread ของ OpenCV ได้

วันนี้ก็เลยจะมาแนะนำการอ่านไฟล์ภาพด้วย OpenCV และ Pillow นะครับ

ส่วนภาพข้างบนไม่เกี่ยวกับบทความนะครับ แค่เห็นมันสวยดีใครจะลองเอาไปใช้เขียนโปรแกรมอ่านไฟล์ภาพก็ได้นะ


เริ่มที่ OpenCV กันก่อนเลยครับ

สมมติ ให้ไฟล์ของเราอยู่ที่ C:\Users\skconan\Desktop\skconan-blog\content\blog\python-read-img\title.png

เราจะใช้ function cv2.imread(path,flags)

Parameters Description
path เป็นที่อยู่ของไฟล์ภาพ
flags ประเภทของสีที่ใช้ในการอ่านไฟล์ภาพ

ประเภทของสี หรือค่าของ flags ที่ผมใช้บ่อยๆมี 3 ค่าครับ

Value Description
> 0 จะ return ภาพที่เป็น 3 Channel
= 0 จะ return ภาพขาวดำ หรือ Grayscale
< 0 จะ return ภาพที่เพิ่ม Channel alpha มา ซึ่งค่า alpha คือ ค่าความโปร่งใสของภาพ

มาดูตรงนี้กันนิดนึงครับ อันนี้เป็นส่วนที่ผมเคยพลาดมา

  1. ถ้ามีการใช้ \ (blackslash) ตรง path จะต้องมี r นำหน้า เช่น r’C:\Users\skconan\Desktop\image.jpg’ เพื่อให้รู้ว่า string นี้เป็น raw string

  2. ใน OpenCV จะอ่านไฟล์ภาพ และแสดงผลเป็น BGR นะครับ ไม่ใช่ RGB ซึ่งคำสั่งที่ใช้แสดงผล คือ cv2.imshow() รับภาพเป็น BGR นะครับ ย้ำหลายรอบหน่อย 5555

ตอนนี้ก็มาดูโค้ดกันครับ จะยกตัวอย่างการอ่านภาพสี และก็แสดงผลด้วยคำสั่ง cv2.imshow() นะครับ

import cv2

img = cv2.imread(r'C:\Users\skconan\Desktop\skconan-blog\content\blog\python-read-img\title.png',1)

cv2.imshow('images', img)

cv2.waitKey(-1)

ต่อมาจะเป็นการอ่านไฟล์ภาพด้วย Pillow

ปกติ data type ภาพของ Pillow จะแตกต่างจาก OpenCV เมื่อเราอ่านไฟล์ภาพด้วย Pillow แล้วก็จะต้องแปลงภาพทให้สามารถใช้กับ OpenCV ได้ ซึ่ง data type ภาพของ OpenCV จะเป็น numpy array นั้นเองครับ มาดูโค้ดกันเลยครับ

import cv2
import numpy as np
from PIL import Image

pil = Image.open('C:\Users\skconan\Desktop\skconan-blog\content\blog\python-read-img\title.png').convert('RGB') 

pil = np.array(pil) 

r,g,b = cv2.split(pil)

pil = cv2.merge((b,g,r))

cv2.imshow('pil',pil)

cv2.waitKey(-1)

มาดูโค้ด 3 บรรทัดนี้กันหน่อยครับ

pil = np.array(pil) 

r,g,b = cv2.split(pil)

pil = cv2.merge((b,g,r))

เริ่มที่บรรทัดแรกก่อนนะครับ จะเป็นการแปลง data type ให้เป็น numpy array นั้นเองครับ

ส่วน 2 บรรทัดสุดท้าย จะเป็นการแบ่งภาพออกเป็น 3 Channel R G B แล้วก็รวมเป็นภาพใหม่ BGR เพื่อให้แสดงผลได้ถูกต้อง แล้วทำไปทำไมใช่มั้ยครับ ถ้าใครนึกไม่ออกลองย้อนไปอ่านข้างบนเรื่องการแสดงผลของ OpenCV ดูนะครับ

อันนี้เป็นภาพสีส้มที่เราเห็นในคอมพิวเตอร์นะครับ ตรงตามรางไม่เกี่ยวนะครับเปิดใน vs code เลยเป็นแบบนั้น

orange

ถ้าเราอ่านภาพโดยใช้ Pillow แล้วไม่แปลงเป็น BGR ผลลัพธ์ก็จะเป็นตามนี้นะครับ ภาพขวา ใช้ cv2.imread() ส่วนภาพซ้ายใช้ Image.open() ของ Pillow

compare

ซึ่งที่กล่าวมาทั้งหมดเราจะเห็นว่าแต่ละ Library ก็มีความแตกต่างกัน ซึ่งผมไม่ได้บอกว่าอะไรดีไม่ได้นะครับ แต่ผมใช้ OpenCV เป็นหลักเลยต้องแปลงภาพจาก Pillow มาเป็นมาตรฐานของ OpenCV

หากใครชอบเนื้อหาที่ผมเขียน สามารถร่วมกัน Donate เพื่อเป็นค่ากาแฟได้นะครับ ^^


ใครที่สงสัยจุดไหน หรือพบว่าจุดไหนที่ผมอธิบายผิด สามารถเข้ามาพูดคุยกันได้นะครับ inbox มาที่ Facebook, Twitter เลยก็ได้ครับ หรือ mail มาที่ supakit.kr@gmail.com จะยินดีมากเลยครับ



Written by Supakit Kriangkhajorn

© 2019, Built with