ใน OpenCV มีฟังก์ชันการทำ smoothing image มาให้ ตอนแรกไม่เคยคิดมาก่อนว่า smoothing = blurring การทำ smoothing ใน OpenCV ใช้คำสั่ง
void cvSmooth(
const CvArr* src,
CvArr* dst,
int smoothtype =CV_GAUSSIAN,
int param1=3,
int param2=0,
int param3=0,
int param4=0
);
โดยรวมแล้วคือการเฉลี่ยค่าของ pixel (จริงๆ คือค่าใช้ CvArr นั้นๆ แต่ต่อไปนี้ถือว่าเราประมวลกับภาพ จึงขอเรียก pixel เพื่อความสะดวก) นั้นๆ ด้วย pixel ที่อยู่รอบข้าง
ตัวแปร smoothtype มีค่าคือ CV_BLUR, CV_BLUR_NO_SCALE, CV_MEDIAN, CV_GAUSSIAN, CV_BILATERAL
CV_BLUR คือการทำเฉลี่ยค่า pixel ด้วยค่า pixel รอบๆ ข้าง โดยขนาด pixel รอบข้างกำหนดไว้ใน param1, param2
CV_BLUR_NO_SCALE คือผลรวมค่า pixel ด้วยค่า pixel รอบๆ ข้าง(แบบเดียวกับ CV_BLUR) ผลลัพธ์ที่ได้จะเร็วกว่า CV_BLUR (เพราะใช้ผลรวมในขณะที่ CV_BLUR ต้องหารด้วย param1*param2 อีกที) ข้อควรระวังคือ dst จะต้องมี bit depth ที่มากกว่า src ไม่งั้นจะเกิดการ overflow ได้
CV_MEDIAN เหมือน CV_BLUR แต่ใช้ค่ามัธยฐานแทนค่าเฉลี่ยเลขคณิต ด้วยคุณสมบัติของมัธยฐานที่ส่วนใหญ่ไม่มีผลกระทบต่อข้อมูลที่โดดในกลุ่ม ดังนั้นการใช้วิธีนี้จะทนต่อ noisy image ได้ดีกว่าแบบ CV_BLUR ทั้งสองแบบ
CV_GAUSSIAN คือการใช้ค่าเฉลี่่ยแบบ GAUSSIAN โดยค่า pixel แต่ละ pixel จะถูกถ่วงน้ำหนักด้วยด้วยค่าที่แปรผกผันกับระยะห่างจาก pixel ที่ต้องการ ยิ่งไกลมากผลของ pixel นั้นก็จะน้อย param1, param2 แสดงถึงขนาดของ filter window param3,param4 คือค่า σ ในแนวนอนและแนวตั้ง Gaussian distribution ตามลำดับ
ใน OpenCV มีการ optimize โคดเป็นพิเศษสำหรับ gaussian kernel ขนาด 3x3, 5x5, 7x7 โดยตั้งค่า param3=0
แต่จุดอ่อนของ GAUSSIAN smooth คือ gaussian assume ว่า noise จะเกิดกระจายได้ทั่วๆไม่ได้กระจุกที่ใดที่หนึ่งเป็นพิเศษ และค่าของ pixel จะมีความกระจายแบบต่อเนื่่อง(เข้าใจว่าเป็นผลมาจากการ assumption ว่าเป็นกระจายแบบ gaussian) ซึ่งในส่วน edge ของภาพ pixel จะกระจายไม่ต่อเนื่องกับ pixel ข้างเคียง(ก็เป็นขอบนี่มันก็ต้องตัดกันสิ) ผลที่ได้คือ Gaussian จะ smooth ส่วน edge ทิ้งไป
CV_BILATERAL โดยหลักการของ bilateral filtering นั้นจะคำนวณ pixel โดยถ่วงน้ำหนักจากทั้ง space (ระยะห่าง ยิ่งห่างมากยิ่งมีน้ำหนักน้อย) และ range(ความแตกต่างของสียิ่งแตกต่างมากยิ่งมีน้ำหนักน้อย) ใน OpenCV การถ่วงน้ำหนักที่ใช้ จะใช้ Guassian distribution ทั้ง space และ range(จริงๆ ใช้ distribution อื่นก็ได้) การ smooth แบบนี้จะรักษา edge ของภาพไว้ได้ดีกว่าแบบ CV_GAUSSIAN param1 จะเป็นค่า σ สำหรับ spatial domain, param2 จะเป็นค่า σ สำหรับ color domain
ค่า σ ใน gaussian distribution จะหมายถึงค่า standard deviation ของการกระจ่ายการตั้งค่า σ ให้มากจะเป็นเพิ่มน้ำหนักให้กับ pixel (เพราะในความเป็นจริงตามสูตร ระยะห่างทั้ง space และ color จะคิดเป็นจำนวนเท่าของ σ)
Wednesday, April 14, 2010
Learning OpenCV: Smoothing image in OpenCV
Labels:
Bilateral filtering,
Gaussian,
Learning OpenCV,
smoothing
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment