- อธิบายหลักการของการ จำลองระดับความสว่างหลายระดับด้วยอาร์เรย์พิกเซลขาวดำในเชิงภาพ
- Dithering คือเทคนิคที่ใช้ สร้างภาพลวงตาให้ดูเหมือนมีสีหรือระดับความสว่างมากกว่าที่มีจริง
- ในวิธี Ordered dithering จะใช้ threshold map เพื่อกำหนดว่าพิกเซลแต่ละจุดจะเป็นขาวหรือดำโดยอิงจากค่าความสว่าง
- ในกระบวนการนี้ การเปลี่ยนแปลงของความหนาแน่นพิกเซล จะสร้างความรู้สึกเหมือนภาพระดับเทา พร้อมคงรูปทรงของภาพต้นฉบับไว้
- บทความนี้เป็นตอนแรกของซีรีส์ 3 ตอนที่ว่าด้วยแนวคิดพื้นฐานของ dithering โดยตอนถัดไปจะพูดถึง อัลกอริทึมการสร้าง threshold map และ error diffusion
แนวคิดและหลักการของ dithering
- Dithering เป็นเทคนิคเชิงภาพสำหรับ แสดงเฉดสีได้มากขึ้นด้วยจำนวนสีที่จำกัด
- จัดเรียงพิกเซลขาวดำเป็นแพตเทิร์นเฉพาะเพื่อสร้าง ภาพลวงตาของระดับสีเทาหลายขั้น
- เพิ่ม ความหลากหลายทางการมองเห็น โดยไม่ต้องเพิ่มจำนวนสีจริง
- ในบทความนี้ใช้ ภาพระดับสีเทา เป็นตัวอย่าง
- บนหน้าจอที่แสดงได้เพียงขาวดำ แต่ละพิกเซลจะถูกแปลงเป็น สีที่ใกล้ที่สุด (ดำหรือขาว)
- หากแปลงแบบตรงไปตรงมา ขอบของแสงเงาจะหยาบและรายละเอียดของเงาบางส่วนจะหายไป
- Dithering ช่วยให้เกิดการไล่ระดับแสงเงาที่นุ่มนวลขึ้นด้วยการ เปลี่ยนพิกเซลบางส่วนให้เป็นสีตรงข้ามอย่างตั้งใจ
- บริเวณมืดจะเพิ่มความหนาแน่นของพิกเซลสีดำ และบริเวณสว่างจะเพิ่มความหนาแน่นของพิกเซลสีขาว
- ผลลัพธ์คือ ความต่างของความหนาแน่นพิกเซล ที่ก่อให้เกิดภาพลวงตาของระดับสีเทา
Ordered Dithering และ threshold map
- Ordered dithering เป็นวิธี dithering แบบง่ายที่ใช้ threshold map
- threshold map คือกริดของ ค่าความสว่าง ตั้งแต่ 0 (มืดที่สุด) ถึง 1 (สว่างที่สุด)
- นำค่าความสว่างของพิกเซลอินพุตแต่ละจุดไปเทียบกับ threshold ของตำแหน่งนั้น
- ถ้าความสว่างมากกว่า threshold ให้เป็นสีขาว ถ้าน้อยกว่าให้เป็นสีดำ
- ทำซ้ำกระบวนการนี้กับทุกพิกเซลเพื่อสร้าง ภาพแพตเทิร์นขาวดำ
- threshold map ถูกออกแบบให้สร้าง แพตเทิร์นความหนาแน่นขาวดำที่เหมาะสม ตามการกระจายความสว่างของภาพอินพุต
- พื้นที่สว่างจะมีสัดส่วนสีขาวมากกว่า และพื้นที่มืดจะมีสัดส่วนสีดำมากกว่า
- ความต่างของความหนาแน่นนี้ทำให้เกิด เอฟเฟกต์ที่เมื่อมองจากไกลแล้วดูเหมือนภาพระดับสีเทา
การประมวลผลภาพขนาดใหญ่และเอฟเฟกต์ทางสายตา
- เมื่อต้องทำ dithering กับภาพขนาดใหญ่ จะต้อง ขยาย threshold map ให้พอดีกับขนาดภาพทั้งหมด
- ใช้หลักการเดิมคือเปรียบเทียบความสว่างของแต่ละพิกเซลกับ threshold แล้วแปลงเป็นขาวดำ
- ผลลัพธ์คือภาพที่ ใช้เพียงสองสีเท่านั้น แต่ยังคงโครงสร้างแสงเงาของภาพต้นฉบับไว้
- แม้จำนวนสีจะลดลง แต่ยัง คงรายละเอียดทางภาพไว้ผ่านการเปลี่ยนแปลงของความหนาแน่นพิกเซล
ความหมายของ dithering และโครงสร้างของซีรีส์
- Dithering เป็นเทคนิคที่ ไม่ได้เพิ่มสี แต่ลดสีลงแล้วสร้างความหลากหลายทางการมองเห็นแทน
- ผู้เขียนอธิบายสิ่งนี้ว่าเป็น “กระบวนการใช้สิ่งที่มีอยู่ให้เกิดประโยชน์สูงสุด”
- บทความนี้เป็นตอนแรกจากทั้งหมด 3 ตอน โดยเน้นที่ หลักการพื้นฐานและความเข้าใจเชิงภาพ
- บทความถัดไปจะกล่าวถึง อัลกอริทึมการสร้าง threshold map และบทสุดท้ายจะกล่าวถึง error diffusion
- ซีรีส์นี้มีแผนจะสำรวจ แนวทางเชิงอัลกอริทึมที่หลากหลายของ dithering และความแตกต่างของผลลัพธ์ทางสายตา
แนะนำผู้เขียนและโปรเจกต์
- visualrambling.space เป็นโปรเจกต์ส่วนตัวที่ Damar ดูแล
- สร้าง คอนเทนต์อินเทอร์แอกทีฟที่ใช้สำรวจและอธิบายหัวข้อต่าง ๆ ในเชิงภาพ
- หัวข้อที่นำเสนอมีทั้ง Three.js, WebGL, dithering, visualization, interactive learning เป็นต้น
- Damar มีแผนจะแชร์ บทความเชิงภาพใหม่ ๆ อย่างต่อเนื่องผ่านบัญชี X/Twitter (@damarberlari)
2 ความคิดเห็น
ความคิดเห็นจาก Hacker News
นี่คือเทคนิค halftone ต่างหาก หมายถึงวิธีทำให้ดูเหมือนว่ามีสีมากกว่าจำนวนจริงในพาเลต แต่สำหรับผมมันไม่ใช่ dithering
ผมคิดว่า dithering คือเทคนิคสำหรับกำจัด banding ที่เกิดจากพาเลตมีขนาดไม่ใหญ่พอ
halftone ที่แสดงตรงนี้ขยายพาเลต 2 สีให้ดูเหมือนมีราว 20 สีได้ก็จริง แต่ banding ก็ยังเห็นชัดอยู่ดี
banding แบบนี้แก้ได้ด้วยการใช้สีให้มากกว่านี้มาก ๆ (เช่น grayscale 256 ระดับ หรือถ้าเป็น RGB ก็ 256³) หรือไม่ก็ใช้ dithering
คิดว่าเทคนิค error diffusion ที่เกริ่นไว้ท้ายสุดน่าจะเป็นสิ่งที่ผมกำลังพูดถึง
แก่นของ dithering คือ noise แต่เดโมนี้ไม่มี noise เลย ทุกอย่างเป็น deterministic ทั้งหมด
ถึงอย่างนั้นตัวพรีเซนเทชันเองก็ยอดเยี่ยมมาก
โดยทั่วไป noise เกิดขึ้นในกระบวนการ quantization และ dithering คือเทคนิคในการ จัดรูปแบบ noise นั้น
Bayer-matrix ordered dithering ที่ใช้ตรงนี้จะผลัก noise ไปกองในย่านความถี่สูง ทำให้สังเกตเห็นได้ยากขึ้น แต่ในย่านความถี่ต่ำก็ยังมี banding เหลืออยู่
อย่างที่ Dave Long บอก อัลกอริทึมเส้นของ Bresenham ก็อาจมองได้ว่าเป็น dithering แบบหนึ่ง เพียงแต่สัญญาณนั้นไม่ใช่ความสว่าง แต่เป็นตำแหน่งของปากกา
มีการคุยเรื่องนี้กันไปเมื่อไม่กี่วันก่อนด้วย — ดู เธรดนี้
บทความในวิกิพีเดีย
เมื่อก่อนเครื่องสีของ NeXT ใช้จอ 12 บิต (4 บิตต่อช่องสี) แต่ถ้าใช้ dithering ดี ๆ มันดูเหมือน 24 บิต true color ได้เลย
ขอแนะนำวิดีโอของ Daniel Shiffman จาก Coding Train สองคลิป
Turning Images into Dots: The Magic of Dithering
Coding Challenge 181: Weighted Voronoi Stippling
เป็นหัวข้อที่น่าสนใจ ภาพแอนิเมชันก็ดี และเห็นได้ชัดว่าทุ่มเทมาก
แต่ พรีเซนเทชันแบบอินเทอร์แอ็กทีฟ แบบนี้อ่านยากกว่าบล็อกโพสต์แบบดั้งเดิม
โครงสร้างของเนื้อหามองภาพรวมได้ไม่ชัด และต้องอ่านทีละประโยค ทำให้ไล่ดูเร็ว ๆ ได้ยาก
ให้ความรู้สึกเหมือน วิดีโออินเทอร์แอ็กทีฟ ที่ผู้ใช้ควบคุมความเร็วเองได้
ปกติผมก็ชอบข้อความมากกว่า แต่คิดว่ารูปแบบนี้ก็เป็นการดัดแปลงที่น่าสนใจ
ผมเคยใช้ ordered และ error diffusion dithering เป็นภาษาภาพในหลายโปรเจกต์งานออกแบบ
โดยเฉพาะงานสาย tech/computer/blockchain ทั้งในแบบภาพนิ่งและแอนิเมชัน
เทคโนโลยีเก่า ๆ แบบนี้มีทั้ง ความอบอุ่นและความชวนคิดถึง แบบแปลก ๆ เลยเหมาะจะเอาไปผสมกับไอเดียใหม่ ๆ
ตัวอย่างงานของผมอยู่ใน Instagram:
D.Y.O.R. / Printed / Titles / ทดลอง Dithering
ดูได้ที่ olsz.me
เมื่อก่อนผมเคยทำตัวสลับระหว่าง dithering สองแบบ
โปรเจกต์ GitHub
ผมอยากจะชอบสิ่งนี้มากจริง ๆ แต่การอ่านข้อความบน แพตเทิร์นที่เคลื่อนไหว มันยากเกินไป
วิธีการทำภาพออกมาสวย แต่ผมไม่เข้าใจส่วนของ threshold map
อธิบายไม่พอว่าแมปถูกสร้างขึ้นอย่างไร และกำหนด threshold ยังไง
ไม่แน่ใจว่าเป็นเพราะสำหรับผู้เขียนมันชัดเจนเกินไปเลยละไว้หรือเปล่า
หัวใจสำคัญคือการจำแนวคิดของ ‘threshold’ ให้ได้ พิกเซลสีเทาจะถูกเปลี่ยนเป็นขาวหรือดำตามค่า threshold
ตัวอย่างเช่น
dithered_color = (raw_color > threshold_color) ? white : blackจะใช้ threshold แบบสุ่มก็ได้ ถ้าค่าเฉลี่ยเป็น 0.5 ก็จะประมาณค่าสีเทาเดิมได้ค่อนข้างดี
สิ่งสำคัญคือเมื่อจำนวนพิกเซลขาวเพิ่มขึ้น ต้องทำให้มันไม่ไปติดกัน
สีเทา 50% อาจออกแบบเป็น ลายตารางหมากรุก ส่วน 25% ก็เป็นพิกเซลขาวเพียง 1 จุดในกริด 2x2 เป็นต้น
การทดลองแบบนี้ลองทำเองใน ShaderToy จะสนุกมาก
ตอนแรกนึกว่าใช้ ‘ภาพไบนารี’ เป็นอินพุต แต่พอหลัง ๆ กลายเป็นใช้พื้นที่สีเทาเป็นอินพุต
dithering ทำให้จอที่ไม่รองรับสี 10 บิตยังดูเหมือนเป็น 10 บิตได้ดีพอ
banding หายไป และ noise ช่วยกลบการขาดความลึกของสี
ดังนั้นมันยังเป็นเทคนิคที่มีประโยชน์ในยุคปัจจุบัน ไม่ใช่แค่สำหรับ งานศิลปะสไตล์เรโทร
ผู้คนยังนึกถึงแค่ palette dithering กันอยู่
8 บิตต่อช่องสีนั้นไม่พอ เพราะผลจาก gamma correction ทำให้ใช้งานจริงได้แค่ประมาณ 220 ระดับ
ผมดูแล Rust crate dithereens อยู่เพื่อแก้ปัญหาแบบนี้
แค่ดูกราเดียนต์ด้านบนของ README ก็เห็นทันทีว่าทำไมมันสำคัญ
ตอนลดภาพบิตสูงลงมาเป็น 10 บิตหรือ 8 บิต แค่ random dithering ก็ได้ผลดีพอแล้ว
Photoshop ใช้ dithering โดยอัตโนมัติเป็นค่าเริ่มต้นตอนแปลง 16 บิตเป็น 8 บิต
ซอฟต์แวร์อื่นไม่ทำแบบนั้น พอพิมพ์โปสเตอร์ขนาดใหญ่แล้วเกิด banding ขึ้นมา คุณจะรู้ทันที
มันเคยทำให้แผง TN แบบ 6 บิตดูเหมือน 8 บิต และตอนนี้ก็ใช้กับ HDR-10 ด้วย
วิธีนี้เป็นอัลกอริทึมง่าย ๆ ที่กะพริบพิกเซลอย่างรวดเร็วเพื่อผสมสี
บทความวิกิเรื่อง Frame rate control
รูปแบบการนำเสนอยอดเยี่ยมมาก และตั้งตารอตอนต่อไป
เมื่อก่อนผมเคยใช้ ordered dithering กับ ZX Spectrum Raytracer ซึ่งทำง่ายและผลลัพธ์ก็ดี
ลิงก์โปรเจกต์
คิดว่าในยุค 80 มันไม่ค่อยถูกใช้เพราะปัญหาด้านประสิทธิภาพ แต่จำได้ว่าเคยเห็นในพื้นหลังของ Windows 3.1 หรือ Monkey Island VGA ช่วงยุค 90
เดโมเจ๋งมาก แต่การเรียก dithering ว่าเป็น “ภาพลวงตา ของเฉดสีที่มากขึ้น” ดูไม่ค่อยแม่นนัก
ถ้าเอาภาพที่ dither แล้วไปผ่าน low-pass filter เฉดสีกลางเหล่านั้นมีอยู่จริง
คล้ายกับที่ แอมป์คลาส D ปล่อยสัญญาณแบบพัลส์ออกมา แต่หลังผ่านฟิลเตอร์แล้วจะกลายเป็นเสียงแอนะล็อกจริง ๆ
สุดท้ายแล้วการมองเห็นของเราและระยะห่างเองก็ทำหน้าที่เป็นฟิลเตอร์นั้น
ถ้ามองดี ๆ ก็รู้ได้ว่าสีจริงนั้นไม่ได้มีอยู่
เรารับรู้สีเทาจากพิกเซลขาวดำล้วน ๆ แต่ในขณะเดียวกันก็รู้ว่านั่นคือภาพลวงตา
เพราะงั้นผมคิดว่าคำว่า ‘illusion’ ก็ยังเหมาะอยู่
ตัดข้อความออกแล้วใช้แนวทางเป็นวิดีโอแบบอินเทอร์แอกทีฟที่บรรยายเฉพาะภาพในหอประชุม เป็นไอเท็มที่เท่มากจนเหมือนจะฉีกเวทีได้เลย ฉากที่นำภาพระดับสีเทามาแยกเป็นเลเยอร์แบบ 3D ให้ดูนั้น ผมคิดว่าเป็นคำอธิบายที่เป็นมิตรมาก