5.13. ฟิลเตอร์เชิงเส้นและบริเวณใกล้เคียง

การดำเนินการทางคณิตศาสตร์พิกเซลในส่วนก่อนหน้าของบทนี้รวมภาพสองภาพเข้าด้วยกันทีละจุด ฟิลเตอร์ ทำงานที่เกี่ยวข้องในรูปแบบที่แตกต่างกัน: คำนวณค่าของทุกพิกเซลเอาต์พุตจาก บริเวณใกล้เคียง ขนาดเล็กของพิกเซลนำเข้าที่ล้อมรอบตำแหน่งที่สอดคล้องกัน เอาต์พุตที่ (x, y) คือสถิติบางอย่าง -- ค่าเฉลี่ย ค่ามัธยฐาน หรือค่าที่พบบ่อยที่สุด -- ของพิกเซลนำเข้าในกล่องเล็กที่มีจุดศูนย์กลางอยู่ที่ (x, y)

การเปลี่ยนกรอบความคิดเล็กน้อยนั้น -- การย้ายจากทีละพิกเซลมาเป็นทีละหน้าต่างพิกเซล -- คือสิ่งที่ทำให้กลุ่มการดำเนินการที่มีประโยชน์ทั้งหมดทำงานได้ ค่าเฉลี่ยธรรมดาในหน้าต่างเล็กจะปรับสัญญาณรบกวนของ sensor ให้เรียบขึ้น ค่ามัธยฐานในหน้าต่างเดียวกันจะกำจัดสัญญาณรบกวนแบบจุดเดี่ยวโดยไม่ทำให้ขอบอ่อนลงมากนัก ค่าเฉลี่ยทวิภาคปฏิเสธที่จะทำให้เรียบข้ามขอบเขตคอนทราสต์ที่แข็งแกร่ง โดยรักษาขอบของวัตถุในขณะที่ทำความสะอาดพื้นผิวภายใน บริเวณใกล้เคียงคือหน่วยของงาน ส่วนการเลือกสถิติจะกำหนดว่าฟิลเตอร์ทำอะไร

5.13.1. ขนาดเคอร์เนล

ฟิลเตอร์บริเวณใกล้เคียงทุกตัวรับพารามิเตอร์ size ที่กำหนด รัศมี ของหน้าต่างเป็นพิกเซล หน้าต่างเองเป็นรูปสี่เหลี่ยมและครอบคลุม (2 * size + 1) พิกเซลในแต่ละด้าน -- ดังนั้น size=1 หมายถึงบริเวณใกล้เคียง 3x3, size=2 หมายถึง 5x5, size=3 หมายถึง 7x7 และต่อไปเรื่อยๆ

A small image grid with a highlighted 3-by-3 sub-grid representing the filter's neighbourhood. An arrow shows the neighbourhood sliding one pixel to the right. A second arrow shows it sliding down to the next row at the end of the row. The output pixel for each position is drawn under the neighbourhood, with a small note saying that the output is some statistic of the input neighbourhood.

บริเวณใกล้เคียงเลื่อนผ่านภาพทีละพิกเซล จากซ้ายบนไปขวาล่าง พิกเซลเอาต์พุตแต่ละตัวคือผลลัพธ์ของการใช้สถิติของฟิลเตอร์กับบริเวณใกล้เคียงของนำเข้าที่มีจุดศูนย์กลางอยู่ที่ตำแหน่งนั้น

ขนาดที่ใหญ่ขึ้นหมายถึงบริเวณใกล้เคียงที่ใหญ่ขึ้น ซึ่งหมายถึงการกรองที่เรียบกว่า (หรือรุนแรงกว่า) ต้นทุนเพิ่มขึ้นตามพื้นที่ของหน้าต่าง ดังนั้นฟิลเตอร์ size=3 จึงทำงานประมาณเก้าเท่าต่อพิกเซลเทียบกับฟิลเตอร์ size=1 ค่าเริ่มต้นในทางปฏิบัติสำหรับงานทำความสะอาดส่วนใหญ่คือ size=1 หรือ size=2; ใช้ขนาดที่ใหญ่กว่าเฉพาะเมื่อบริเวณใกล้เคียงขนาดเล็กไม่เพียงพอในการระงับลักษณะที่แอปพลิเคชันต้องการระงับ

5.13.2. ฟิลเตอร์ค่าเฉลี่ย

mean() แทนที่แต่ละพิกเซลด้วย ค่าเฉลี่ยเลขคณิต ของบริเวณใกล้เคียง ผลลัพธ์จะปรับความผันแปรระหว่างพิกเซลให้เรียบตามขนาดของหน้าต่าง ซึ่งทำให้เป็นวิธีที่ถูกที่สุดในการระงับสัญญาณรบกวนของ sensor: ความผันแปรความถี่สูงจะถูกหักล้าง เนื้อหาความถี่ต่ำยังคงอยู่

การแลกเปลี่ยนคือขอบและลักษณะเด่นที่คมชัดอื่นๆ ก็จะถูกหักล้างด้วย ขอบที่สว่างซึ่งกว้างหนึ่งพิกเซลก่อนฟิลเตอร์จะกว้างสองหรือสามพิกเซลหลังจากฟิลเตอร์ค่าเฉลี่ย size=1 โดยความสว่างลดลงที่ไหล่ สำหรับการลดสัญญาณรบกวนบนภาพที่มีพื้นผิวน้อย (ผนังสะอาด ด้านในของมาร์กเกอร์สี) การแลกเปลี่ยนนั้นใช้ได้ สำหรับฉากที่มีความซับซ้อนซึ่งขอบมีความสำคัญ ฟิลเตอร์ตัวใดตัวหนึ่งต่อไปนี้มักจะเหมาะสมกว่า

img.mean(1)        # 3x3 box average -- fast, gentle smoothing
img.mean(2)        # 5x5 box average -- stronger, slower

5.13.3. ค่ามัธยฐาน โหมด และจุดกึ่งกลาง

ฟิลเตอร์บริเวณใกล้เคียงทางสถิติอีกสามตัวแลกเปลี่ยนค่าเฉลี่ยเลขคณิตธรรมดาด้วยสิ่งที่มีความทนทานต่อค่าผิดปกติมากขึ้น

median() ส่งคืน ค่ามัธยฐาน ของบริเวณใกล้เคียง -- ค่าที่อยู่ตรงกลางของรายการพิกเซลหน้าต่างที่เรียงลำดับแล้ว พิกเซลที่สว่างมากหรือมืดมากในหน้าต่างจะไม่ดึงค่ามัธยฐาน แต่เพียงกลายเป็นหนึ่งในค่าสุดโต่งที่ถูกทิ้ง ผลในทางปฏิบัติคือการกรองค่ามัธยฐานจะกำจัดสัญญาณรบกวนแบบจุดเดี่ยวและ salt-and-pepper โดยไม่ทำให้ขอบอ่อนลงเหมือนที่ mean ทำ ต้นทุนคือการคำนวณต่อพิกเซลมากขึ้น -- การจัดเรียงหน้าต่างช้ากว่าการหาค่าเฉลี่ย -- และผลลัพธ์ไม่ใช่ค่าเฉลี่ยอย่างเคร่งครัด ซึ่งบางครั้งมีความสำคัญสำหรับคณิตศาสตร์ปลายน้ำ

พารามิเตอร์ percentile (ค่าเริ่มต้น 0.5) เลื่อนค่าที่เลือกออกจากค่ามัธยฐานอย่างเคร่งครัด percentile=0.0 ส่งคืนค่าต่ำสุดของบริเวณใกล้เคียง, percentile=1.0 คือค่าสูงสุด; ค่ากลางเลือกตามสัดส่วนระหว่างทั้งสองในหน้าต่างที่เรียงลำดับแล้ว ทำให้ median สามารถเน้นส่วนที่มืดหรือสว่างของบริเวณใกล้เคียงได้โดยไม่สูญเสียความทนทานต่อค่าผิดปกติของสถิติลำดับ

mode() ส่งคืนค่า ที่พบบ่อยที่สุด ในบริเวณใกล้เคียง มีประโยชน์เมื่อโมเดลสัญญาณรบกวนคือ "พิกเซลส่วนใหญ่ถูกต้อง มีบางส่วนถูกทำให้เสียหายในระดับต่างๆ" ซึ่งคำตอบที่ถูกต้องคือค่าที่ปรากฏบ่อยที่สุด -- ซึ่งค่ามัธยฐานอาจพลาดเมื่อค่าที่เสียหายสะสมอยู่ด้านเดียวของหน้าต่างที่เรียงลำดับ

midpoint() ส่งคืน การรวมกันแบบถ่วงน้ำหนักของค่าต่ำสุดและค่าสูงสุด ของบริเวณใกล้เคียง -- bias=0.5 ให้จุดกึ่งกลางระหว่างทั้งสอง, bias=0.0 ให้ค่าต่ำสุด, bias=1.0 ให้ค่าสูงสุด ใช้น้อยกว่าตัวอื่นแต่ควรรู้จักเมื่อเป้าหมายคือการดึงลักษณะเด่นที่มืดหรือสว่างโดยเฉพาะ

5.13.4. แบบทวิภาค เวอร์ชันที่รักษาขอบ

bilateral() คือฟิลเตอร์บริเวณใกล้เคียงที่ควรทำความเข้าใจให้ดีที่สุด มันผลิตเอฟเฟกต์การทำให้เรียบของ mean() แต่มีข้อจำกัดเพิ่มเติม: ยิ่งพิกเซลบริเวณใกล้เคียง แตกต่าง จากพิกเซลกลางมากเท่าใด มันก็นับในค่าเฉลี่ยน้อยลงเท่านั้น ผลลัพธ์จะทำให้ภายในของทุกบริเวณที่สม่ำเสมอเรียบขึ้นโดยไม่รั่วซึมข้ามขอบที่แยกมัน ซึ่งเป็นสิ่งที่แอปพลิเคชันส่วนใหญ่ต้องการจริงๆ

พารามิเตอร์สองตัวควบคุมว่าฟิลเตอร์ลดค่าน้ำหนักพิกเซลอย่างรุนแรงแค่ไหน:

  • color_sigma กำหนดว่า ความแตกต่างของสี ส่งผลต่อการถ่วงน้ำหนักอย่างไร ค่าที่เล็กกว่าหมายความว่าฟิลเตอร์เข้มงวดมากขึ้นในการลดน้ำหนักพิกเซลที่แตกต่างจากจุดศูนย์กลาง

  • space_sigma กำหนดว่า ระยะห่างเชิงพื้นที่ ส่งผลต่อการถ่วงน้ำหนักอย่างไร ค่าที่เล็กกว่าให้น้ำหนักมากขึ้นกับพิกเซลที่ใกล้กับจุดศูนย์กลาง

ค่าเริ่มต้น (color_sigma=0.1, space_sigma=1.0) เป็นจุดเริ่มต้นที่สมเหตุสมผล การปรับแต่งมักเป็นเรื่องของการรันฟิลเตอร์บนเฟรมตัวอย่างและปรับจนกว่าขอบคมชัดและภายในสะอาด

แบบทวิภาคมีราคาแพงกว่า median() และแพงกว่า mean() อย่างมีนัยสำคัญ ดังนั้นควรใช้ เฉพาะ เมื่อพฤติกรรมการรักษาขอบเป็นสิ่งที่แอปพลิเคชันต้องการ

5.13.5. การกำหนดค่าขีดแบ่งแบบปรับตัว

ฟิลเตอร์ค่าเฉลี่ย ค่ามัธยฐาน โหมด และจุดกึ่งกลางทั้งหมดมีคู่ของอาร์กิวเมนต์คำสำคัญเดียวกันที่เปลี่ยนเอาต์พุตให้เป็นค่าขีดแบ่งแบบไบนารี:

  • threshold=True เปลี่ยนฟิลเตอร์เป็นโหมดการกำหนดค่าขีดแบ่ง

  • offset=N เลื่อนค่าตัดเฉพาะที่ด้วย N หน่วยก่อนการเปรียบเทียบ

กลไกนี้สร้างขึ้นจากพฤติกรรมปกติของฟิลเตอร์โดยตรง หากไม่มี threshold=True ฟิลเตอร์จะคำนวณสถิติของมันเหนือบริเวณใกล้เคียงและเขียนสถิตินั้นลงในพิกเซลเอาต์พุต เมื่อมี threshold=True ฟิลเตอร์จะคำนวณสถิติเดียวกัน จากนั้นเปรียบเทียบพิกเซล ต้นทาง ที่ตำแหน่งเดียวกันกับสถิติบวกออฟเซ็ต และเขียนค่าสูงสุดของรูปแบบถ้าต้นทางมากกว่า มิฉะนั้นเป็นศูนย์

ผลลัพธ์คือภาพไบนารีซึ่งค่าตัด เคลื่อนที่ตามความสว่างในท้องถิ่น ทั่วเฟรม บริเวณที่สว่างจะได้ค่าตัดสูง บริเวณที่มืดจะได้ค่าตัดต่ำ และพิกเซลพื้นหน้าที่สว่างกว่าเพื่อนบ้านในท้องถิ่นจะตรงกันไม่ว่าจะอยู่ในบริเวณที่สว่างหรือมืด -- ซึ่งเป็นพฤติกรรมที่ค่าขีดแบ่งส่วนกลางเดียวไม่สามารถผลิตได้บนภาพที่มีแสงสว่างไม่สม่ำเสมอ

img.mean(3, threshold=True, offset=5)

พารามิเตอร์ offset คือที่ที่แอปพลิเคชันควบคุมว่า การทดสอบเข้มงวด แค่ไหน ออฟเซ็ตบวกเล็กน้อยต้องการให้พิกเซลต้นทางสว่างกว่าเพื่อนบ้านอย่างมีนัยสำคัญก่อนนับเป็นการจับคู่ ซึ่งระงับสัญญาณรบกวน sensor แบบ false positive โดยแลกกับการหลุดพื้นหน้าที่จาง ออฟเซ็ตลบเล็กน้อยจับพื้นหน้าที่จางโดยแลกกับการให้สัญญาณรบกวนบางส่วนผ่าน การเลือกขึ้นอยู่กับสิ่งที่ส่วนที่เหลือของไปป์ไลน์จะทำกับเอาต์พุตไบนารี

Three image panels in a row. The first is an input grayscale frame with a brightness gradient and foreground marks scattered across at uniform darkness. The second panel shows a global threshold applied to it: the foreground is correctly classified on the bright side, but the entire dark side reads as foreground because page and foreground both fall below the cutoff. The third panel shows an adaptive threshold applied to the same input: the foreground is correctly classified across the whole frame.

ภายใต้แสงสว่างที่ไม่สม่ำเสมอ ค่าขีดแบ่งส่วนกลางเดียวไม่สามารถอธิบายพื้นหน้าในทุกตำแหน่ง ฟิลเตอร์บริเวณใกล้เคียงที่รันด้วย threshold=True ผลิตค่าตัดที่เคลื่อนที่ตามความสว่างในท้องถิ่นและจำแนกพื้นหน้าอย่างถูกต้องตลอดทั้งเฟรม

ตระกูลฟิลเตอร์รันค่าขีดแบ่งแบบปรับตัว ดังนั้นการเลือกฟิลเตอร์ ที่ถูกต้อง มีความสำคัญ: mean() สำหรับค่าขีดแบ่งแบบปรับตัวที่ถูกที่สุด, median() เมื่อนำเข้ามีสัญญาณรบกวน salt-and-pepper ที่ฟิลเตอร์ควรปฏิเสธก่อนคำนวณค่าตัดในท้องถิ่น