2015-08-26 19 views
65

Uzayda birçok noktanın 3D koordinatlarını almaya çalışıyorum, ancak hem undistortPoints() hem de triangulatePoints()'dan tek sonuçlar alıyorum. Her iki kameralar farklı çözünürlük olduğundan, ben bunları ayrı ayrı kalibre ettikOpenCV undistortPuanlar ve triangulatePoint garip sonuçlar verir (stereo)

ardından, 0,34 ve 0,43 RMS hataları var daha matrisleri elde etmek stereoCalibrate() kullanılan 0,708 bir RMS var ve ardından kalan matrisleri elde etmek stereoRectify() kullandı. Elimizdeki koordinatlarla çalışmaya başladım ama garip sonuçlar elde ediyorum. (935, 262) ve başka için sırasıyla (934, 176) ve (1227.9016, 292.4686) iken undistortPoints() çıkışı, tek bir nokta için (1228.709125, 342.79841) olup:

Örneğin, girişidir. Bu garip, çünkü bu noktaların her ikisi de çerçevenin ortasına çok yakın, çarpıklıkların en küçüğü. Onları 300 piksele taşımasını beklemiyordum.

traingulatePoints()'a geçtiğinde, sonuçlar daha da yabancı oluyor - Gerçek hayatta üç nokta arasındaki mesafeyi (bir cetvelle) ölçtüm ve her resimde pikseller arasındaki mesafeyi hesapladım. Çünkü bu sefer noktalar oldukça düz bir düzlemdeydi, bu iki uzunluk (piksel ve gerçek), | AB |/| BC | her iki durumda da 4/9 civarındaydı. Ancak, triangulatePoints() bana raylardan, | AB |/| BC | 3/2 veya 4/2'dir. noktaları arasındaki

double pointsBok[2] = { bokList[j].toFloat()+xBok/2, bokList[j+1].toFloat()+yBok/2 }; 
cv::Mat imgPointsBokProper = cv::Mat(1,1, CV_64FC2, pointsBok); 

double pointsTyl[2] = { tylList[j].toFloat()+xTyl/2, tylList[j+1].toFloat()+yTyl/2 }; 
//cv::Mat imgPointsTyl = cv::Mat(2,1, CV_64FC1, pointsTyl); 
cv::Mat imgPointsTylProper = cv::Mat(1,1, CV_64FC2, pointsTyl); 

cv::undistortPoints(imgPointsBokProper, imgPointsBokProper, 
     intrinsicOne, distCoeffsOne, R1, P1); 
cv::undistortPoints(imgPointsTylProper, imgPointsTylProper, 
     intrinsicTwo, distCoeffsTwo, R2, P2); 

cv::triangulatePoints(P1, P2, imgWutBok, imgWutTyl, point4D); 

double wResult = point4D.at<double>(3,0); 
double realX = point4D.at<double>(0,0)/wResult; 
double realY = point4D.at<double>(1,0)/wResult; 
double realZ = point4D.at<double>(2,0)/wResult; 

açıları tür sorta iyi ama genellikle:

`7,16816 168,389 4,44275` vs `5,85232 170,422 3,72561` (degrees) 
`8,44743 166,835 4,71715` vs `12,4064 158,132 9,46158` 
`9,34182 165,388 5,26994` vs `19,0785 150,883 10,0389` 

Ben tüm çerçeve üzerinde undistort() kullanmaya çalıştı, ancak sonuç var

Bu

benim kodudur Sadece garip. B ve C noktaları arasındaki mesafe her zaman hemen hemen değişmeden olmalı ve henüz bu ne alıyorum: kare

7502,42  
4876,46 
3230,13 
2740,67 
2239,95 

Frame. Gerçek mesafe (üst) vs

Piksel mesafesi (alt) - çok benzer olmalıdır: |BC| distance

Açısı:

da ABC angle

, hem undistortPoints() ve undistort() aynı vermemelidir sonuçlar (burada başka bir video seti)?

+0

Kalibrasyon için kullandığınız kodu ve üçgenleme parçası için bazı örnek görüntüleri ekleyebilir misiniz? – AldurDisciple

+0

Bu zor olabilir ... bir sürü var. Yarın sadece ilgili parçaları yayınlamaya çalışacağım – Petersaber

+0

Bu, karmaşık bir kalibrasyona benziyor - bir kamerada (distorsiyonu görmezden geliyorsanız) 'undistort' (stereo kalibrasyon yok sayılıyorsa) çalışıyor mu? Her kameranın içsel özelliklerini ayrı ayrı kalibre edebilmeli ve bunların tamam olduklarından emin olmalısınız ve daha sonra bu değerleri 'CV_CALIB_USE_INTRINSIC_GUESS' işaretini kullanarak ilk tahmin olarak stereo kalibrasyona geçirmelisiniz. – abarry

cevap

1

cv :: undistort işlevi tek seferde bozulma ve yeniden çoğaltma işlevini yerine getirir.

  1. geri kamera çıkıntısı (kamera matrisinin tersinden çarpma)
  2. bozulmasını engelleyerek sağlanır rotasyon matrisi R1/R2 ile
  3. döndürme geri almak için distorsiyon modeli uygulanır: Bu, aşağıdaki işlem listesi vardır Resim Projeksiyon matris P1 aracılığıyla görüntü
  4. proje noktaları/Eğer matrisler, R1, P1 resp başarılı olursa P2

. Cv :: stereoCalibrate() 'dan R2, P2, giriş noktaları bozulmamış ve düzeltilecektir. Düzeltme, görüntülerin karşılık gelen noktaların aynı y koordinatına sahip olacak şekilde dönüştürüldüğü anlamına gelir. Görüntülerin düzeltilmesi için benzersiz bir çözüm yoktur, çünkü her iki görüntüye de karşılık gelen noktaların hizalamasını değiştirmeden herhangi bir çeviri veya ölçekleme uygulayabilirsiniz. Yani, cv :: stereoCalibrate() projeksiyon merkezinin yerini biraz değiştirebilir (ör. 300 piksel). Saf bozulmayı istiyorsanız, bir Kimlik Matrisini (R1 yerine) ve orijinal fotoğraf makinesi Matrix K'yi (P1 yerine) geçirebilirsiniz. Bu, orijinal olanlara benzer piksel koordinatlarına yol açmalıdır.

İlgili konular