Bu yazı benim çözümümün başlangıç noktasıydı, burada birçok iyi fikir vardı, bu yüzden sonuçlarımı paylaşacaktım. Ana fikir, phash hızını kullanarak anahtar nokta tabanlı görüntü eşleşmesinin yavaşlığını aşmanın bir yolunu buldum.
Genel çözüm için birkaç strateji uygulamak en iyisidir. Her algoritma belirli görüntü dönüştürme türleri için en uygunudur ve bundan yararlanabilirsiniz.
Üstte en hızlı algoritmalar; en yavaş (daha doğru olsa da). Daha hızlı seviyede iyi bir eşleşme bulunursa yavaş olanları atlayabilirsiniz.
- kesin kopyalar için dosya karması tabanlı (md5, sha1 vb.)
- yeniden ölçeklendirilmiş görüntüler için algısal karma (phash)
- değiştirilmiş görüntüler için özellik tabanlı (SIFT)
Phash ile çok iyi sonuçlar alıyorum. Hassasiyet, yeniden ölçeklendirilmiş görüntüler için iyidir. Değiştirilmiş (algısal olarak) görüntüler (kırpılmış, döndürülmüş, yansıtılmış vb.) İçin iyi değildir. Karma hızıyla başa çıkmak için samanlık karmasını korumak için bir disk önbelleği / veritabanı kullanmalıyız.
Phash ile ilgili gerçekten güzel bir şey, karma veritabanınızı oluşturduktan sonra (ki benim için yaklaşık 1000 resim / sn'dir), aramalar çok, çok hızlı olabilir, özellikle de tüm karma veritabanını bellekte tutabildiğinizde. Bir karma sadece 8 bayt olduğu için bu oldukça pratiktir.
Örneğin, 1 milyon görüntünüz varsa, 1 milyon 64 bit karma değerleri (8 MB) dizisini gerektirir. Bazı CPU'larda bu L2 / L3 önbelleğine sığar! Pratik kullanımda 1 Giga-hamm / sn üzerinde bir corei7 karşılaştırması gördüm, bu sadece CPU için bir bellek bant genişliği sorunudur. 64 milyar CPU (8 GB RAM gerekir) için 1 Milyar görüntü veritabanı pratiktir ve aramalar 1 saniyeyi geçmez!
Değiştirilmiş / kırpılmış görüntüler için SIFT gibi bir dönüşüm-değişmez özellik / anahtar nokta dedektörü gibi görünmektedir. SIFT, kırpma / döndürme / ayna vb. Tespit edecek iyi anahtar noktaları üretecektir. Ancak tanımlayıcı karşılaştırması, phash tarafından kullanılan çekiçleme mesafesine kıyasla çok yavaştır. Bu büyük bir sınırlamadır. Maksimum IxJxK tanımlayıcı bir görüntüyü aramakla karşılaştırıldığı için çok fazla karşılaştırma vardır (I = num haystack görüntüleri, J = samanlık görüntüsü başına hedef anahtar noktaları, K = iğne görüntüsü başına hedef anahtar noktaları).
Hız sorununu aşmak için, bulunan her anahtar noktanın çevresinde phash kullanmayı, alt dikdörtgeni belirlemek için özellik boyutunu / yarıçapını kullanarak denedim. Bunu iyi yapmanın hilesi, farklı alt rekt seviyeleri (iğne görüntüsünde) oluşturmak için yarıçapı büyütmek / küçültmektir. Genellikle ilk seviye (ölçeklendirilmemiş) eşleşir, ancak genellikle birkaç tane daha alır. Bunun neden çalıştığından% 100 emin değilim, ancak phash'ın çalışması için çok küçük özelliklerin etkinleştirildiğini hayal edebiliyorum (phash görüntüleri 32x32'ye kadar ölçeklendirir).
Başka bir sorun, SIFT'in kilit noktaları en iyi şekilde dağıtmayacağıdır. Görüntünün çok fazla kenarı olan bir bölümü varsa, anahtar noktaları orada kümelenir ve başka bir alanda elde edemezsiniz. Dağıtım geliştirmek için OpenCV GridAdaptedFeatureDetector kullanıyorum. Hangi ızgara boyutunun en iyi olduğundan emin değilim, küçük bir ızgara kullanıyorum (görüntü yönüne bağlı olarak 1x3 veya 3x1).
Özellik saptama işleminden önce muhtemelen tüm samanlık görüntülerini (ve iğneyi) daha küçük bir boyuta ölçeklemek istersiniz (maksimum boyut boyunca 210 piksel kullanıyorum). Bu, görüntüdeki gürültüyü azaltacaktır (bilgisayar görme algoritmaları için her zaman bir sorun), ayrıca dedektörü daha belirgin özelliklere odaklayacaktır.
İnsanların görüntüleri için yüz algılamayı deneyebilir ve ölçeklendirilecek görüntü boyutunu ve ızgara boyutunu (örneğin 100 piksel olacak şekilde ölçeklendirilmiş en büyük yüz) belirlemek için kullanabilirsiniz. Özellik dedektörü çoklu ölçek seviyelerini (piramitleri kullanarak) açıklar, ancak kaç seviye kullanacağı konusunda bir sınırlama vardır (bu elbette ayarlanabilir).
Önemli nokta dedektörü, muhtemelen istediğiniz özellik sayısından daha azını döndürdüğünde en iyi şekilde çalışır. Örneğin, 400 ister ve 300 geri alırsanız, bu iyi. Her seferinde 400 tane geri alırsanız, muhtemelen bazı iyi özelliklerin dışarıda bırakılması gerekiyordu.
İğne görüntüsünün samanlıkta görüntülerden daha az anahtar noktası olabilir ve yine de iyi sonuçlar alabilirsiniz. Daha fazlasını eklemek size büyük kazançlar sağlamaz, örneğin J = 400 ve K = 40 ile isabet oranım yaklaşık% 92'dir. J = 400 ve K = 400 ile isabet oranı sadece% 96'ya kadar çıkıyor.
Ölçekleme, döndürme, aynalama vb. Çözmek için çekiçleme fonksiyonunun aşırı hızından yararlanabiliriz. Çok geçişli bir teknik kullanılabilir. Her bir yinelemede, alt dikdörtgenleri dönüştürün, yeniden karıklayın ve arama işlevini tekrar çalıştırın.