ㄍ๏ สารบัญ ๏ㄟ
๛ การแปลงระบบสี
๛ การแปลงสีเป็นขาวดำ
๛ ระบบสี HSV
๛ การคัดกรองเฉพาะสีในขอบเขตที่ต้องการ
๛ การกลับสี
๛ การแยกและรวมสี
ต่อจาก
บทที่ ๓
ในบทนี้จะว่าด้วยเรื่องของระบบของสีและการแปลงสีไปมาระหว่างระบบต่างๆ
รวมถึงการคัดกรองเอาเฉพาะบริเวณที่ต้องการโดยใช้สีเป็นเกณฑ์
การแปลงระบบสี介
ในการแสดงผสมและแสดงสีในคอมพิวเตอร์นั้นโดยทั่วไปเราจะคุ้นเคยกับระบบ RGB คือ แดง, เขียว, น้ำเงิน ในขณะที่ opencv
จะสลับลำดับของสีแดงกับน้ำเงิน กลายเป็น BGR ซึ่งก็คือ น้ำเงิน, เขียว, แดง
นอกจากนี้ยังมีระบบ HSB ซึ่งนิยมใช้ เกี่ยวกับระบบนี้จะกล่าวถึงโดยละเอียดในหัวข้อถัดไป
ใน opencv มีฟังก์ชันที่ช่วยในการแปลงสีระหว่างระบบต่างๆ นั่นคือ cv2.cvtColor()
วิธีใช้
ลำดับ |
ชื่อ |
สิ่งที่ต้องใส่ |
ชนิดข้อมูล |
1 |
src |
อาเรย์รูปภาพ |
np.array |
2 |
code |
รหัสแปลงสี |
flag (int) |
ในส่วนของรหัสแปลงสีนี้ค่าที่ใส่คือแฟล็กที่ cv2 เตรียมไว้ให้ ซึ่งจะมีชื่อขึ้นต้นด้วย COLOR_
และตามด้วยระบบที่แปลงโดยมีเลข 2
คั่น แบบนี้
เช่นถ้าแปลงจาก RGB เป็น HSV ก็จะใช้ cv2.COLOR_RGB2HSV ถ้ากลับกันก็จะเป็น cv2.COLOR_HSV2RGB
ระบบสีที่แปลงไปมาได้มีอะไรบ้างอาจลองมาดูรายชื่อแฟล็กทั้งหมดได้ดังนี้
เวลาที่จะแปลงจากระบบ BGR ใน opencv ให้เป็น RGB เช่นเพื่อใช้ใน matplotlib อาจใช้ cv2.cvtColor โดยใส่
cv2.COLOR_BGR2RGB
การแปลง BGR>RGB แบบนี้อาจใช้ rup[:,:,::-1] ดังที่ได้กล่าวในบทที่ ๒ ไปแล้วแทนได้ รวมทั้งแปลงกลับ
แต่ถ้าเป็นระบบที่มีค่าความโปร่งใสอยู่ด้วยก็จะยุ่งยากเข้ามาหน่อย และชื่อโหมดเวลาแปลงโหมดที่มีความโปร่งใสจะเพิ่มตัว A
เข้ามา เช่นถ้าแปลง BGR ที่มีความโปร่งใสด้วยเป็น RGB ก็ใช้cv2.COLOR_BGRA2RGBA
ตัวอย่างเช่นลองเอาภาพนี้ซึ่งมีฉากหลังโปร่งมาแปลงเป็น RGBA เพื่อมาแสดงใน matplotlib
miku04c01.png
การแปลงสีเป็นขาวดำ介
สีขาวดำก็ถือเป็นสีระบบหนึ่งเช่นกัน ในนี้ใช้คำว่า GRAY
ยกตัวอย่างการแปลงจากสี BGR เป็นสีขาวดำ ใช้ cv2.COLOR_BGR2GRAY
rin04c01.jpg
rin04c02.jpg
อย่างไรก็ตาม ถึงไม่แปลงด้วยวิธีนี้ ก็สามารถเปิดในโหมดขาวดำแล้วเอามาบันทึกใหม่ทันทีก็ได้ไฟล์ภาพขาวดำเช่นกัน
ในทางกลับกัน จะใช้ cv2.COLOR_GRAY2BGR เพื่อแปลงภาพขาวดำเป็นภาพสี BGR ก็ได้ แต่ก็ไม่ได้ทำให้ได้ภาพที่มีสีขึ้นมา
แค่ทำให้ได้ค่าน้ำเงินเขียวแดง ๓ สีที่มีค่าเท่ากัน
เวลาแสดงภาพขาวดำด้วย imshow ของ matplotlib อาจใช้ cv2.COLOR_GRAY2RGB แปลง
ระบบสี HSV介
ในขณะที่ระบบ RGB หรือ BGR ใช้เลข ๓ ตัวแทน ๓ สีที่เป็นส่วนผสม ระบบสี HSV เองก็ประกอบไปด้วยค่า ๓ ค่า
แต่ไม่ได้แทนค่าสีต่างๆ แต่ ๓ ค่านั้นมีความหมายดังนี้
- H (hue) ค่าเฉดสี มีค่าตั้งแต่ 0-179 เป็นค่าที่บอกว่าสีอยู่ในช่วงไหน สีแดงเป็น 0 สีเขียวเป็น 60
สีน้ำเงินเป็น 120
- S (saturation) ค่าความอิ่มตัว หรือความสดของสี มีค่าตั้งแต่ 0-255 ยิ่งค่าสูงสียิ่งสด
- V (value) ค่าความสว่าง มีค่าตั้งแต่ 0-255 ยิ่งสูงยิ่งสว่าง
เพื่อให้เห็นภาพชัดว่าตัวแปร H S V อันไหนส่งผลต่อสีอย่างไรบ้าง ลองวาดออกมาเป็นแผนภาพไล่สี โดยแบ่งเป็น ๓ อัน
ต่อไปลองทำเป็นตัวอย่างโดยสร้างค่า H S V ต่างๆจากนั้นแปลงสีเป็น RGB เพื่อแสดงด้วย matplotlib (ในที่นี้ใช้ np.meshgrid เพื่อสร้างโครงข่าย
รายละเอียดอ่านได้ใน
numpy & matplotlib บทที่
๒๔)
ลองให้ h คงที่อยู่ที่ 135 แล้วไล่ค่า s กับ v
ต่อมาลองให้ s คงที่อยู่ที่ 200 แล้วไล่ค่า h กับ v
สุดท้ายลองให้ v คงที่อยู่ที่ 200 แล้วไล่ค่า h กับ s
อย่างไรก็ตาม ระบบ HSV อาจมีความแตกต่างกันไปขึ้นอยู่กับว่าใช้ที่ไหน ขอบเขตของ H อาจเป็นค่ามุมซึ่งสูงสุดที่ 360 แทน ส่วน
S กับ V อาจมีค่าเป็นเปอร์เซ็นต์เต็ม 100 และชื่อเรียกบางทีก็อาจเรียกว่า HSL หรือ HSB
ดังนั้นค่าที่แสดงในตัวอย่างนี้เป็นค่าในระบบของ opencv เอง ถ้าไปใช้ที่อื่นก็ต้องแปลงค่าให้เข้าตามนั้น
การคัดกรองเฉพาะสีในขอบเขตที่ต้องการ介
ฟังก์ชัน cv2.inRange() ใช้ในการพิจารณาค่าสีภายในภาพว่าเข้าช่วงที่ต้องการหรือไม่ โดยจะพิจารณาทุกสีไปพร้อมกัน
ฟังก์ชันนี้จะให้ค่าออกมาเป็นอาเรย์ ๒ มิติ ซึ่งมีขนาดเท่ากับขนาดภาพ และมีค่าเป็น 255
หากค่าจุดนั้นอยู่ในขอบเขตช่วงที่กำหนด นอกนั้นจะเป็น 0
cv2.inRange() จะใช้กับระบบสี RGB, BGR หรือ HSV ก็ได้
ขอยกตัวอย่างการคัดกรองสีโดยใช้ภาพนี้ จะเห็นว่าในภาพมีสีน้ำเงินกับสีเหลืองที่ค่อนข้างเด่น โจทย์คือถ้าอยากจะคัดกรองเอาเฉพาะส่วนนั้นโดยใช้สีเป็นเกณฑ์ควรทำอย่างไร?
rin04c03.jpg
เริ่มจากลองใช้กับระบบสี BGR ดู เพื่อคัดเอาเฉพาะส่วนที่มีสีน้ำเงินมากเหลือไว้
rin04c04.jpg
ผลที่ได้คือแถวที่มีส่วนประกอบของสีน้ำเงินอยู่ต่ำเกินก็จะถูกกรองออกไป แต่ว่าสีอื่นที่มีส่วนประกอบของสีน้ำเงินก็ยังอยู่ เช่นสีขาวและสีที่สว่างมาก
ต่อมาลองเปลี่ยนเป็นกรองสีเหลือง ซึ่งหมายถึงมีทั้งสีแดงและเขียวอยู่มากพร้อมกัน
rin04c05.jpg
พื้นที่ที่ถูกกรองออกก็จะต่างไป คราวนี้ส่วนสีน้ำเงินหายไป แต่จะเห็นว่าส่วนสีขาวไม่ว่าจะกรองยังไงก็จะเหลืออยู่เสมอ
ดังนั้นการกรองในระบบ BGR นั้นไม่เหมาะที่จะคัดกรองเอาเฉดสีที่ต้องการ กรณีนี้ถ้าแปลงเป็นระบบ HSV จะเหมาะกว่า
ตัวอย่างต่อไปใช้ภาพเดิม แต่คราวนี้ลองกรองในระบบ HSV หาเฉดสีน้ำเงินดู
rin04c06.jpg
คราวนี้ลองดูเฉดสีเหลือง
rin04c07.jpg
จากตัวอย่างข้อแตกต่างระหว่างการกำหนดขอบเขตด้วยระบบ BGR ดับ HSV โดยจะเห็นว่าแม้จะกำหนดเงื่อนไขที่ตัวสี
โดยเส้นสีน้ำเงินและเหลืองเหมือนกัน แต่สำหรับ BGR นั้นแค่สนว่ามีสีน้ำเงินอยู่ปริมาณมากพอ แต่สีอื่นก็อาจปนอยู่มากเช่นกัน
ทำให้สีอาจไม่ได้ออกเป็นสีน้ำเงิน
ในขณะที่เมื่อใช้ HSV เพื่อคัดกรอง จะสามารถกรองเอาเฉพาะที่เฉดสีไปทางสีที่ต้องการได้ จึงเหลือแค่ที่ออกไปในทางสีน้ำเงิน
คือตรงหน้าจอสีน้ำเงิน และแสงจากหน้าจอที่สะท้อนลงบนคีย์บอร์ด
ดังนั้นจะเห็นได้ถึงประโยชน์ของการแปลงเป็นระบบ HSV ระบบนี้อาจเหมาะสมในการใช้ในงานบางจำพวกมากกว่า BGR
การแปลงระบบสีไปมาเพื่อให้เหมาะสมกับการใช้งานจึงเป็นเทคนิคหนึ่งที่สำคัญ
การกลับสี介
ฟังก์ชัน cv2.bitwise_not() ใช้เพื่อกลับค่าสีในระบบ BGR จากมืดเป็นสว่าง สว่างเป็นมืด
ตัวอย่าง
gumi04c01.jpg
gumi04c02.jpg
การแยกและรวมสี介
cv2.split() เอาไว้แยกสีของภาพออกเป็นลิสต์ของค่าแต่ละสี ส่วน cv2.merge()
ใช้รวมลิสต์ของค่าแต่ละสีเข้าเป็นอาเรย์ของภาพสี
ลองยกตัวอย่างด้วยการแยกสีภาพออกเป็น ๓ สี แล้วก็เอามารวมใหม่ให้อีก ๒ สีเป็นศูนย์ ก็จะได้ภาพที่มีองค์ประกอบของ ๓
สีแยกกัน
miku04c03.jpg
อ่านบทถัดไป >>
บทที่ ๕