โพสต์นี้เป็นจุดเริ่มต้นของการแก้ปัญหาของฉันความคิดที่ดีมากมายที่นี่ดังนั้นฉันแม้ว่าฉันจะแบ่งปันผลลัพธ์ของฉัน ข้อมูลเชิงลึกหลักคือฉันได้พบวิธีที่จะหลีกเลี่ยงความช้าของการจับคู่ภาพที่อิงกับจุดสำคัญโดยใช้ประโยชน์จากความเร็วของ phash
สำหรับวิธีแก้ปัญหาทั่วไปควรใช้กลยุทธ์หลายวิธี อัลกอริทึมแต่ละอันเหมาะที่สุดสำหรับการแปลงภาพบางประเภทและคุณสามารถใช้ประโยชน์จากมันได้
ที่ด้านบนอัลกอริทึมที่เร็วที่สุด; ที่ด้านล่างช้าที่สุด (แต่แม่นยำยิ่งขึ้น) คุณอาจข้ามสิ่งที่ช้าหากการจับคู่ที่ดีอยู่ในระดับที่เร็วขึ้น
- file-hash based (md5, sha1, ฯลฯ ) สำหรับการทำซ้ำที่แน่นอน
- การรับรู้การแฮ็ช (phash) สำหรับภาพที่ได้รับการปรับลด
- คุณสมบัติตาม (SIFT) สำหรับภาพที่แก้ไข
ฉันมีผลลัพธ์ที่ดีมากกับ phash ความแม่นยำนั้นดีสำหรับภาพที่ได้รับการปรับสภาพ มันไม่ดีสำหรับภาพที่ถูกแก้ไข (รับรู้) (เกรียน, หมุน, ทำมิเรอร์และอื่น ๆ ) ในการจัดการกับความเร็วการแฮชเราต้องใช้แคชดิสก์ / ฐานข้อมูลเพื่อรักษาแฮชของกองหญ้า
สิ่งที่ดีจริงๆเกี่ยวกับ phash คือเมื่อคุณสร้างฐานข้อมูลแฮช (ซึ่งสำหรับฉันคือประมาณ 1,000 ภาพ / วินาที) การค้นหาอาจเร็วมากโดยเฉพาะอย่างยิ่งเมื่อคุณสามารถเก็บฐานข้อมูลแฮชทั้งหมดไว้ในหน่วยความจำ วิธีนี้ค่อนข้างใช้งานได้จริงเนื่องจากแฮชมีเพียง 8 ไบต์
ตัวอย่างเช่นหากคุณมี 1 ล้านภาพก็จะต้องใช้อาร์เรย์ค่าแฮช 64- บิต 1 ล้าน (8 MB) ในซีพียูบางตัวจะเหมาะกับ L2 / L3 cache! ในการใช้งานจริงฉันได้เห็น corei7 เปรียบเทียบที่มากกว่า 1 Giga-hamm / วินาทีมันเป็นเพียงคำถามของแบนด์วิดธ์หน่วยความจำกับ CPU ฐานข้อมูลภาพ 1 พันล้านใช้งานได้จริงบน CPU 64 บิต (จำเป็นต้องใช้ RAM 8GB) และการค้นหาจะไม่เกิน 1 วินาที!
สำหรับภาพที่ถูกปรับเปลี่ยน / ครอบตัดดูเหมือนว่าจะเป็นตัวตรวจจับคุณสมบัติ / จุดเปลี่ยนสำคัญอย่าง SIFT ซึ่งเป็นวิธีที่จะไป SIFT จะสร้างจุดสำคัญที่ดีที่จะตรวจจับการครอบตัด / หมุน / กระจกเป็นต้นอย่างไรก็ตามตัวเปรียบเทียบจะช้ามากเมื่อเทียบกับระยะการแฮ็กที่ใช้โดย phash นี่เป็นข้อ จำกัด ที่สำคัญ มีการเปรียบเทียบที่ต้องทำมากมายเนื่องจากมีตัวบ่งชี้ IxJxK สูงสุดเปรียบเทียบกับการค้นหาภาพหนึ่งภาพ (I = ภาพกองหญ้าแห้ง J, J = จุดสำคัญเป้าหมายต่อภาพกองหญ้า, K = จุดเป้าหมายต่อภาพเข็ม)
เพื่อแก้ไขปัญหาความเร็วฉันลองใช้ phash รอบแต่ละประเด็นที่พบโดยใช้ขนาด / รัศมีของคุณสมบัติเพื่อกำหนดสี่เหลี่ยมผืนผ้าย่อย เคล็ดลับในการทำให้การทำงานเป็นไปด้วยดีนี้คือการเพิ่ม / ลดขนาดรัศมีเพื่อสร้างระดับ sub-rect ที่แตกต่างกัน (ในรูปเข็ม) โดยทั่วไปแล้วระดับแรก (ไม่ปรับสัดส่วน) จะจับคู่ แต่บ่อยครั้งจะใช้เวลาเพิ่มขึ้นเล็กน้อย ฉันไม่แน่ใจ 100% ว่าทำไมสิ่งนี้ถึงใช้ได้ แต่ฉันสามารถจินตนาการได้ว่ามันเปิดใช้งานฟีเจอร์ที่เล็กเกินกว่าที่ phash จะทำงานได้ (phash ลดขนาดภาพลงเหลือ 32x32)
ปัญหาอื่นคือ SIFT จะไม่กระจายจุดสำคัญอย่างเหมาะสม หากมีส่วนของภาพที่มีขอบจำนวนมากจุดสำคัญจะจับกลุ่มที่นั่นและคุณจะไม่ได้รับสิ่งใดในบริเวณอื่น ฉันใช้ GridAdaptedFeatureDetector ใน OpenCV เพื่อปรับปรุงการกระจาย ไม่แน่ใจว่าขนาดกริดที่ดีที่สุดคืออะไรฉันใช้กริดขนาดเล็ก (1x3 หรือ 3x1 ขึ้นอยู่กับการวางแนวของภาพ)
คุณอาจต้องการปรับขนาดภาพหญ้าแห้ง (และเข็ม) ให้มีขนาดเล็กลงก่อนที่จะทำการตรวจจับคุณสมบัติ (ฉันใช้ 210px ตามขนาดสูงสุด) สิ่งนี้จะช่วยลดจุดรบกวนในภาพ (มักเป็นปัญหาสำหรับอัลกอริธึมการมองเห็นของคอมพิวเตอร์) และจะเน้นการตรวจจับด้วยคุณสมบัติที่โดดเด่น
สำหรับรูปภาพของบุคคลคุณอาจลองใช้การตรวจจับใบหน้าและใช้เพื่อกำหนดขนาดภาพที่จะขยายและขนาดกริด (ตัวอย่างเช่นปรับขนาดใบหน้าที่ใหญ่ที่สุดให้เป็น 100px) ตัวตรวจจับคุณสมบัตินั้นมีหลายระดับ (โดยใช้ปิรามิด) แต่มีข้อ จำกัด ว่าจะใช้กี่ระดับ (แน่นอนว่าสามารถปรับได้)
เครื่องตรวจจับ keypoint นั้นทำงานได้ดีที่สุดเมื่อมันกลับมาน้อยกว่าจำนวนคุณสมบัติที่คุณต้องการ ตัวอย่างเช่นถ้าคุณขอ 400 และได้รับ 300 คืนมันก็ดี หากคุณได้รับคืน 400 ทุกครั้งอาจต้องมีฟีเจอร์ที่ดีบางอย่างออกมา
ภาพเข็มสามารถมีประเด็นสำคัญน้อยกว่าภาพที่กองหญ้าและยังได้ผลลัพธ์ที่ดี การเพิ่มมากขึ้นไม่จำเป็นต้องทำให้คุณได้กำไรมากเช่น J = 400 และ K = 40 อัตราการตีของฉันอยู่ที่ประมาณ 92% ด้วย J = 400 และ K = 400 อัตราการเข้าชมจะสูงถึง 96% เท่านั้น
เราสามารถใช้ประโยชน์จากความเร็วสูงสุดของฟังก์ชัน hamming เพื่อแก้ปัญหาการสเกลการหมุนการมิเรอร์และอื่น ๆ สามารถใช้เทคนิคแบบหลายพาสได้ ในการวนซ้ำแต่ละครั้งให้แปลงสี่เหลี่ยมผืนผ้าย่อยการแฮชอีกครั้งและเรียกใช้ฟังก์ชันการค้นหาอีกครั้ง