การครอบตัดโดยพลการของรูปร่างอัตโนมัติ


14

ฉันมีรูปร่างตามอำเภอใจซึ่งกำหนดโดยรูปแบบไบนารี (สีเทา = รูปร่าง, สีดำ = พื้นหลัง)

ฉันต้องการค้นหาสี่เหลี่ยมที่มีขนาดใหญ่ที่สุดที่มีพิกเซลสีเทาเท่านั้น (สี่เหลี่ยมนั้นเป็นภาพสีเหลือง):

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

รูปร่างนั้นเป็น "ชิ้นเดียว" เสมอ แต่ไม่จำเป็นต้องนูน (ไม่ใช่ทุกจุดคู่บนขอบเขตของรูปร่างที่สามารถเชื่อมต่อกันด้วยเส้นตรงที่วิ่งผ่านรูปร่าง)

บางครั้งมี "สี่เหลี่ยมจัตุรัสสูงสุด" อยู่จำนวนมากจากนั้นจึงสามารถนำข้อ จำกัด เพิ่มเติมมาใช้เช่น:

  • การใช้รูปสี่เหลี่ยมผืนผ้าโดยมีจุดศูนย์กลางอยู่ใกล้กับจุดศูนย์กลางมวลของรูปร่าง (หรือศูนย์กลางของภาพ)
  • การใช้สี่เหลี่ยมที่มีอัตราส่วนกว้างยาวที่สุดใกล้กับอัตราส่วนที่กำหนดไว้ล่วงหน้า (เช่น 4: 3)

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

ความคิดแรกของฉันเกี่ยวกับอัลกอริทึมคือ:

  1. คำนวณการแปลงระยะทางของรูปร่างและค้นหาจุดศูนย์กลางมวล
  2. ขยายพื้นที่สี่เหลี่ยมในขณะที่มีพิกเซลของรูปร่างเท่านั้น
  3. ขยายสี่เหลี่ยม (แต่เดิมเป็นสี่เหลี่ยม) ในความกว้างหรือความสูงในขณะที่มันมีพิกเซลของรูปร่างเท่านั้น

อย่างไรก็ตามฉันคิดว่าอัลกอริทึมดังกล่าวจะช้าและจะไม่นำไปสู่ทางออกที่ดีที่สุด

ข้อเสนอแนะใด ๆ


2
สิ่งนี้มีประโยชน์หรือไม่? mathworks.com/matlabcentral/fileexchange/…
Atul Ingle

@AtulIngle อย่างแน่นอน! ขอบคุณ คุณสามารถเพิ่มคำตอบเพื่อให้ฉันยอมรับได้หรือไม่ จากนั้นฉันจะพยายามแก้ไขคำตอบเพื่ออธิบายเพิ่มเติมเกี่ยวกับอัลกอริทึม - แต่ฉันไม่ต้องการเพียงแค่ตอบคำถามของตัวเองโดยใช้ลิงก์ที่คุณให้ ...
Libor

ที่ดี! ฉันหวังว่าจะได้อ่านคำตอบที่ซับซ้อนของคุณในขณะที่ฉันยังไม่ได้อ่านรหัส
Atul Ingle

@AtulIngle ตกลงฉันได้เพิ่มการสนทนาในคำตอบและเชื่อมโยงไปยังบทความเต็มของฉัน
Libor

คำตอบ:


10

มีรหัสใน Matlab Fileexchange ที่เกี่ยวข้องกับปัญหาของคุณ: http://www.mathworks.com/matlabcentral/fileexchange/28155-inscribedrectangle/content/html/Inscribed_Rectangle_demo.html

ปรับปรุง

ฉันเขียนบทความเกี่ยวกับการสอนเรื่องการคำนวณสี่เหลี่ยมที่ถูกจารึกไว้ที่ใหญ่ที่สุดโดยอิงจากลิงก์ด้านบนจาก Atul Ingle

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

squares[x,y] = min(squares[x+1,y], squares[x,y+1], squares[x+1,y+1]) + 1

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

ตัวอย่างไบนารีมาสก์และแผนที่ที่คำนวณได้มีลักษณะดังนี้:

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

การรับสูงสุดในแผนที่จะเผยให้เห็นจตุรัสที่ถูกจารึกไว้ที่ใหญ่ที่สุด:

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

อัลกอริธึมการค้นหาแบบสี่เหลี่ยมผืนผ้ามากกว่าการสแกนมาสก์อีกสองครั้งเพื่อค้นหาสี่เหลี่ยมสองคลาส:

  • ความกว้างมากกว่าสี่เหลี่ยมจัตุรัส (และความสูงอาจน้อยกว่า)
  • ความสูงมากกว่าขนาดของสี่เหลี่ยมจัตุรัส (และความกว้างอาจน้อยกว่า)

ทั้งสองคลาสถูกล้อมรอบด้วยสี่เหลี่ยมที่ใหญ่ที่สุดเนื่องจากไม่มีสี่เหลี่ยมที่จุดที่กำหนดสามารถมีทั้งสองมิติมากกว่าสี่เหลี่ยมจัตุรัสที่ถูกจารึกไว้ (แม้ว่าหนึ่งมิติจะใหญ่กว่า)

เราต้องเลือกเมตริกสำหรับขนาดสี่เหลี่ยมผืนผ้าเช่นพื้นที่เส้นรอบวงหรือผลรวมของมิติ

นี่คือแผนที่ผลลัพธ์สำหรับสี่เหลี่ยม:

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

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

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

การใช้งานจริงของอัลกอริทึมนี้คือการครอบตัดรูปภาพที่ไม่ใช่แบบสี่เหลี่ยม ฉันใช้อัลกอริธึมนี้ในไลบรารีการเย็บรูปภาพ SharpStitchของฉัน:

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

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