Özellikle 2000 noktaya kadar işlem yapmak istiyorsanız, bu her zaman çok fazla hesaplama gerektirecektir. Eminim zaten bu tür desen eşleştirme için son derece optimize edilmiş çözümler vardır, ancak bunları bulmak için ne denildiğini bulmanız gerekir.
Bir görüntü yerine bir nokta bulutu (seyrek veriler) hakkında konuştuğunuz için, çapraz korelasyon yöntemim gerçekten geçerli değil (ve hesaplama açısından daha da kötü olurdu). RANSAC gibi bir şey muhtemelen çabucak bir eşleşme bulur, ancak bu konuda fazla bir şey bilmiyorum.
Bir çözüm denemem:
Varsayımlar:
- Sadece gevşek veya "muhtemelen doğru" bir eşleşme değil, en iyi eşleşmeyi bulmak istiyorsunuz
- Maç, ölçüm veya hesaplamadaki gürültü nedeniyle küçük bir miktar hataya sahip olacak
- Kaynak noktaları eş düzlemlidir
- Tüm kaynak noktaları hedefte bulunmalıdır (= eşleşmeyen herhangi bir nokta profilin tamamı için bir uyumsuzluktur)
Bu nedenle, şeyleri diskalifiye ederek ve hesaplama süresini azaltarak birçok kısayol alabilmelisiniz. Kısacası:
- kaynaktan üç puan seç
- aynı şekle sahip 3 nokta kümesini bularak hedef noktalarda arama yapın
- 3 puanlık bir eşleşme bulunduğunda, yakın bir eşleşme olup olmadığını görmek için düzlemdeki tanımladıkları diğer tüm noktaları kontrol edin
- tüm noktaların birden fazla eşleşmesi bulunursa, en az 3B uzaklık hatası toplamı olanı seçin
Daha ayrıntılı:
pick a point from the source for testing s1 = (x1, y1)
Find nearest point in source s2 = (x2, y2)
d12 = (x1-x2)^2 + (y1-y2)^2
Find second nearest point in source s3 = (x3, y3)
d13 = (x1-x3)^2 + (y1-y3)^2
d23 = (x2-x3)^2 + (y2-y3)^2
for all (x,y,z) test points t1 in target:
# imagine s1 and t1 are coincident
for all other points t2 in target:
if distance from test point > d12:
break out of loop and try another t2 point
if distance ≈ d12:
# imagine source is now rotated so that s1 and s2 are collinear with t1 and t2
for all other points t3 in target:
if distance from t1 > d13 or from t2 > d23:
break and try another t3
if distance from t1 ≈ d13 and from t2 ≈ d23:
# Now you've found matching triangles in source and target
# align source so that s1, s2, s3 are coplanar with t1, t2, t3
project all source points onto this target plane
for all other points in source:
find nearest point in target
measure distance from source point to target point
if it's not within a threshold:
break and try a new t3
else:
sum errors of all matched points for this configuration (defined by t1, t2, t3)
Diğer tüm noktalar için hangi yapılandırma en az kare hatasına sahip olursa olsun en iyi eşleşme
En yakın 3 komşu test noktasıyla çalıştığımızdan, eşleme hedef noktaları bir miktar yarıçap içinde olup olmadıklarını kontrol ederek basitleştirilebilir. Örneğin, (0, 0) 'dan 1 yarıçapı arıyorsanız, biraz hızlandırmak için gerçek Öklid mesafesini hesaplamadan x1 - x2'ye dayalı olarak diskalifiye edebiliriz (2, 0). Bu, çıkarma işleminin çarpma işleminden daha hızlı olduğunu varsayar. Orada daha keyfi sabit yarıçaplı göre optimize aramalar da.
function is_closer_than(x1, y1, z1, x2, y2, z2, distance):
if abs(x1 - x2) or abs(y1 - y2) or abs(z1 - z2) > distance:
return False
return (x1 - x2)^2 + (y1 - y2)^2 + (z1 - z2)^2 > distance^2 # sqrt is slow
d= ( x1- x2)2+ ( y1- y2)2+ ( z1- z2)2----------------------------√
Minimum hesaplama süresi, 2 puanlı eşleşme bulunamazsa olur. Hedefte 2000 puan varsa, bu 2000 * 2000 mesafe hesaplamaları olacaktır, ancak birçoğu bir çıkarma ile diskalifiye edilir ve önceki hesaplamaların sonuçları saklanabilir, böylece sadece select = 1,999,000'i gerekir.( 20002)
Aslında, maçları bulsanız da bulmasanız da, bunların hepsini hesaplamanız gerekeceğinden ve bu adım için yalnızca en yakın komşuları önemsediğiniz için, belleğiniz varsa, bu değerleri optimize edilmiş bir algoritma kullanarak önceden hesaplamak daha iyidir . Delaunay veya Pitteway üçgenlemesi gibi bir şey , hedefteki her noktanın en yakın komşularına bağlı olduğu. Bunları bir tabloda saklayın, ardından kaynak üçgeni hedef üçgenlerden birine takmaya çalışırken her noktaya bakın.
Çok fazla hesaplama var, ancak hacimsel verilerin çapraz korelasyonu gibi birçok anlamsız sıfırın bir araya getirilmesi yerine, sadece seyrek olan veriler üzerinde çalıştığı için nispeten hızlı olmalıdır. İlk olarak noktaların merkezlerini bulduysanız ve bunları bir koordinat kümesi olarak sakladıysanız, aynı fikir 2B durum için de işe yarar.