SKCONAN

มารู้จัก Simple Thresholding กัน (พร้อมตัวอย่างการใช้งานบน OpenCV)

January 14, 2019

title

Threshold คืออะไร

ก่อนจะรู้จัก Simple Thresholding เรามาดูความหมายของคำว่า Threshold กันก่อน

Threshold ก็คือเกณฑ์ที่ใช้แบ่งสิ่งใดสิ่งหนึ่ง เช่น

มีรถอยู่ 5 คัน ขับด้วยความเร็ว ดังนี้ 60, 156, 120, 80 และ 180 กม.ต่อชม. แล้วเราก็เถียงกับเพื่อนว่า คันไหนขับเร็ว คันไหนขับช้า เราเลยต้องมีเกณฑ์มาแบ่ง

สมมติเราให้ รถที่ขับเร็วกว่า 90 กม.ต่อชม. เป็นรถที่ขับเร็ว เราเรียกค่านี้ว่า Threshold Value


Simple Thresholding คืออะไร

ภาพที่จะพูดถึงในบทความจะมีความลึกของสีอยู่ที่ 8-bit หรือมีค่า intensity อยู่ระหว่าง 0 - 255

คือ การนำภาพ 1 Channel (หรือ Grayscale Image) มาแปลงค่า intesity ของแต่ละ Pixel ให้เหลือเพียง 2 ค่า คือ 0(ดำ) กับ 255(ขาว) เราเรียกภาพที่มีค่า intensity เพียง 2 ค่า ว่า “Binary Image” โดยเราจะใช้ Threshold Value ในการแบ่งว่า Pixel ที่มี intensity XX ควรมีค่าเท่าไหร่ ดังนี้

  1. pixel ที่มีค่า มากกว่าเท่ากับ Threshold Value มีค่าเท่ากับ 255 หรือสีขาว

  2. pixel ที่มีค่า น้อยกว่า Threshold Value มีค่าเท่ากับ 0 หรือสีดำนั้นเองครับ

สมมติ เรามีภาพอยู่หนึ่งภาพ แล้วอยากลบพื้นหลังออก (บางภาพก็อาจจะใช้วิธีนี้ไม่ได้)

00

โดยการแปลงเป็น Grayscale ก่อน

grayscale

แล้วดู Histogram (ใครไม่รู้ว่า histogram คืออะไร ลองอ่านอันนี้ดูนะครับ) ว่ามีค่าสีไปกองอยู่ตรงไหนเยอะ เพราะ ถ้าเราลองสังเกตดู background ส่วนใหญ่จะเป็นสีฟ้าโทนเดียวกันหมดเลย แล้วก็มีจำนวน pixel เกินครึ่งนึงของรูปภาพ

ก็แสดงว่าบริเวณที่ ค่า intensity มีจำนวน pixel เยอะ หรือพูดง่ายๆก็คือ บริเวณที่กราฟสูงๆฐานกว้างกว่าจุดอื่นนั้นแหละ คือ background

histogram

ถ้าเป็นภาพนี้ก็จะเห็นว่าค่าสีส่วนใหญ่ มากกว่า 160 เราจึงใช้ 160 เป็น Threshold Value จะได้ผลลัพธ์ดังนี้

result
import cv2

from matplotlib import pyplot as plt

img = cv2.imread('00.png')

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

hist = cv2.calcHist([gray], [0], None, [256], [0, 256])

_, th = cv2.threshold(gray,160,255,cv2.THRESH_BINARY)

cv2.imshow('images', img)

cv2.imshow('Simple Thresholding', th)

cv2.imshow('Grayscale', gray)

plt.plot(hist, color='blue')

plt.title('Histogram of Grayscale')

plt.show()

จากผลลัพธ์ Pixel ที่เป็นสีดำจะมีค่าเป็น 0 ส่วนสีขาวจะมีค่าเป็น 255 ซึ่งเพิ่งเท่านี้เรายังไม่สามารถลบ พื้นหลัง ออกได้เดี๋ยวคราวหน้าจะมาสอนสร้าง mask ไว้คุมตัวโคนันแล้วลบพื้นหลังทิ้ง

มาดูฟังก์ชั่นที่เราใช้หา Threshold กัน

ฟังก์ชั่นที่ใช้ก็จะเป็น

cv2.threshold(Grayscale, th_value, max_value, style)
parameter ความหมาย
Grayscale ภาพขาวดำ ที่จริงมันก็คือ ภาพที่มี 1 Channel เราอาจจะไม่ต้องแปลงเป็น Grayscale แต่เอา Channel R, G หรือ B มาใช้เลยก็ได้ด้วยการใช้ Function cv2.split()
th_value Threshold value นั้นแหละครับ
max_value ค่าสีที่ใช้แสดง เมื่อ Pixel นั้นมีค่ามากกว่า th_value เช่น ถ้าเราลดจาก 255 เป็น 200 ภาพผลลัพธ์ที่ได้จากสีขาวก็จะกลายเป็นสีออกเทาๆ
style ลักษณะผลลัพธ์ แบบที่เราใช้ก็เป็นแบบธรรมดา ถ้าเติม _INV ไปก็จะ invert สีผลลัพธ์ให้ตรงกันข้าม ลองไปเล่นกันดูมีทั้งหมด 5 แบบ ตามด้านล้างเลย
cv2.THRESHOLD_BINARY

cv2.THRESHOLD_BINARY_INV 

cv2.THRESHOLD_TRUNC

cv2.THRESHOLD_TOZERO

cv2.THRESHOLD_TOZERO_INV

บทความนี้ก็จบเพียงเท่านี้ คราวหน้าเราจะมาคุยกันเรื่อง Adaptive Thresholding นะครับ

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


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



รับพัฒนาโปรแกรมทางด้าน Image Processing, Computer Vision และ Machine Learning สามารถติดต่อ สอบถาม และปรึกษาได้ฟรีครับ

Written by Supakit Kriangkhajorn

© 2019, Built with