การประมวลผลภาพ: การปรับปรุงอัลกอริทึมสำหรับการรับรู้ 'Coca-Cola Can'


1658

หนึ่งในโครงการที่น่าสนใจที่สุดที่ผมเคยทำงานอยู่ในคู่ที่ผ่านมาของปีที่ผ่านมาเป็นโครงการเกี่ยวกับการประมวลผลภาพ เป้าหมายคือการพัฒนาระบบเพื่อให้สามารถรู้จัก'กระป๋อง' ของ Coca-Cola (โปรดทราบว่าฉันกำลังเน้นคำว่า 'กระป๋อง' คุณจะเห็นว่าทำไมในหนึ่งนาที) คุณสามารถดูตัวอย่างด้านล่างโดยที่สามารถรู้จักในสี่เหลี่ยมสีเขียวพร้อมสเกลและการหมุน

การจับคู่แม่แบบ

ข้อ จำกัด บางประการเกี่ยวกับโครงการ:

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

ดังนั้นคุณสามารถจบลงด้วยสิ่งที่ยุ่งยากเช่นนี้ (ซึ่งในกรณีนี้อัลกอริทึมของฉันล้มเหลวโดยสิ้นเชิง):

ยอดรวมล้มเหลว

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

ภาษา : เสร็จใน C ++ โดยใช้ไลบรารีOpenCV

การประมวลผลล่วงหน้า : สำหรับการประมวลผลภาพล่วงหน้าเช่นเปลี่ยนภาพให้อยู่ในรูปแบบดิบมากขึ้นเพื่อมอบให้กับอัลกอริทึมฉันใช้ 2 วิธี:

  1. การเปลี่ยนโดเมนสีจาก RGB เป็นHSVและการกรองตามเฉดสี "สีแดง" ความอิ่มตัวของสีเหนือขีด จำกัด ที่กำหนดเพื่อหลีกเลี่ยงสีที่มีลักษณะคล้ายสีส้มและการกรองค่าต่ำเพื่อหลีกเลี่ยงโทนมืด ผลลัพธ์ที่ได้คือภาพขาวดำไบนารีซึ่งพิกเซลสีขาวทั้งหมดจะเป็นตัวแทนของพิกเซลที่ตรงกับเกณฑ์นี้ เห็นได้ชัดว่ายังมีอึมากในภาพ แต่จะช่วยลดจำนวนมิติที่คุณต้องทำงานด้วย ภาพซ้อน
  2. การกรองสัญญาณรบกวนโดยใช้การกรองแบบมัธยฐาน (ใช้ค่าพิกเซลเฉลี่ยของประเทศเพื่อนบ้านทั้งหมดและแทนที่พิกเซลด้วยค่านี้) เพื่อลดเสียงรบกวน
  3. การใช้ตัวกรองการตรวจจับขอบของ Cannyเพื่อรับรูปทรงของรายการทั้งหมดหลังจาก 2 ขั้นตอนก่อนหน้า การตรวจจับรูปร่าง

ขั้นตอนวิธีการ : ขั้นตอนวิธีการของตัวเองผมเลือกสำหรับงานนี้ถูกนำมาจากนี้หนังสือที่น่ากลัวในการสกัดคุณลักษณะและเรียกทั่วไป Hough Transform (ที่แตกต่างกันสวยจากปกติ Hough Transform) โดยพื้นฐานแล้วมันบอกว่าบางสิ่ง:

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

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

GHT

เมื่อคุณทราบแล้วฮิวริสติกแบบอิงเกณฑ์สามารถให้ตำแหน่งของพิกเซลกลางซึ่งคุณสามารถรับขนาดและการหมุนจากนั้นพล็อตสี่เหลี่ยมผืนผ้าเล็ก ๆ ของคุณรอบ ๆ มัน (ขนาดสเกลและการหมุนสุดท้ายจะเห็นได้ชัดว่าสัมพันธ์กับคุณ เทมเพลตดั้งเดิม) ในทางทฤษฎีอย่างน้อย ...

ผลลัพธ์ : ตอนนี้ในขณะที่วิธีการนี้ใช้งานได้ในกรณีพื้นฐาน แต่ก็ขาดไปอย่างมากในบางพื้นที่:

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

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

ฉันหวังว่าบางคนจะเรียนรู้บางสิ่งบางอย่างจากมันเช่นกันฉันคิดว่าไม่ใช่เฉพาะคนที่ถามคำถามเท่านั้นที่ควรเรียนรู้ :)


45
อาจมีการกล่าวว่าคำถามนี้เหมาะสมกว่าที่ dsp.stackexchange.com หรือ stats.stackexchange.com และคุณควรพิจารณาถามซ้ำอีกครั้งที่ไซต์เหล่านั้นด้วย
ely

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

7
@stacker ทำให้เป็นจุดที่ดี สำหรับความเร็วที่คุณต้องการได้รับคุณสมบัติราคาถูกเพื่อคำนวณเช่นฮิสโตแกรมของการไล่ระดับสีเชิง วิธีแรกที่ไร้เดียงสาจริงๆคือการติดป้ายสี่เหลี่ยมขนาดใหญ่ในภาพการฝึกอบรมด้วยตนเองและใช้ตัวอย่างเชิงลบแบบสุ่มบวกเหล่านี้เพื่อฝึกอบรม SVM หรือลักษณนามต้นไม้ตัดสินใจ การฝึกอบรมจะใช้เวลานานกว่า แต่การดำเนินการกับภาพใหม่จะเร็วกว่ามาก ฉันวางแผนที่จะเขียนวิธีนี้ขึ้นเมื่อฉันมีเวลาว่างมากขึ้นเพื่อรวมการอ้างอิงที่ถูกต้อง
ely

9
วิธีการเกี่ยวกับวิธีการคล้ายกับreCAPTCHA ? ;)
George Duckett

39
ทำไมเรื่องนี้จึงถูกย้ายจากdsp.stackexchange.com ? ดูเหมือนว่าไซต์นั้นจะมีขนาดพอดีดีกว่า stackoverflow o_O
BlueRaja - Danny Pflughoeft

คำตอบ:


672

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

มันถูกนำมาใช้ในOpenCV 2.3.1

คุณสามารถค้นหาตัวอย่างโค้ดที่ดีโดยใช้คุณสมบัติในFeatures2D + Homography เพื่อค้นหาวัตถุที่รู้จัก

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

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

แหล่งที่มาของภาพ: ตัวอย่างการสอน

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

เอกสารต้นฉบับ


6
ฉันเห็นด้วยกับ @stacker - SIFT เป็นตัวเลือกที่ยอดเยี่ยม มันแข็งแกร่งมากเมื่อเทียบกับขนาดและการหมุน มันค่อนข้างแข็งแกร่งเทียบกับการเสียรูปเปอร์สเปคทีฟ (สิ่งนี้สามารถปรับปรุงได้ตามที่ stacker แนะนำ: ฐานข้อมูลแม่แบบที่มีมุมมองเปอร์สเปคทีฟที่แตกต่างกันของวัตถุที่ต้องการ) ส้นของ Achilles ในประสบการณ์ของฉันจะเป็นแสงที่หลากหลายและการคำนวณราคาแพงมาก ฉันไม่รู้การใช้งานจาวาใด ๆ ฉันตระหนักถึงการใช้งาน OpenCV และได้ใช้การติดตั้ง GPU c ++ / Windows ( SiftGPU ) ที่เหมาะกับการใช้งานแบบเรียลไทม์

31
ข้อควรระวัง: เท่าที่ฉันรัก SIFT / SURF และสิ่งที่พวกเขาทำกับฉันพวกเขาถูกจดสิทธิบัตร สิ่งนี้อาจเป็นปัญหาขึ้นอยู่กับเงื่อนไขหลายประการรวมถึงที่ตั้งทางภูมิศาสตร์ AFAIK
Agos

12
ดังนั้นลองใช้ ORB หรือ FREAK ของ OpenCV ที่ไม่มีปัญหาสิทธิบัตร ORB เร็วกว่า SIFT มาก ORB มันค่อนข้างแย่เมื่อเทียบกับขนาดและรูปแบบแสงในประสบการณ์ของฉัน แต่ทดสอบด้วยตัวเอง
Rui Marques

66
คุณจะยอมรับสิ่งนี้ได้อย่างไรในฐานะคำตอบ ... ไม่มีคำอธิบายคุณลักษณะใดที่สามารถแยกความแตกต่างของขวดออกจากกระป๋อง .. พวกเขาทั้งหมดเพียงแค่ดูรูปแบบของรูปแบบในท้องถิ่นที่คงที่ ฉันยอมรับว่า SIFT, SURF, ORB, FREAK และอื่น ๆ สามารถช่วยคุณในการจับคู่คุณสมบัติ แต่ .. เกี่ยวกับส่วนอื่น ๆ ของคำถามเช่น occlusions, ขวด vs Can ฯลฯ ฉันหวังว่านี่จะไม่ใช่ทางออกที่สมบูรณ์ถ้าคุณต้องการ ให้ GOOGLED ปัญหาของคุณน่าจะเป็นผลลัพธ์แรกจะเป็นคำตอบนี้เท่านั้น
G453

11
@ G453 คุณพูดถูก! อาจเป็นเพราะเขารู้สึกทึ่งกับประสิทธิภาพของ SHIFT และลืมว่าการดึงข้อมูลและการจับคู่ไม่ใช่ปัญหา ...
sepdek

383

เพื่อให้เร็วขึ้นฉันจะใช้ประโยชน์จากความจริงที่ว่าคุณไม่ได้ถูกขอให้ค้นหาภาพ / วัตถุโดยพลการ แต่เป็นภาพที่มีโลโก้ Coca-Cola โดยเฉพาะ สิ่งนี้มีความสำคัญเนื่องจากโลโก้นี้มีความโดดเด่นมากและควรมีลายเซ็นที่ไม่เปลี่ยนแปลงขนาดในโดเมนความถี่โดยเฉพาะในช่องสีแดงของ RGB กล่าวคือรูปแบบการสลับของการสแกนแนวนอน - แดง - ขาว - แดงที่พบโดยแนวการสแกนแนวนอน (ผ่านการฝึกอบรมในโลโก้แนวนอน) จะมี "จังหวะ" ที่โดดเด่นเมื่อผ่านแกนกลางของโลโก้ จังหวะนั้นจะ "เร่งความเร็ว" หรือ "ช้าลง" ในระดับและทิศทางที่แตกต่างกัน แต่จะยังคงสัดส่วนเท่ากัน คุณสามารถระบุ / กำหนด scanlines เช่นสองสามโหลทั้งแนวนอนและแนวตั้งผ่านโลโก้และอีกหลายแนวทแยงมุม ในรูปแบบดาวกระจาย เรียกว่า "บรรทัดการสแกนลายเซ็น"

ลายเซ็นสแกนเส้น

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

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

(อัปเดต: สำหรับการรับรู้ขวดฉันจะมองหาโค้ก (ของเหลวสีน้ำตาล) ติดกับโลโก้ - นั่นคือภายในขวดหรือในกรณีของขวดเปล่าฉันจะมองหาหมวกที่จะมี รูปร่างพื้นฐานขนาดและระยะห่างที่เหมือนกันของโลโก้และโดยทั่วไปจะเป็นสีขาวหรือสีแดงค้นหารูปทรงสีทึบที่ควรจะเป็นเมื่อเทียบกับโลโก้ไม่แน่นอน แต่เป้าหมายของคุณควรอยู่ที่นี่ หาง่ายคนได้อย่างรวดเร็ว .)

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


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

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

29
ฉันชอบแนวคิดของการใช้จำนวนเครื่องสแกนบาร์โค้ดสำหรับการตรวจจับโลโก้ Coca-Cola อย่างรวดเร็ว +1!
Li-aung Yip

8
ปัญหาของการค้นหาลายเซ็นในกรณีนี้คือถ้าเราหมุนกระป๋องไปอีกด้านหนึ่งเช่นการซ่อนลายเซ็นต์อัลกอริทึมจะไม่สามารถตรวจจับกระป๋องได้
karlphillip

34
@karlphillip: หากคุณซ่อนลายเซ็นเช่นโลโก้ดังนั้นวิธีการใด ๆ ที่ขึ้นอยู่กับการค้นหาโลโก้จะล้มเหลว
Li-aung Yip

162

ปัญหาสนุก: เมื่อฉันมองภาพขวดของคุณฉันก็คิดว่ามันก็เป็นกระป๋องได้เช่นกัน แต่ในฐานะมนุษย์สิ่งที่ฉันทำเพื่อบอกความแตกต่างก็คือฉันก็สังเกตเห็นว่ามันเป็นขวด ...

ดังนั้นเพื่อบอกกระป๋องและขวดแตกต่างกันแค่สแกนหาขวดก่อนล่ะ? หากคุณพบเจอให้ปิดฉลากก่อนที่จะมองหากระป๋อง

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


5
ใช่ฉันก็คิดเกี่ยวกับเรื่องนั้นเช่นกัน แต่ก็ไม่มีเวลามากที่จะทำ คุณจะจำขวดได้อย่างไรเนื่องจากส่วนหลักจะมีลักษณะเป็นกระป๋อง ฉันคิดว่ากำลังมองหาปลั๊กสีแดงด้วยและดูว่ามันสอดคล้องกับศูนย์ขวดหรือเปล่า แต่มันก็ดูไม่ค่อยแข็งแกร่งเท่าไหร่
Charles Menguy

42
หากมีฝาสีแดง (หรือแหวน) ขนานกับ "โคคาโคล่า" มันน่าจะเป็นขวด
Lukasz Madon

@linker คุณฝึกขั้นตอนวิธีสำหรับกระป๋องอย่างไร คุณมีตัวอย่างกระป๋องหรือไม่? วิธีการเกี่ยวกับการฝึกอบรมตัวอย่างขวด?
siamii

1
จุดแข็งของอัลกอริธึมนี้คือคุณต้องการเพียงหนึ่งเทมเพลตเพื่อฝึกฝนและใช้การแปลงทั้งหมดเพื่อจับคู่กับกระป๋องที่มีศักยภาพอื่น ๆ ฉันใช้เทมเพลตรุ่นนี้ที่ได้รับการพัฒนาและมีเส้นสายเพื่อฝึกอบรมดังนั้นความแตกต่างเพียงอย่างเดียวระหว่างกระป๋องกับขวดก็คือปลั๊ก แต่ฉันเกรงว่ามันจะทำให้เกิดผลบวกที่ผิดพลาดมากขึ้นเนื่องจากจุดศูนย์ถ่วงจะอยู่ตรงขอบ หรือด้านนอกของขวด มันคุ้มค่าที่จะลองดูสิ แต่นั่นจะเพิ่มเวลาในการประมวลผลของฉันเป็นสองเท่าและฉันจะร้องไห้;)
Charles Menguy

7
โดยพื้นฐานแล้วนี่เป็นทิศทางที่สมเหตุสมผล ฉันจะวลีมันแตกต่างกันเล็กน้อย: ก่อนอื่นหาผู้สมัครทั้งหมดและจากนั้นสำหรับผู้สมัครแต่ละคนพิจารณาว่าเป็นขวดกระป๋องหรืออย่างอื่น
MSalters

131

เป็นเรื่องยากที่มนุษย์จะแยกแยะความแตกต่างระหว่างขวดและกระป๋องในภาพที่สอง (หากพื้นที่โปร่งใสของขวดถูกซ่อนอยู่)

พวกมันเกือบจะเหมือนกันยกเว้นพื้นที่เล็กมาก (นั่นคือความกว้างที่ด้านบนของกระป๋องเล็กไปหน่อยในขณะที่เสื้อคลุมของขวดมีความกว้างเท่ากันตลอด แต่เปลี่ยนเล็กน้อยใช่ไหม?)

สิ่งแรกที่อยู่ในใจของฉันคือการตรวจสอบด้านบนของขวดสีแดง แต่ก็ยังคงมีปัญหาหากไม่มีขวดด้านบนหรือถ้ามันถูกซ่อนอยู่บางส่วน (ดังกล่าวข้างต้น)

สิ่งที่สองที่ฉันคิดเกี่ยวกับความโปร่งใสของขวด OpenCV มีงานบางอย่างในการค้นหาวัตถุโปร่งใสในภาพ ตรวจสอบลิงค์ด้านล่าง

โดยเฉพาะอย่างยิ่งดูที่นี่เพื่อดูว่าพวกเขาตรวจจับแก้วได้อย่างแม่นยำ:

ดูผลการดำเนินงานของพวกเขา:

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

พวกเขากล่าวว่าเป็นการใช้งานกระดาษ"A Geodesic Active Contour Framework สำหรับการค้นหาแก้ว" โดย K. McHenry และ J. Ponce, CVPR 20062006

มันอาจจะเป็นประโยชน์ในกรณีของคุณเล็กน้อยแต่ปัญหาเกิดขึ้นอีกครั้งถ้าขวดเต็ม

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

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

ตอนนี้คุณสามารถลบภูมิภาคสีเหลืองนั่นคือฉลากของขวดและเรียกใช้อัลกอริทึมของคุณเพื่อค้นหากระป๋อง

อย่างไรก็ตามการแก้ปัญหานี้ยังมีปัญหาที่แตกต่างเช่นในโซลูชั่นอื่น ๆ

  1. มันทำงานได้เฉพาะในกรณีที่ขวดของคุณว่างเปล่า ในกรณีนี้คุณจะต้องค้นหาพื้นที่สีแดงระหว่างสีดำสองสี (หากของเหลว Coca Cola เป็นสีดำ)
  2. ปัญหาอื่นถ้าส่วนที่โปร่งใสถูกครอบคลุม

แต่อย่างไรก็ตามหากไม่มีปัญหาข้างต้นในภาพดูเหมือนว่าจะเป็นวิธีที่ดีกว่า


+1 ฉันคิดเกี่ยวกับสิ่งนี้และกำลังจะใช้แนวทางนี้ อย่างไรก็ตาม @linker ควรแชร์ชุดรูปภาพของเขาเพื่อที่เราจะได้ทำการเดาที่มีการศึกษามากขึ้น
karlphillip

ใช่ .. ฉันคิดว่ามันดีถ้ามีภาพมากกว่านี้
Abid Rahman K

พิจารณาว่าเรามีฉลากสำหรับขวด / กระป๋องเท่านั้นและไม่มีปัจจัยอื่นที่แตกต่างของฝาขวดหรือความโปร่งใสหรือด้านบน / ล่าง - ความกว้างของขวดนั้นแตกต่างจากความกว้างของกระป๋อง
Ken

เกิดอะไรขึ้นถ้ากระป๋องวางหน้าโลโก้ขวด?
AlgoRythm

51

ฉันชอบคำตอบของDarren Cookและstackerจริงๆต่อปัญหานี้ ฉันอยู่ในท่ามกลางการแสดงความคิดเห็นเกี่ยวกับสิ่งเหล่านั้น แต่ฉันเชื่อว่าวิธีการของฉันนั้นมีคำตอบมากเกินไปที่จะไม่ทิ้งไว้ที่นี่

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

ความลับในที่นี้คือการพิจารณาว่าคุณลักษณะภาพใดที่สามารถมีหรือผ่านช่องว่างเชิงลบคุณลักษณะใดบ้างที่มีอยู่สำหรับผลิตภัณฑ์โค้กอื่น ๆ ที่ไม่มีอยู่ในกระป๋อง ด้วยเหตุนี้คำตอบยอดนิยมในปัจจุบันจะร่างวิธีการพื้นฐานสำหรับการเลือก "สามารถ" หากไม่ระบุ "ขวด" หากมีฝาขวดของเหลวหรือวิธีการแสดงภาพอื่น ๆ ที่คล้ายกัน

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

ด้วยเหตุนี้เกณฑ์การเลือกกระป๋องที่ถูกต้องที่สุดจะเป็นดังนี้:

  • รูปร่างของวัตถุนั้นเป็นรูปทรงหรือไม่เมื่อคุณร่างคำถามของคุณถูกต้อง? ถ้าเป็นเช่นนั้น +1
  • หากเราสันนิษฐานว่ามีแสงจากธรรมชาติหรือแสงเทียมเราตรวจจับโครงร่างโครเมี่ยมกับขวดที่บ่งบอกว่าสิ่งนี้ทำจากอลูมิเนียมหรือไม่? ถ้าเป็นเช่นนั้น +1
  • เราพิจารณาแล้วว่าคุณสมบัติ specularของวัตถุนั้นถูกต้องสัมพันธ์กับแหล่งกำเนิดแสงของเรา ( ลิงก์วิดีโอตัวอย่างในการตรวจจับแหล่งกำเนิดแสง ) หรือไม่ ถ้าเป็นเช่นนั้น +1
  • เราสามารถพิจารณาคุณสมบัติอื่น ๆ เกี่ยวกับวัตถุที่ระบุว่ามันเป็นกระป๋องรวมถึง แต่ไม่ จำกัด เพียงภาพโทโพโลยีที่เอียงของโลโก้การวางแนวของวัตถุการวางเคียงกันของวัตถุ (ตัวอย่างเช่นบนพื้นผิวภาพถ่าย) เช่นตารางหรือในบริบทของกระป๋องอื่น ๆ ) และการปรากฏตัวของแท็บดึง? ถ้าเป็นเช่นนั้นสำหรับแต่ละ +1

การจำแนกประเภทของคุณอาจมีลักษณะดังนี้:

  • สำหรับการจับคู่ผู้สมัครแต่ละครั้งหากตรวจพบโลโก้ Coca Cola ให้วาดเส้นขอบสีเทา
  • สำหรับการแข่งขันแต่ละครั้งที่มากกว่า +2 ให้วาดเส้นขอบสีแดง

สิ่งนี้จะเน้นให้ผู้ใช้เห็นสิ่งที่ตรวจพบโดยเน้นการมองในแง่บวกที่อาจตรวจพบได้อย่างถูกต้องว่าเป็นกระป๋อง

การตรวจจับของแต่ละสถานที่มีความซับซ้อนของเวลาและพื้นที่แตกต่างกันและสำหรับแต่ละวิธีการส่งผ่านอย่างรวดเร็วผ่านhttp://dsp.stackexchange.comนั้นมีเหตุผลมากกว่าการพิจารณาอัลกอริทึมที่ถูกต้องและมีประสิทธิภาพมากที่สุดสำหรับวัตถุประสงค์ของคุณ ความตั้งใจของฉันที่นี่คือบริสุทธิ์และเรียบง่ายเพื่อเน้นว่าการตรวจสอบว่ามีสิ่งใดสามารถทำได้โดยทำให้ส่วนการตรวจจับของผู้สมัครไม่ถูกต้องไม่ถูกต้องนั้นไม่ใช่วิธีการแก้ปัญหาที่มีประสิทธิภาพหรือมีประสิทธิภาพมากที่สุดสำหรับปัญหานี้ ตาม

และขอแสดงความยินดีกับการโพสต์ Hacker News! โดยรวมแล้วนี่เป็นคำถามที่ยอดเยี่ยมมากสำหรับการประชาสัมพันธ์ที่ได้รับ :)


2
นั่นเป็นวิธีที่น่าสนใจซึ่งอย่างน้อยก็คุ้มค่าที่จะลองใช้ฉันชอบเหตุผลของคุณเกี่ยวกับปัญหา
Charles Menguy

นี่คือสิ่งที่ฉันคิด: อย่าแยกประเภทของสิ่งที่ผิด กฎในคุณสมบัติเพิ่มเติมของสิ่งที่ทำให้โค้กสามารถ แต่ฉันสงสัยว่า: คุณทำอะไรเกี่ยวกับกระป๋องที่ถูกแบน? ฉันหมายความว่าถ้าคุณเหยียบโค้กกระป๋องมันก็ยังเป็นกระป๋องได้ แต่มันจะไม่มีรูปร่างเหมือนเดิมอีกต่อไป หรือว่าเป็นปัญหา AI-Complete?
เอียน

41

มองที่รูปร่าง

มองดูรูปร่างของกระป๋อง / ขวดสีแดง ขอให้สังเกตว่ากระป๋องลดลงเล็กน้อยที่ด้านบนสุดในขณะที่ฉลากขวดตรง คุณสามารถแยกความแตกต่างระหว่างสองสิ่งนี้โดยการเปรียบเทียบความกว้างของส่วนสีแดงกับความยาวของมัน

มองไปที่ไฮไลท์

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

เท่าที่ฉันสามารถบอกได้ว่าเป็นวิธีที่มนุษย์จะบอกความแตกต่างระหว่างฉลากสองประเภท หากสภาพแสงไม่ดีมีความไม่แน่นอนในการแยกความแตกต่างของทั้งสองอย่างไรก็ตาม ในกรณีนี้คุณจะต้องสามารถตรวจสอบสถานะของขวดโปร่งใส / โปร่งแสงได้


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

ในตัวอย่างของคุณให้สังเกตว่า specularity สำหรับฉลากพลาสติกกระจายได้มากกว่าจุดสว่างบนกระป๋อง? นั่นคือวิธีที่คุณสามารถบอกได้
tskuzzy

ฉันเห็นคุณต้องการใช้การแทนพื้นที่สีประเภทใดในกรณีนี้เพื่อจับภาพ specularity ในอัลกอริทึมของคุณ ดูเหมือนว่าจะเป็นการยากที่จะได้รับใน RGB หรือ HSV
Charles Menguy

3
ถ้าแหล่งกำเนิดแสงอยู่ด้านหลังกระป๋อง ฉันคิดว่าคุณจะไม่เห็นไฮไลท์
Rui Marques

37

โปรดดูที่ตัวติดตาม Predatorของ Zdenek Kalalติดตาม มันต้องมีการฝึกอบรมบางอย่าง แต่มันสามารถเรียนรู้วิธีที่วัตถุที่ถูกติดตามดูการวางแนวและตาชั่งที่แตกต่างกัน

ซอร์สโค้ดมีอยู่ในเว็บไซต์ของเขา มันอยู่ในMATLABแต่อาจมีการนำ Java ไปใช้งานแล้วโดยสมาชิกชุมชน ฉันได้ติดตั้งส่วนติดตามของ TLD อีกครั้งใน C # หากฉันจำได้อย่างถูกต้อง TLD จะใช้ Ferns เป็นเครื่องมือตรวจจับจุดสำคัญ ฉันใช้ SURF หรือ SIFT แทน (แนะนำโดย @stacker แล้ว) เพื่อ reququire วัตถุถ้ามันหายไปโดยติดตาม คำติชมของตัวติดตามทำให้ง่ายต่อการสร้างตามเวลาที่รายการเทมเพลตลอด / โต้คลื่นแบบไดนามิกที่มีเวลาเปิดใช้งานการเรียกคืนวัตถุด้วยความแม่นยำสูงมาก

หากคุณสนใจที่จะติดตั้งตัวติดตาม C # ของฉันอย่าลังเลที่จะถาม


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

ขณะทำการค้นคว้า TLD ฉันพบผู้ใช้รายอื่นที่กำลังมองหาการใช้งาน C # --- มีเหตุผลใดที่จะไม่นำงานของคุณมาใช้กับ Github stackoverflow.com/questions/29436719/…
spillner

2
NB ปีต่อมาการเชื่อมโยงตอนนี้ตาย
J Evans

33

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

นอกจากนี้ฉันสามารถแนะนำไม่จำเป็นต้องมีความแม่นยำหรือความเร็ว แต่เพื่อความสนุกคุณสามารถใช้โครงข่ายประสาทเทียมที่ได้รับการฝึกฝนบนภาพแบ่งส่วนสีเพื่อระบุรูปร่างของกระป๋อง สิ่งเหล่านี้เร็วมากและแม่นยำมากถึง 80/90% การฝึกอบรมจะเป็นกระบวนการที่ใช้เวลานาน แต่เนื่องจากคุณต้องระบุความสามารถในแต่ละภาพด้วยตนเอง


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

ขนาดของชุดการฝึกอบรมที่มีโครงข่ายประสาทเทียมจะให้ผลที่น่าพอใจเท่าไร สิ่งที่ดีในวิธีนี้ก็คือฉันต้องการเพียงหนึ่งเทมเพลตเพื่อจับคู่เกือบทุกอย่าง
Charles Menguy

2
หากชุดภาพของคุณถูกกำหนดไว้ล่วงหน้าและถูก จำกัด เพียงแค่ผลลัพธ์ที่สมบูรณ์แบบไม่ยอมใครง่ายๆในโปรแกรมของคุณ;)
sne11ius

ใช่ถ้าฉันฝึกบนชุดข้อมูลฉันจะใช้อัลกอริทึมกับแน่ใจว่าฉันจะได้ผลลัพธ์ที่สมบูรณ์แบบ :) แต่ตัวอย่างเช่นสำหรับการมอบหมายนี้โปรแกรมได้รับการทดสอบโดยอาจารย์ในตอนท้ายของชุดรูปภาพที่จัดขึ้น . ฉันต้องการทำสิ่งที่จะแข็งแกร่งและไม่เหมาะสมกับข้อมูลการฝึกอบรม
Charles Menguy

จำนวนชุดการฝึกซ้อมจะแตกต่างกันไป แต่คุณต้องระวังในเรื่องเล็ก ๆ น้อย ๆ ด้วย: อย่าไปรถไฟคุณอาจต้องการให้ชุดทดสอบแสดงความแม่นยำของคุณ จำนวนชุดการฝึกจะขึ้นอยู่กับจำนวนเลเยอร์ที่คุณจะใช้
Fantastic Mr Fox

24

ฉันจะตรวจสอบรูปสี่เหลี่ยมสีแดง: RGB -> HSV, ตัวกรองสีแดง -> ภาพไบนารีปิด (ขยายแล้วลบออกรู้จักกันimcloseใน MATLAB)

จากนั้นมองผ่านรูปสี่เหลี่ยมผืนผ้าจากใหญ่ไปหาน้อยที่สุด สี่เหลี่ยมที่มีสี่เหลี่ยมเล็ก ๆ ในตำแหน่ง / มาตราส่วนที่รู้จักสามารถถูกเอาออกได้ (สมมติว่าสัดส่วนขวดเป็นค่าคงที่สี่เหลี่ยมเล็ก ๆ จะเป็นฝาขวด)

นี่จะทำให้คุณเป็นรูปสี่เหลี่ยมสีแดงจากนั้นคุณจะต้องตรวจสอบโลโก้เพื่อบอกว่ามันเป็นรูปสี่เหลี่ยมผืนผ้าสีแดงหรือกระป๋องโค้ก ชอบ OCR แต่มีโลโก้เป็นที่รู้จัก


2
เช่นนี้กำลังถูกกล่าวถึงใน DSP ในเวลาสั้น ๆ เมื่อมันถูกย้ายขวดบางส่วนอาจไม่มีปลั๊ก;) หรือปลั๊กอาจซ่อนบางส่วน
Charles Menguy

22

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


3
ที่จริงแล้วไม่มี: ไม่มีข้อ จำกัด เรื่องขนาดหรือการวางแนว (หรือการวางแนว แต่ฉันไม่ได้จัดการกับมัน) ดังนั้นคุณจึงสามารถวางขวดได้ไกลมากในพื้นหลังและกระป๋องในพื้นหน้าและกระป๋องจะใหญ่กว่า กว่าขวด
Charles Menguy

ฉันได้ตรวจสอบด้วยว่าอัตราส่วนความกว้างต่อความสูงนั้นค่อนข้างใกล้เคียงกับขวดและกระป๋องดังนั้นนั่นก็ไม่ใช่ตัวเลือกเช่นกัน
Charles Menguy

อัตราส่วนฉลาก (เป็นเครื่องหมายการค้า) เหมือนกัน ดังนั้นหากขวด (ใหญ่กว่า) อยู่ไกลจากภาพเล็กน้อยขนาดของมันจะเหมือนกับของกระป๋อง
littleadv

3
เพื่ออธิบายเพิ่มเติมอีกเล็กน้อย สมมติว่ากระป๋องอยู่ที่ z = 0 และขวดที่ z = -100 เนื่องจากขวดอยู่ด้านหลังมันจะดูเล็กลง แต่ถ้าฉันรู้ว่าขวดอยู่ที่ z = -100 และสามารถที่ z = 0 จากนั้นฉันสามารถคำนวณขนาดที่คาดหวังของกระป๋อง / ขวดหากทั้งคู่แปลเป็น z = 0 ตอนนี้พวกเขาอยู่ที่ระดับความลึกเท่ากันและด้วยเหตุนี้ฉันสามารถตัดสินใจตามขนาด
Sharad

2
นี่เป็นเพียงความคิดเห็นไม่ใช่คำตอบ แต่มันใกล้กว่าที่จะเป็นคำตอบมากกว่าความเห็นในฐานะคำตอบข้างต้นด้วยคะแนนโหวต 120 คะแนน
Fattie

22

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

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

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

ที่นี่โลโก้ด้านบนและด้านล่างมีสีเข้มสนิทสอดคล้องกับสี ค่อนข้างง่ายในแง่ที่

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

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

(อันสุดท้ายคือสิ่งที่ดีที่สุดที่ฉันสามารถหาได้จากขวดโคคาโคล่าขนาดใหญ่ที่ว่างเปล่า - น่าสนใจที่หมวกและแหวนเป็นสีเหลืองแสดงว่าสีแดงของหมวกอาจไม่น่าเชื่อถือ)

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

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

  • ค้นหาแหล่งท่องเที่ยวหลัก (พื้นหลังโลโก้สีแดงและอาจเป็นโลโก้ของตัวเองสำหรับการวางแนวแม้ว่าในกรณีที่กระป๋องหันหน้าไปคุณต้องให้ความสนใจกับสีแดงเพียงอย่างเดียว)
  • ตรวจสอบรูปร่างและทิศทาง แต่อีกครั้งผ่านสีแดงที่โดดเด่นมาก
  • ตรวจสอบสีรอบ ๆ รูปร่าง (เนื่องจากรวดเร็วและไม่เจ็บปวด)
  • ในที่สุดหากจำเป็นให้ตรวจสอบรูปร่างของสีเหล่านั้นรอบแหล่งท่องเที่ยวหลักสำหรับความกลมที่เหมาะสม

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

ฝันร้ายเพิ่มเติมที่น่าสนใจอาจรวมถึงความสามารถในการนั่งด้านหลังขวดในระยะทางที่โลหะของมันเกิดขึ้นเพื่อแสดงด้านบนและด้านล่างของฉลากซึ่งจะยังคงล้มเหลวตราบใดที่คุณสแกนไปตามความยาวทั้งหมดของสีแดง ป้ายกำกับ - ซึ่งเป็นปัญหามากกว่าเพราะคุณไม่ได้ตรวจจับกระป๋องที่คุณสามารถมีได้ซึ่งต่างจากการพิจารณาว่าคุณกำลังตรวจจับขวดจริงรวมถึงกระป๋องโดยไม่ได้ตั้งใจ แก้วว่างเปล่าครึ่งหนึ่งในกรณีนี้!


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

แก้ไข

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


10
เฉดสีแดงส่วนใหญ่เป็นแบบอัตนัยและได้รับอิทธิพลอย่างมากจากการพิจารณาแสงและสมดุลสีขาว คุณอาจประหลาดใจกับจำนวนที่สามารถเปลี่ยนแปลงได้ ลองพิจารณาตัวอย่างเช่นภาพลวงตากระดานหมากรุกนี้
Octopus

2
การปรับปรุงการเชื่อมโยงที่ @Octopus โพสต์: persci.mit.edu/gallery/checkershadow
หาดใหญ่

ภาพลวงตาการรับรู้ไม่ส่งผลกระทบต่อสิ่งที่เว็บแคมของคุณมองเห็น - เช่นสิ่งที่รหัสของคุณได้รับ - เฉพาะสายตาของมนุษย์ที่มีประโยชน์ (?) ทำให้สมองเสียสติ
barny

17

ฉันไม่ทราบเกี่ยวกับ OpenCV แต่ดูที่ปัญหาอย่างมีเหตุผลฉันคิดว่าคุณสามารถแยกความแตกต่างระหว่างขวดและสามารถทำได้โดยการเปลี่ยนภาพที่คุณกำลังมองหาเช่น Coca Cola คุณควรรวมจนถึงส่วนบนของกระป๋องเช่นในกรณีที่มีซับเงินที่ด้านบนของโคคาโคล่าและในกรณีของขวดจะไม่มีซับเงินดังกล่าว

แต่เห็นได้ชัดว่าอัลกอริธึมนี้จะล้มเหลวในกรณีที่ซ่อนส่วนบนของกระป๋อง แต่ในกรณีเช่นนี้แม้แต่มนุษย์ก็จะไม่สามารถแยกความแตกต่างระหว่างสองคนได้


1
ฉันมีความคิดแบบเดียวกัน แต่ฉันคิดว่าสีเงินเรียงรายอยู่ด้านบนของกระป๋องสามารถเปลี่ยนแปลงได้อย่างมากขึ้นอยู่กับมุมของกระป๋องในภาพ สามารถเป็นเส้นตรงหรือวงกลม บางทีเขาอาจใช้ทั้งสองเป็นข้อมูลอ้างอิง?
Alexis Dufrenoy

15

ฉันชอบความท้าทายและต้องการให้คำตอบซึ่งฉันคิดว่าแก้ปัญหาได้

  1. แยกคุณสมบัติ (จุดสำคัญตัวอธิบายเช่น SIFT, SURF) ของโลโก้
  2. จับคู่คะแนนกับรูปแบบของโลโก้ (ใช้ Matcher เช่น Brute Force)
  3. ประเมินพิกัดของร่างกายแข็ง (ปัญหา PnP - SolvePnP)
  4. ประมาณตำแหน่งหมวกตามร่างกายที่แข็ง
  5. ทำการฉายย้อนกลับและคำนวณตำแหน่งพิกเซลภาพ (ROI) ของฝาขวด (ฉันถือว่าคุณมีพารามิเตอร์ที่แท้จริงของกล้อง)
  6. ตรวจสอบด้วยวิธีการว่าฝามีหรือไม่ หากมีแล้วนี่คือขวด

การตรวจจับฝาปิดเป็นปัญหาอื่น มันอาจจะซับซ้อนหรือเรียบง่ายก็ได้ ถ้าฉันเป็นคุณฉันจะตรวจสอบฮิสโตแกรมสีใน ROI เพื่อการตัดสินใจง่ายๆ

กรุณาให้ข้อเสนอแนะหากฉันผิด ขอบคุณ


13

ไม่กี่ปีที่ผ่านมาในการตอบคำถามนี้ ด้วยสถานะของศิลปะผลักดันให้ขีด จำกัด โดย CNNs ในช่วง 5 ปีที่ผ่านมาฉันจะไม่ใช้ OpenCV เพื่อทำงานนี้ทันที! ( ฉันรู้ว่าคุณต้องการคุณสมบัติ OpenCv โดยเฉพาะในคำถาม ) ฉันรู้สึกว่าอัลกอริธึมการตรวจจับวัตถุเช่น Faster-RCNNs, YOLO, SSD และอื่น ๆ จะทำให้ปัญหานี้เกิดขึ้นเมื่อเทียบกับฟีเจอร์ OpenCV ถ้าฉันจัดการปัญหานี้ตอนนี้ (หลังจาก 6 ปี !!) ฉันจะใช้Faster-RCNNแน่นอน


5
OP กล่าวว่ามีภาพความละเอียดสูง 30 ภาพซึ่งอาจไม่ใช่สถานการณ์ที่ดีที่สุดสำหรับการฝึกอบรม ConvNets ไม่เพียง แต่พวกมันจะน้อยเกินไป (เพิ่มมากขึ้น) ส่วนความละเอียดสูงจะทำลาย ConvNets
Kostas Mouratidis

11

ฉันชอบคำถามของคุณไม่ว่าหัวข้อนั้นจะอยู่นอกหรือไม่: P

ที่น่าสนใจกัน; ฉันเพิ่งจบเรื่องในระดับที่เราครอบคลุมหุ่นยนต์และคอมพิวเตอร์วิสัยทัศน์ โครงการของเราสำหรับภาคการศึกษานั้นคล้ายคลึงกับโครงการที่คุณบรรยายอย่างไม่น่าเชื่อ

เราต้องพัฒนาหุ่นยนต์ที่ใช้ Xbox Kinect เพื่อตรวจจับขวดโค้กและกระป๋องในทิศทางใด ๆ ในสภาพแสงและสภาพแวดล้อมที่หลากหลาย วิธีการแก้ปัญหาของเราเกี่ยวข้องกับการใช้ตัวกรองผ่านแถบบนช่องทางฮิวร่วมกับการแปลงรูปวงกลม เราสามารถ จำกัด สภาพแวดล้อมได้เล็กน้อย (เราสามารถเลือกตำแหน่งและวิธีการวางตำแหน่งหุ่นยนต์และเซ็นเซอร์ Kinect) ไม่เช่นนั้นเราจะใช้การแปลง SIFT หรือ SURF

คุณสามารถอ่านเกี่ยวกับวิธีการของเราในโพสต์บล็อกของฉันในหัวข้อ :)


2
โครงการที่น่าสนใจ แต่ใช้ได้กับการตั้งค่าเฉพาะของคุณเท่านั้น
Rui Marques

10

มีกลุ่มของตัวอธิบายสีที่ใช้ในการรับรู้วัตถุกระดาษด้านล่างเปรียบเทียบจำนวนมาก มันมีพลังพิเศษเมื่อรวมกับ SIFT หรือ SURF SURF หรือ SIFT เพียงอย่างเดียวไม่ได้มีประโยชน์มากในโคคาโคล่าสามารถถ่ายภาพได้เพราะพวกเขาไม่รู้จักจุดสนใจมากมายคุณต้องใช้ข้อมูลสีเพื่อช่วย ฉันใช้ BIC (Border / Classi Pixel Classi) กับ SURF ในโครงการและมันใช้งานได้ดีในการรับรู้วัตถุ

ตัวบอกสีสำหรับการค้นคืนรูปภาพบนเว็บ: การศึกษาเปรียบเทียบ


10

การเรียนรู้อย่างลึกซึ้ง

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

หากคุณไม่ได้รวบรวมชุดข้อมูลที่มีขนาดใหญ่มากให้ทำการหลอกลวงโดยใช้คุณสมบัติการเรียนรู้เชิงลึกสำหรับชุดข้อมูลขนาดเล็ก เป็นการใช้การรวมกันของ Support Vector Machines (SVM) กับอวนประสาท

เมื่อคุณป้อนรูปภาพไปยังโมเดลการเรียนรู้เชิงลึกที่ผ่านการฝึกอบรมก่อนหน้านี้ (เช่น GoogleNet) แทนที่จะใช้เลเยอร์การตัดสินใจ (ขั้นสุดท้าย) ของเครือข่ายประสาทเทียมเพื่อทำการจำแนกประเภทให้ใช้ข้อมูลของเลเยอร์ก่อนหน้า

OpenCV และ Google Net: http://docs.opencv.org/trunk/d5/de7/tutorial_dnn_googlenet.html

OpenCV และ SVM: http://docs.opencv.org/2.4/doc/tutorials/ml/introduction_to_svm/introduction_to_svm.html


9

คุณต้องการโปรแกรมที่เรียนรู้และปรับปรุงความถูกต้องในการจำแนกประเภทอย่างเป็นทางการจากประสบการณ์

ฉันจะแนะนำการเรียนรู้แบบลึกด้วยการเรียนรู้อย่างลึกซึ้งสิ่งนี้กลายเป็นปัญหาเล็กน้อย

คุณสามารถกำหนดรุ่นของการลงทะเบียน v3 ได้ที่ Tensorflow:

วิธีการชั้นสุดท้ายฝึกจัดตั้งกองทุนสำหรับหมวดหมู่ใหม่

ในกรณีนี้คุณจะได้รับการฝึกอบรมเครือข่ายประสาทเทียมในการจำแนกวัตถุเป็นโคคาโคล่าสามารถหรือไม่


2
ฮอทดอกหรือไม่ฮอทดอก
YellowPillow

6

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

มันจะมีประโยชน์ในการแยกกระป๋องเท่านั้นและสามารถใช้ร่วมกับการตรวจจับวัตถุโปร่งใส


3

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

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


0

หากคุณสนใจที่จะเป็นเรียลไทม์สิ่งที่คุณต้องการคือการเพิ่มลงในตัวกรองการประมวลผลล่วงหน้าเพื่อกำหนดสิ่งที่ได้รับการสแกนด้วยสิ่งที่หนัก ตัวกรองการประมวลผลล่วงหน้าที่ดีรวดเร็วและเป็นเวลาจริงซึ่งจะช่วยให้คุณสแกนสิ่งต่าง ๆ ที่มีแนวโน้มว่าจะเป็นโคคาโคล่ามากกว่าที่จะเป็นไปได้ก่อนที่จะย้ายไปยังสิ่งที่ไม่แน่นอนมากขึ้น ของสีที่มีความอดทนบางอย่างออกไปจากsqrt(pow(red,2) + pow(blue,2) + pow(green,2))กระป๋องโคคาโคล่าของคุณ เริ่มด้วยความทนทานต่อสีที่เข้มงวดมากและลดความคลาดเคลื่อนของสีลง จากนั้นเมื่อหุ่นยนต์ของคุณหมดเวลาที่กำหนดเพื่อดำเนินการกับเฟรมปัจจุบันมันจะใช้ขวดที่พบในปัจจุบันสำหรับวัตถุประสงค์ของคุณ โปรดทราบว่าคุณจะต้องปรับแต่งสี RGB ในsqrt(pow(red,2) + pow(blue,2) + pow(green,2))เพื่อให้ถูกต้อง

นอกจากนี้นี่คือ gona ดูเหมือนจะเป็นใบ้จริงๆ แต่คุณแน่ใจหรือไม่ว่าจะเปิดการปรับให้-oFastเหมาะสมของคอมไพเลอร์เมื่อคุณรวบรวมรหัส C ของคุณ?


0

อาจจะช้าไปหลายปี แต่ก็ยังมีทฤษฎีที่ต้องลอง

อัตราส่วนของขอบเขตสี่เหลี่ยมผืนผ้าของขอบเขตโลโก้สีแดงต่อขนาดโดยรวมของขวด / สามารถแตกต่างกัน ในกรณีของกระป๋องควรเป็น 1: 1 ในขณะที่จะแตกต่างกันในขวด (มีหรือไม่มีฝา) สิ่งนี้จะทำให้ง่ายต่อการแยกความแตกต่างระหว่างสอง

อัปเดต: ความโค้งแนวนอนของพื้นที่โลโก้จะแตกต่างกันระหว่างกระป๋องและขวดเนื่องจากขนาดแตกต่างกันไป สิ่งนี้อาจมีประโยชน์โดยเฉพาะถ้าหุ่นยนต์ของคุณต้องการหยิบกระป๋อง / ขวดและคุณตัดสินใจจับ


-1

สิ่งแรกที่ฉันจะมองคือสี - เหมือนสีแดงเมื่อทำการตรวจจับตาแดงในภาพ - มีช่วงสีที่จะตรวจจับมีลักษณะบางอย่างเกี่ยวกับเรื่องนี้พิจารณาพื้นที่โดยรอบและระยะห่างจากตาอื่นถ้ามัน เห็นได้ชัดในภาพ

1: คุณสมบัติแรกคือสีและสีแดงโดดเด่นมาก หลังจากตรวจพบ Coca Cola Red มีหลายรายการที่น่าสนใจ 1A: พื้นที่สีแดงมีขนาดใหญ่แค่ไหน (มีปริมาณเพียงพอที่จะทำการตรวจสอบความถูกต้องจริงหรือไม่ - 10 พิกเซลอาจไม่เพียงพอ) 1B: มีหรือไม่ สีของฉลาก - "Coca-Cola" หรือ wave 1B1: มีเพียงพอที่จะพิจารณาความน่าจะเป็นสูงที่จะเป็นป้ายกำกับหรือไม่

รายการที่ 1 เป็นทางลัด - ดำเนินการล่วงหน้าหากมีน้ำมูกอยู่ในภาพ - ไปต่อ

ดังนั้นหากเป็นกรณีนี้ฉันสามารถใช้ส่วนของภาพนั้นและเริ่มดูการซูมออกจากพื้นที่ที่สงสัยมากขึ้น - โดยทั่วไปดูบริเวณ / ขอบโดยรอบ ...

2: ระบุรหัสพื้นที่ภาพด้านบนเป็น 1 - ตรวจสอบจุดโดยรอบ [ขอบ] ของรายการที่เป็นปัญหา ตอบ: มีอะไรบ้างที่ดูเหมือนจะเป็นกระป๋องหรือเงิน - กระป๋อง? B: ขวดอาจดูโปร่งใส แต่อาจเป็นโต๊ะกระจก - ดังนั้นจะมีโต๊ะแก้ว / ชั้นวางหรือพื้นที่โปร่งใส - ถ้ามีหลายอย่างออกมาได้ ขวดอาจมีฝาปิดสีแดงก็อาจจะไม่ได้ แต่ควรมีรูปร่างของสกรูด้านบน / ด้ายเกลียวหรือหมวก C: แม้ว่าสิ่งนี้จะล้มเหลว A และ B ก็ยังสามารถเป็นได้ - เป็นบางส่วน .. นี่เป็นเรื่องที่ซับซ้อนมากขึ้นเมื่อมันเป็นบางส่วนเนื่องจากขวดบางส่วน / บางส่วนอาจมีลักษณะเหมือนกันดังนั้นจึงทำการประมวลผลเพิ่มเติมของการวัดขอบภูมิภาคแดง ที่ขอบขวดเล็กอาจมีขนาดใกล้เคียงกัน

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


-9

นี่เป็นโครงการเก่าที่ฉันทำงานอยู่ ภาพแผนที่ใช้งานง่ายมากด้วย javascript ฉันเสนอให้คุณคุณอ่านมันและรู้วิธีใช้มัน เราไม่ต้องการ JQuery และระบบอื่น ๆ ในการใช้อิมเมจ MAP

    //Copyright Cherif yahiaoui, by ELEBAN.FR

//variables de flottement.
var myInstOne = null;
var globalize = null;

var eleban_preload_images = function (name, imgs, url){
try{
    var oThis = this;
    this.images = new Array();
    this.imageshover = new Array();
    this.imagesNames = new Array(imgs.split(";"));


        for(var i=0; i < this.imagesNames[0].length; i++){
            this.images[i] = new Image();
            this.imageshover[i] = new Image();
        }

    this.url = url;

    this.GetAbsoluteurl = function () {

    var img = new Image(); img.src = url;
    url = img.src; img = null; 
        this.url = url; 

    };

    this.Preload = function () {

        for(var i=0; i < this.imagesNames[0].length; i++){
            this.images[i].src = this.url+("btn-"+this.imagesNames[0][i]+".png");
            this.imageshover[i].src = this.url+("btn-"+this.imagesNames[0][i]+"-hover.png");
        }

    };
    this.GetAbsoluteurl();
    this.Preload();
}
finally {return;}
}

var g_preloaderhover = new eleban_preload_images("loaderhover","menu;malette;reservation;cabine;facebook;map;amis","./images/");


//variable arret flottement
var g_stopflo = false;

var myObjfloater = function(name, idname, itop, differ ) {
var oThis = this; // création d'une référence vers l'objet courant
this.name = name;
this.id =idname;
this.xstep= 0.3;
this.itime = 30;
this.obj = null;
this.y = itop;
this.yadd = 0;
this.up = true;
this.pause = false;
this.differ = differ;
this.coordsimage = null;
this.objimg = null;
this.initimages = false;
this.compteur = 0;
this.over = false;
this.timeoutstop = null;
try{
this.initimage = function(){
var img = this.obj.getElementsByTagName('img')[0];
this.coordsimage = new Array(img.width, img.height);
this.objimg = img;
this.initimages = true;
};


this.myMethod = function() {
if(!g_stopflo){
    if(this.differ != 0){ 
this.differ=this.differ-0.1; 
}else{

if(this.obj){
if(this.over == false){
    this.yadd=this.yadd+0.1; this.itime = this.itime + 10;
this.obj.style.visibility = "hidden";
this.y = ((this.up)? this.y - this.yadd : this.y + this.yadd);
this.obj.style.marginTop = this.y +"%" ;
this.obj.style.visibility = "visible";

if (this.yadd > this.xstep){ 
    this.up = (this.up)? false : true;
    this.yadd = -0.1; this.itime=180;
}
}
}else{
    if (document){
        if(document.getElementById) {
         this.obj = document.getElementById(this.id); 
        //this.y = this.obj.offsetTop;
        }else{
        if(document.getElementByTagName) { this.obj = document.getElementByTagName(this.id); this.y = this.obj.offsetTop;}
        }

    }
}
}
this.timeoutstop=setTimeout(function() { oThis.myMethod(); }, this.itime);
}    
};

this.callDelayed = function() {
    // utilisation de la référence vers l'objet
if(!g_stopflo){
    this.timeoutstop=setTimeout(function() { oThis.myMethod(); }, this.itime);
}
};
}
finally {return;}
};

// special creation des zones AREA
function eleban_createallarea(){
try{
var measur = new Array("w", "h");
measur["w"] = new Array(330,570,185,300,115,390,225);
measur["h"] = new Array(460,570,295,450,100,190,115);
var ititle = new Array("Voir les menus  et nos suggestions","Repas &agrave; emporter","R&eacute;servation d&rsquo;une table","Nous contacter","Nous rejoindre sur FaceBook","Calculer votre trajet","liste des amis");
var ihref = new Array("menus.html","emporter.html","reservation.html","contact.html","likebox.html","google.html","amis.html");
var b_map = new Array(0,1,2,3,4,5,6);
b_map[0] = "71,32,240,32,249,43,289,352,280,366,102,385,90,371,51,38";
b_map[1] = "66,52,95,14,129,56,115,91,100,93,112,273,128,284,122,366,176,343,193,296,191,194,147,189,145,166,201,111,199,84,545,105,532,354,509,388,412,478,32,401,77,383,87,375,82,286,95,269,94,221,24,195,11,165,9,120,89,123,89,94,78,92,77,92,77,93,75,93,77,93,76,93,79,92";
b_map[2] = "19,25,169,38,173,112,161,113,105,103,90,125,91,262,121,269,124,281,96,293,62,289,49,281,56,268,83,264,84,121,71,98,16,90";
b_map[3] = "60,0,216,1,226,20,225,403,168,421,42,410,45,10";
b_map[4] = "31,7,72,10,82,18,88,45,88,71,76,81,29,80,17,68,16,18";
b_map[5] = "91,40,141,38,178,27,184,4,211,5,223,24,240,23,386,135,229,121,103,180,6,156,49,94";
b_map[6] = "6,32,69,18,79,6,118,7,141,2,149,10,211,17,202,28,209,30,189,62,195,70,178,74,180,90,164,90,154,107,68,101,34,104,34,98,18,97,28,84,15,84,30,65";

if (document.getElementById){
for (var i=0; i<b_map.length;i++){
var obj = document.getElementById("pc_menu"+i);
    if(obj){
    var ct = '<img class=\"pc_menu\" src=\"'+g_preloaderhover.images[i].src+'\" alt=\"\" width=\"'+measur["w"][i]+'\" height=\"'+measur["h"][i]+'\" usemap=\"#MAP_INDEX'+i+'\" \/>';
    ct+='<map name=\"MAP_INDEX'+i+'\">';
    ct+='<area shape=\"poly\" coords=\"'+b_map[i]+'\" title=\"'+ititle[i]+'\" href=\"'+ihref[i]+'\" \/>';
    ct+='<\/map>';
    obj.innerHTML = ct;
    }
}
}
}
finally {return;}
}

//preload, creation et gestion de tous les evenements


var image_resizer = function(g_layer){


    b_org_elm = new Array("w",  "h");
    b_org_elm["w"] = new Array(330,570,185,300,115,390,225);
    b_org_elm["h"] = new Array(460,570,295,450,100,190,115);

    b_map = new Array(0,1,2,3,4,5,6);
    b_map[0] = new Array(71,32,240,32,249,43,289,352,280,366,102,385,90,371,51,38);
    b_map[1] = new Array(66,52,95,14,129,56,115,91,100,93,112,273,128,284,122,366,176,343,193,296,191,194,147,189,145,166,201,111,199,84,545,105,532,354,509,388,412,478,32,401,77,383,87,375,82,286,95,269,94,221,24,195,11,165,9,120,89,123,89,94,78,92,77,92,77,93,75,93,77,93,76,93,79,92);
    b_map[2] = new Array(19,25,169,38,173,112,161,113,105,103,90,125,91,262,121,269,124,281,96,293,62,289,49,281,56,268,83,264,84,121,71,98,16,90);
    b_map[3] = new Array(60,0,216,1,226,20,225,403,168,421,42,410,45,10);
    b_map[4] = new Array(31,6,70,10,78,18,84,23,88,44,88,70,78,80,75,81,33,82,23,76,18,69,16,22,21,13);
    b_map[5] = new Array(91,40,141,38,178,27,184,4,211,5,223,24,240,23,386,135,229,121,103,180,6,156,49,94);
    b_map[6] = new Array(6,32,69,18,79,6,118,7,141,2,149,10,211,17,202,28,209,30,189,62,195,70,178,74,180,90,164,90,154,107,68,101,34,104,34,98,18,97,28,84,15,84,30,65);


    b_layer = g_layer;

//gere mouseover
    this.mouseover = function(e){
        if (!e) var e = window.event;
        var tg = (window.event) ? e.srcElement : e.target
            if (tg.nodeName){
                if(tg.nodeName == "AREA"){
                var divpar = (tg.parentNode)? tg.parentNode.parentNode : tg.parentElement.parentElement;
                    if (divpar){
                        if(divpar.nodeName == "DIV"){
                            var iiobjimg = divpar.getElementsByTagName('img');
                                if (iiobjimg){
                                    ii = parseInt(divpar.id.substring(divpar.id.length-1,divpar.id.length));
                                    iiobjimg[0].src = g_preloaderhover.imageshover[ii].src;
                                }
                        }
                    }
                }
            }
    };

//gere mouseout
    this.mouseout = function(e){
        if (!e) var e = window.event;
        tg = (window.event) ? e.srcElement : e.target
            if (tg.nodeName){
                if(tg.nodeName == "AREA"){
                divpar = (tg.parentNode)? tg.parentNode.parentNode : tg.parentElement.parentElement;
                    if (divpar){
                        if(divpar.nodeName == "DIV"){
                            var iiobjimg = divpar.getElementsByTagName('img');
                                if (iiobjimg){
                                    ii = parseInt(divpar.id.substring(divpar.id.length-1,divpar.id.length));
                                    iiobjimg[0].src = g_preloaderhover.images[ii].src;
                                }
                        }
                    }
                }
            }
    };

//ajout evenements entree sortie à la page web lors du chargement de la page
    this.init = function () {

        for(var i=0; i<b_org_elm["w"].length;i++){
            w = document.getElementById("pc_menu"+i).offsetWidth;
            h = document.getElementById("pc_menu"+i).offsetHeight;

            xa = w/parseFloat(b_org_elm["w"][i]);
            ya = h/parseFloat(b_org_elm["h"][i]);

            area = document.getElementById("pc_menu"+i).getElementsByTagName('area')[0];

            b_map2 = area.coords.split(",");
            yswitch = true;
                for(m=0; m<b_map2.length;m++){
                b_map2[m] = Math.round(parseFloat(b_map[i][m]) * ((yswitch)? xa: ya));
                yswitch = (yswitch)? false :  true;
                }
            area.coords = b_map2.join(',');
        }
    }; 


    this.resize = function () {
    clearTimeout(myInstOne.timeoutstop);
    g_stopflo=true;

    globalize.init();
    g_stopflo=false;
    myInstOne.obj = null;
    myInstOne.callDelayed();
    };


    nar = document.getElementsByTagName('area').length;

        for(var i=0; i<nar;i++){
            var elem = document.getElementsByTagName('area')[i];
            if (elem.addEventListener){
                    elem.addEventListener("onmouseover",this.mouseover,true);
                elem.addEventListener("onmouseout",this.mouseout,true);
            }else if (elem.attachEvent) {
                    elem.attachEvent("onmouseover", this.mouseover);
                    elem.attachEvent("onmouseout", this.mouseout);
            }else{
                    elem["onmouseover"] = this.mouseover;
                    elem["onmouseout"] = this.mouseout;
            }
        }

            window.onresize = this.resize;
        window.onmouseover = this.mouseover;
        window.onmouseout = this.mouseout;
}


//permet de temporiser et éviter les erreurs de chargement des objets
function temporise_Init(Lastdiv){
if(document.getElementById){
    if(document.getElementById(Lastdiv)){

    eleban_createallarea();

    myInstOne = new myObjfloater('b_menumap11', 'pc_menu1', 1, 0);

    globalize = new image_resizer(document.getElementById('pc_redim'));
    globalize.init();
        globalize.resize();



    }else{
    setTimeout(temporise_Init(Lastdiv), 30);
    }
}
}


window.onload = function () {
temporise_Init("pc_bandeau");
}

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