ㄍ๏ สารบัญ ๏ㄟ
๛ การบวกลบรูปภาพ
๛ การหาค่าส่วนต่างระหว่างรูปภาพ
๛ การคูณหารรูปภาพ
๛ การผสมรูปภาพโดยถ่วงน้ำหนัก
ต่อจาก
บทที่ ๒
ในบทนี้จะพูดถึงการนำรูปภาพ ๒ รูปขึ้นไปมาทำอะไรกัน โดยพื้นฐานแล้วก็คือเป็นการบวกลบคูณหารอาเรย์ numpy
โดยมีการใช้ฟังก์ชันของ opencv เข้าร่วมในการคำนวณด้วยซึ่งเหมาะสมสำหรับใช้ในการคำนวณความสว่างของภาพ
โดยเฉพาะที่อยู่ในรูปแบบ uint8
การบวกลบรูปภาพ介
ข้อมูลรูปภาพเป็นอาเรย์ของ numpy ดังนั้นหากมีภาพที่ขนาดเท่ากัน ๒ ภาพก็สามารถนำมาบวกลบกันได้ด้วยเครื่องหมาย + - เลย
อย่างง่าย
แต่ปัญหาก็คือ ข้อมูลรูปภาพซึ่งส่วนใหญ่จะใช้เป็นข้อมูลชนิด uint8 นั้นมีค่าเป็นได้แค่จำนวนเต็มตั้งแต่ 0 ถึง 255 เท่านั้น
ถ้าหากเมื่อบวกกันแล้วเกิดค่าต่ำกว่า
0 หรือเกิน 255 ขึ้นมาก็จะทำให้เกิดปัญหาได้
หากเอาอาเรย์มาบวกลบกันธรรมดาแล้วค่าเกิน 255 ค่านั้นก็จะถูกหารปัดเศษ
ตัวอย่างเช่น สร้าง ๒ ภาพขาวดำที่มีการไล่สีขาวดำแนวตั้งและแนวนอน
imw03c01.png
imw03c02.png
ลองเอามาบวกกัน
imw03c03.png
ผลที่ได้จะออกมาแปลกๆอย่างที่เห็น นั่นคือส่วนที่ค่าเกิน 255 ไปจะกลับมาเป็น 0 นั่นคือค่าจะกลายเป็นเหมือนถูกหารด้วย 256
แล้วเอาเศษ (x = x%256)
หรือถ้าเอามาลบกัน ส่วนที่ต่ำกว่า 0 ก็จะกลับมาเป็น 255 อีก จึงออกมาแปลกๆแบบนี้
imw03c04.png
ซึ่งโดยทั่วไปเราคงจะไม่ได้ต้องการแบบนี้ ดังนั้นการนำอาเรย์รูปภาพมาบวกกันโดยตรงจึงไม่ควรนัก
แทนที่จะทำแบบนั้น เพื่อความปลอดภัยอาจใช้ฟังก์ชัน cv2.add() เวลาบวกกัน และ cv2.subtract() เวลาลบกันแทน
ข้อแตกต่างก็คือถ้าใช้ฟังก์ชันนี้บวกหรือลบแล้วค่าเกิน 255 ก็จะกลายเป็น 255 ไม่เกินนั้น ถ้าต่ำกว่า 0 ก็จะเป็น 0
imw03c05.png
imw03c06.png
คราวนี้ส่วนที่เกินจึงกลายเป็นขาวและดำไป
ภาพสีก็นำมาบวกลบได้เช่นเดียวกัน โดยสีเดียวกันก็จะบวกกันไป
ลองสร้างภาพที่มีเสียงไล่เรียงไปในแนวตั้งและแนวนอนคนละสีแล้วเอามาผสมกันดู
imw03c07.png
imw03c08.png
imw03c09.png
imw03c10.png
imw03c11.png
ผลลัพธ์มีหลายส่วนที่มีสีเป็นค่าเกิน 255 หรือต่ำกว่า 0 ส่วนที่เกินขอบเขตไปก็ถูกตัดเป็น 255 หรือ 0 ไป
ข้อแตกต่างจากการบวกลบอาเรย์ธรรมดาอีกอย่างก็คือ จะต้องทำกับข้อมูลชนิดเดียวกันเท่านั้น ถ้ามี uint8 จะไปบวกลบกับ float32
ก็ต้องแปลงตัวใดตัวหนึ่งเป็นอีกตัวก่อน ต่างจากเมื่อบวกกันธรรมดา
ลองเปรียบเทียบกันดู
อาเรย์ใน numpy ที่บวกลบกันธรรมดานั้นถ้าจำนวนเต็มบวกกับจำนวนจริงก็จะได้ผลเป็นจำนวนจริง
การหาค่าส่วนต่างระหว่างรูปภาพ介
นอกจากบวกลบกันธรรมดาแล้ว บางครั้งอาจต้องการเอา ๒ ภาพมาเทียบแล้วหักลบกันโดยหาส่วนต่าง ซึ่งทำได้โดยฟังก์ชัน
cv2.absdiff()
ตัวอย่างเทียบระหว่างหักลบด้วย cv2.absdiff() กับใช้ c2.subtract()
ใช้กับภาพขาวดำ
miku03c01.jpg
miku03c02.jpg
miku03c03.jpg
miku03c04.jpg
จะเห็นว่าเมื่อใช้ cv2.absdiff() ส่วนต่างไม่ว่าจะเกินมาจากภาพไหนก็จะได้ค่าออกมาเป็นค่าบวก
ต่อไปลองใช้กับภาพสี
miku03c05.jpg
miku03c06.jpg
miku03c07.jpg
miku03c08.jpg
การคูณหารรูปภาพ介
เมื่อมีบวกลบก็ย่อมมีคูณหารด้วย ฟังก์ชันคูณใน cv2 คือ cv2.multiply() ส่วนฟังก์ชันหารคือ cv2.divide()
หลักการก็เหมือนกับตอนบวกและลบ คือค่าจะไม่พ้นไปจากในขอบเขต 0 ถึง 255
ประโยชน์การใช้งานเช่นอาจสร้างตัวคูณที่จะทำให้เกิดการไล่สีต่างกันไปในแต่ละบริเวณ
ตัวอย่างเช่น มีภาพนี้อยู่
teto03c01.jpg
และลองสร้างภาพไล่สีแบบนี้ขึ้นมาเป็นตัวคูณ
a03c01.jpg
สามารถเอาภาพแรกมาคูณกับตัวไล่สีเพื่อจะให้ได้ภาพที่มีลักษณะไล่สีไปตามที่คูณได้
เพียงแต่ว่ามีความยุ่งยากอยู่เล็กน้อย เนื่องจากข้อมูลภาพมีค่าอยู่ในช่วง 0 ถึง 255 แบบนี้จึงไม่สามารถเอามาคูณกันได้เลย
ควรปรับขนาดตัวคูณให้เป็นค่า 0 ถึง 1
และการบวกลบคูณหารอาเรย์จะต้องทำโดยอาเรย์ที่มี dtype ชนิดข้อมูลเดียวกัน
ดังนั้นจึงต้องเปลี่ยนชนิดข้อมูลภาพให้เป็นชนิดจำนวนจริงไปด้วย
ในที่นี้ทำให้เป็น float32 เหมือนกันไปด้วย แล้วลองนำมาคูณกันดู
teto03c02.jpg
เวลาที่จะนำผลที่ได้มาใช้ต่ออีกนั้น บางกรณีอาจต้องเปลี่ยนกลับเป็น uint8 ขึ้นอยู่กับว่าจะไปใช้กับฟังก์ชันอะไรต่อ แต่สำหรับ cv2.imwrite()
ซึ่งใช้บันทึกภาพลงไฟล์นั้นจะใช้ข้อมูลชนิดใดก็ได้จึงไม่จำเป็นต้องเปลี่ยนกลับก็ได้
ต่อมาลองเปลี่ยนมาเป็นหารดู
teto03c03.jpg
นอกจากนี้มีฟังก์ชัน cv2.pow() ไว้คำนวณยกกำลัง cv2.max() กับ cv2.min() เอาไว้ใช้คัดเอาค่าสูงสุดหรือต่ำสุด (คล้าย
np.maximum และ np.minimum ของ numpy แต่ต่างจาก np.max หรือ np.min)
การผสมรูปภาพโดยถ่วงน้ำหนัก介
ฟังก์ชัน cv2.addWeighted() ใช้นำภาพ ๒ ภาพมารวมกันโดยถ่วงน้ำหนักตามที่กำหนด
วิธีใช้
ภาพใหม่ที่ได้จากการผสมจะมีค่าเป็น αx
1+βx
2+γ
โดย
- x1 คือ ภาพที่ ๑
- α คือ น้ำหนักของภาพที่ ๑
- x2 คือ ภาพที่ ๒
- β คือ น้ำหนักของภาพที่ ๒
- γ คือ ค่าที่บวกเพิ่มเติม
α+β จะเป็นตัวกำหนดว่าจะผสมเอาภาพไหนด้วยอัตราส่วนน้ำหนักเท่าไหร่ โดยทั่วไปจะให้ α+β=1
เพื่อให้ได้ความสว่างออกมาค่าอยู่ในช่วงระหว่างค่าของ ๒ ตัว
ลองใช้ ๒ ภาพนี้เป็นตัวอย่าง
teto03c04.jpg
teto03c05.jpg
เอามาผสมกันด้วยน้ำหนักที่ต่างกันไป
teto03c06.jpg
teto03c07.jpg
teto03c08.jpg
ด้วยการใช้น้ำหนักที่ต่างกันไปเรื่อยๆแบบนี้ทำขึ้นมาหลายภาพก็จะได้ภาพที่แสดงขั้นตอนการเปลี่ยนไปทีละขั้นแบบนี้ได้
อ่านบทถัดไป >>
บทที่ ๔