อัลกอริทึมสำหรับการทำโมเสคภาพ - มีวิธีที่เร็วกว่านี้หรือไม่?


9

ฉันเล่นกับการทำภาพโมเสค สคริปต์ของฉันใช้ภาพจำนวนมากปรับขนาดให้เป็นภาพขนาดย่อจากนั้นใช้เป็นภาพย่อยเพื่อประมาณภาพเป้าหมาย

จริงๆแล้ววิธีการนี้ค่อนข้างเป็นที่น่าพอใจ:

ฉันคำนวณข้อผิดพลาดกำลังสองเฉลี่ยสำหรับทุกหัวแม่มือในทุกตำแหน่งไทล์

ตอนแรกฉันเพิ่งใช้ตำแหน่งที่โลภ: วางนิ้วโป้งโดยมีข้อผิดพลาดน้อยที่สุดบนกระเบื้องที่เหมาะสมที่สุดแล้วต่อไปเรื่อย ๆ

ปัญหาเกี่ยวกับความโลภคือมันจะทำให้คุณวางนิ้วหัวแม่มือที่แตกต่างกันมากที่สุดบนกระเบื้องที่ได้รับความนิยมน้อยที่สุดในที่สุดไม่ว่าพวกเขาจะจับคู่กันอย่างใกล้ชิดหรือไม่ก็ตาม ฉันแสดงตัวอย่างที่นี่: http://williamedwardscoder.tumblr.com/post/84505278488/making-image-mosaics

ดังนั้นฉันจึงทำการสุ่มสลับจนกว่าสคริปต์จะถูกขัดจังหวะ ผลลัพธ์ค่อนข้างโอเค

การสลับแบบสุ่มของไพ่สองใบไม่ได้เป็นการปรับปรุงเสมอไป แต่บางครั้งการหมุนของไพ่สามใบขึ้นไปส่งผลให้เกิดการปรับปรุงระดับโลกเช่นA <-> Bอาจไม่ดีขึ้น แต่A -> B -> C -> A1อาจจะ ..

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

แต่มันต้องใช้เวลา .. มาก!

มีวิธีที่ดีกว่าและเร็วกว่านี้ไหม?


ปรับปรุงเงินรางวัล

ผมทดสอบจากการใช้งานที่หลากหลายและงูหลามผูกของวิธีฮังการี

ที่เร็วที่สุดคือ pure-Python https://github.com/xtof-durr/makeSimple/blob/master/Munkres/kuhnMunkres.py

ลางสังหรณ์ของฉันคือสิ่งนี้ใกล้เคียงกับคำตอบที่ดีที่สุด; เมื่อเรียกใช้บนภาพทดสอบห้องสมุดอื่น ๆ ทั้งหมดเห็นด้วยกับผลลัพธ์ แต่ kuhnMunkres.py นี้ในขณะที่เป็นคำสั่งที่มีขนาดเร็วขึ้นมากเพียงใกล้มากกับคะแนนที่การใช้งานอื่น ๆ ได้ตกลงไว้

ความเร็วขึ้นอยู่กับข้อมูล โมนาลิซ่าวิ่งผ่าน kuhnMunkres.py ในเวลา 13 นาที แต่ Scarlet Chested Parakeet ใช้เวลา 16 นาที

ผลลัพธ์นั้นเหมือนกับการสลับสุ่มและการหมุนแบบสุ่มสำหรับนกแก้ว:

ป้อนคำอธิบายรูปภาพที่นี่ป้อนคำอธิบายรูปภาพที่นี่

(kuhnMunkres.py ทางซ้ายสลับสุ่มทางขวาภาพต้นฉบับสำหรับการเปรียบเทียบ )

อย่างไรก็ตามสำหรับภาพ Mona Lisa ที่ฉันทดสอบด้วยผลลัพธ์ที่ได้รับการปรับปรุงให้ดีขึ้นอย่างเห็นได้ชัดและจริง ๆ แล้วเธอมี 'รอยยิ้ม' ที่กำหนดไว้ของเธอส่องผ่าน:

ป้อนคำอธิบายรูปภาพที่นี่ป้อนคำอธิบายรูปภาพที่นี่

(kuhnMunkres.py ทางซ้ายสลับสุ่มทางขวา)


1
ที่เกี่ยวข้อง ... ish เกี่ยวกับการแปลงเพดานปาก Codegolf มีปัญหาที่คล้ายกัน

1
และอีกชุดภาพที่เกี่ยวข้องคือallRGBที่แต่ละภาพ (แม้ว่าจะไม่ได้ให้คำแนะนำวิธีการทำมากเกินไป ... เพียงแค่มีพื้นที่อื่นที่ปัญหานี้เข้าหา)

1
ฉันพบปัญหานี้กับเครื่องทำโมเสกเมื่อไม่กี่ปีที่ผ่านมา เหตุผลของฉันในตอนนี้และตอนนี้ก็คือปัญหาไม่ได้เกิดขึ้นมากกับอัลกอริทึมของคุณ (ส่วน MSE) แต่มีขนาดที่ จำกัด ของจานสีภาพอินพุตของคุณ ฉันไม่ได้ทำงานกับภาพหลายพันล้านภาพฉันแกล้งมันด้วยการอนุญาตให้นำภาพกลับมาใช้ใหม่หลังจากผ่านไประยะหนึ่ง อย่างไรก็ตามหากคุณต้องการรักษาแนวทางของคุณไว้อาจเป็นการดีที่จะทำการส่งผ่านครั้งแรกสำหรับพอดี "ดี" จากนั้นปฏิบัติต่อส่วนที่เหลือของภาพเป็นแบบสุ่ม (หรือ Random-ish) - ด้วยชุดอินพุตแบบ จำกัด คุณมี ทางเลือกมากมาย
J Trana

@MichaelT ขอบคุณสำหรับลิงค์ที่ยอดเยี่ยม :) codegolf โดยเฉพาะอย่างยิ่งเป็นที่น่าสนใจ ผมพบว่าคะแนนที่ดีที่สุดของการแก้ปัญหาการใช้แลกเปลี่ยนสุ่ม (หมุนไม่สุ่ม) และมีการสันนิษฐานว่าทำงานมากในขณะที่ ...
Will

1
มาที่นี่หลังจากที่คุณได้เลือกคำตอบและได้รับรางวัล วิธีการที่แตกต่างกันคือการรักษาปัญหานี้เป็นปัญหาการจำลองการอบอ่อน คุณสามารถใช้ SA เป็นหนึ่งในขั้นตอนการแก้ปัญหาของคุณ
andy256

คำตอบ:


3

ใช่มีสองวิธีที่ดีกว่าและเร็วกว่า

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

จากนั้นคุณสามารถปรับค่าใช้จ่ายของคุณโดยแทนที่ MSE ด้วยระยะทางที่แม่นยำมากขึ้นโดยไม่ต้องเปลี่ยนอัลกอริทึมพื้นฐาน


ขอบคุณ! LAP และ Hungarian Method เป็นผู้นำที่ฉันต้องการ! อัปเดตด้วยผลลัพธ์ที่เป็นปัญหา
จะ

3

ฉันค่อนข้างแน่ใจว่านั่นเป็นปัญหา NP-hard เพื่อหาทางออก 'สมบูรณ์แบบ' คุณจะต้องลองทุกความเป็นไปได้อย่างละเอียดถี่ถ้วน

วิธีหนึ่งที่จะใช้ความพอดีแบบโลภแล้วลองปรับปรุงมัน นั่นอาจเป็นได้โดยการวางภาพที่ไม่ดี (หนึ่งในภาพสุดท้าย) และค้นหาสถานที่อื่นที่จะใส่จากนั้นถ่ายภาพนั้นและย้ายมันไปเรื่อย ๆ คุณทำเสร็จเมื่อ (ก) หมดเวลา (ข) ความพอดีคือ 'ดีพอ'

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


ใช่มันคล้ายกับที่คุณทำอยู่ ประเด็นคือการลืมคำตอบมายากลและคิดในแง่ของอัลกอริธึมที่ 2: เติมแรกแล้วปรับให้เหมาะสม

การเติมอาจเป็น: สุ่มมีให้ดีที่สุดดีที่สุดก่อนดีพอมีบางจุดร้อน

การเพิ่มประสิทธิภาพอาจเป็นแบบสุ่มแก้ไขที่แย่ที่สุดหรือ (ตามที่ฉันแนะนำ) การจำลองการอบอ่อนหรืออัลกอริทึมทางพันธุกรรม

คุณต้องมีตัวชี้วัดของ 'คุณงามความดี' และระยะเวลาที่คุณเตรียมที่จะใช้จ่ายและเพียงแค่ทำการทดสอบ หรือหาคนที่ทำจริง


คุณอธิบายวิธีการที่อธิบายไว้ในคำถาม ... หรือไม่
จะ

1

หากไทล์สุดท้ายเป็นปัญหาของคุณคุณควรพยายามวางไว้ก่อนเวลาอย่างใด;)

วิธีหนึ่งคือดูกระเบื้องที่อยู่ไกลที่สุดจากอันดับ x% ของการแข่งขัน นั่นคือการจับคู่ที่ดีที่สุดที่จะได้รับต่อไป

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

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

นอกจากนี้เมื่อใช้การตรวจจับขอบคุณอาจต้องวาง y% โลภแรก (อาจจนกว่าคุณจะวาง "edginess" ในกระเบื้องด้านซ้าย) เพื่อให้ "ฮอตสปอต" ถูกจัดการอย่างดี จากนั้นสลับไปที่ "การควบคุมความเสียหาย" สำหรับส่วนที่เหลือ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.