วิธีคร็อปรูปขั้นเทพ(?) ด้วยคณิตศาสตร์

วิธีคร็อปรูปขั้นเทพ(?) ด้วยคณิตศาสตร์

ใครเคยประสบปัญหาคร็อปรูปยังไงก็ไม่สวยไหมฮะ

เมื่อตอนกลางปีที่แล้ว ผมมีโอกาสได้ไปเที่ยวเขาฮาคุซังที่ญี่ปุ่น แล้วบังเอิญเห็นคนเล่นพาราไกลดิ้งอยู่เลยถ่ายเก็บเอาไว้ ผมเลือกถ่ายเป็นแนวนอนเพื่อที่จะให้รูปออกมาเห็นครบทั้ง 4 คน

แต่พอผมจะเอาไปลงสตอรี่ instagram มันดันต้องลงเป็นแนวตั้งนี่สิ ผมต้องทำยังไงดี

ผมมีอยู่ 3 ทางเลือก

หนึ่ง ง่ายที่สุด คือไม่ต้องทำอะไร ลงไปทั้งแนวนอนนั่นแหละ ซึ่งไม่ค่อยสวยเลยเพราะภาพมันจะเล็ก และสตอรี่มันจะมีที่ว่างสีดำ ๆ ด้วย

สอง บีบรูป วิธีนี้แย่มาก เพราะอัตราส่วนของรูปจะผิดไปหมดเลย

และสาม คือคร็อปรูป มือถือส่วนมากสามารถคร็อปรูปได้เลยด้วยแอปดูรูปทั่ว ๆ ไป ปัญหาคือคุณจะเก็บองค์ประกอบของภาพได้ไม่ครบ พาราไกลเดอร์ที่ควรจะมี 4 คนในรูปถูกคร็อปออกไปจนเหลือแค่ 3 คนเอง

คำถามคือ เป็นไปได้ไหมที่ผมจะคร็อปรูป แล้วพาราไกลเดอร์ทั้งสี่คนยังอยู่ในรูปครบถ้วน

ซึ่งคำตอบคือได้ฮะ แค่ต้องไม่ใช่การคร็อปรูปแบบทั่วไป แต่เป็นการคร็อปรูปด้วยอัลกอริทึมที่ชื่อ Seam carving ซึ่งต้องอาศัยเทคนิคทางคณิตศาสตร์นิดหน่อยฮะ

ก่อนจะไปดูวิธีการทำงานของมัน ผมขอเอาผลลัพท์มาให้ดูก่อน ข้างล่างนี้คือรูปต้นฉบับและรูปที่ได้หลังคร็อปด้วย Seam carving ซึ่งจะเห็นว่าองค์ประกอบต่าง ๆ ในรูปยังอยู่ครบและไม่โดนบีบด้วย

คราวนี้มาดูวิธีการทำงานของ Seam carving กัน

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

เช่นถ้าเราพิจารณาพิกเซลที่ (x,y) และพิกเซลรอบ ๆ มัน ดังรูปข้างล่าง โดยเลขในแต่ละช่องนั้นแทนความเข้มของในพิกเซลนั้น ๆ

เราเริ่มคำนวณความแตกต่างไปข้างหน้า (fd) ด้วยการหาความต่างระหว่างความเข้มของช่องที่เราสนใจกับช่องทางขวา และคำนวณความแตกต่างไปข้างหน้า (bd) ด้วยการหาความต่างระหว่างความเข้มของช่องที่เราสนใจกับช่องทางซ้าย จากนั้นก็เอาทั้งสองค่ามาบวกกันและถอดรูท ก็จะได้เป็นค่าความแตกต่างของความเข้มสีที่พิกเซลนั้น ๆ ออกมา

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

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

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

ทำแบบซ้ำไปเรื่อย ๆ จนได้รูปขนาดที่ต้องการ สังเกตว่าแนวเส้นที่มันตัดทิ้งไปนั้นจะไม่โดนคนเล่นพาราไกลดิ้งเลย เนื่องจากมันมองว่าเป็นองค์ประกอบสำคัญ

สวยเลยใช่ไหมครับ

และนอกจากจะเอาไว้ใช้คร็อปรูปแล้ว คุณยังสามารถเอามันมาใช้ลบบางอย่างที่ไม่ต้องการออกจากรูปได้ ด้วยการป้ายสีลงไปในจุดที่ต้องการลบ เพื่อบังคับค่าความต่างสีในบริเวณที่อยากจะลบต่ำกว่าที่อื่น เท่านี้ Seam carving ก็จะให้ความสำคัญและพยายามลบกับบริเวณนั้นก่อนบริเวณอื่นนั่นเอง

อย่างในรูปด้านล่างนี้ สีแดงที่ถูกวาดด้วยเมาส์จะเป็นตัวบอกว่าบริเวณไหนที่ถูกลดค่าความต่างสี Seam carving เลยพยายามลบบริเวณนั้นก่อนที่จะลดขนาดรูปบริเวณอื่นต่อ

ซึ่งพออ่านมาถึงตรงนี้ คุณอาจจะกำลังคิดว่า โห Seam carving เจ๋งขนาดนี้ มันคงต้องถูกใช้ในโปรแกรมแต่งรูปมากมายแน่นอน

แต่นั่นเป็นความคิดที่ผิดฮะ

เพราะ Seam carving นั้นมีจุดอ่อนที่สำคัญมาก นั่นคือมันไม่รู้ว่าตรงไหนกันแน่ที่สำคัญจริง ๆ ในภาพ ลองกลับขึ้นไปดูรูปพาราไกลเดอร์ของผมดูดี ๆ จะเห็นว่าหน้าตาของภูเขาในรูปที่ตัดแล้วนั้นแตกต่างจากรูปต้นฉบับพอสมควร

ยิ่งถ้ามันเจอกับรูปที่ซับซ้อนพอ ๆ กันทั้งองค์ประกอบสำคัญและฉากหลัง มันจะไม่รู้ว่าองค์ประกอบไหนในรูปที่สำคัญจริง ๆ เพราะสำหรับมันทุกอย่างจะดูต่างกันไปหมด

อย่างเช่นรูปข้างล่างนี้

เราซึ่งเป็นมนุษย์รู้ว่าจุดที่สำคัญในรูปนั้นคือคน ส่วนจุดที่ควรตัดออกไปนั้นคือฉากหลังที่เป็นต้นไม้ แต่เนื่องคุณผู้หญิงคนซ้ายดันใส่ชุดสีดำไปหมด ทำให้ Seam carving คิดว่าจุดนั้นไม่สำคัญและเลือกที่จะคร็อปทิ้งออกไป จนทำให้ได้รูปออกมาเป็นแบบนี้

คือเก็บต้นไม้ที่ดูซับซ้อนไว้ แต่ไปตัดเสื้อกับผมซึ่งควรจะเก็บเอาไว้แทน

นั่นจึงเป็นสาเหตุที่เราไม่ค่อยเห็น Seam carving ถูกนำมาใช้จริงในแอปแต่งรูปต่าง ๆ มากนัก เพราะถึงแม้มันจะเป็นอัลกอริทึมที่ฉลาดและน่าทึ่ง แต่ข้อจำกัดเรื่องการแยกแยะว่าส่วนไหนในภาพสำคัญจริง ๆ ก็ยังทำให้มันมีข้อจำกัดในหลายสถานการณ์ ยิ่งทุกวันนี้มี AI เข้ามาช่วยมากขึ้น ไม่ว่าจะเป็นโมเดลรู้จำใบหน้า วัตถุ หรือเทคนิคเติมภาพอัตโนมัติ ก็ยิ่งทำให้วิธีแบบใหม่ ๆ ที่แม่นยำและยืดหยุ่นถูกใช้มากกว่า

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

ถ้าใครอยากไปลองเล่นดูเอง มีคนใจดีเขียนโปรแกรม Seam carving แบบพื้นฐานไว้ให้ใช้ฟรีด้วยนะฮะ ไปลองเล่นดูกันได้ว่ามันเวิร์คหรือไม่เวิร์คกับรูปแบบไหนบ้าง

JS IMAGE CARVER
Content-aware image resizer based on Seam Carving algorithm

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


เอกสารอ้างอิง