2013-10-30 30 views
6

iPad'im tarafından yakalanan resimlerde belirteçler tespit ediyorum. Bu yüzden aralarındaki çevirileri ve rotasyonları hesaplamak istiyorum, bu imgede görüntülerdeki değişim perspektifini değiştirmek istiyorum, bu yüzden onları doğrudan işaretleyicilerin üzerinde yakaladım.OpenCV: wrapPerspective tüm görüntü için

photo 1 photo 2 photo 3

As: Sağ şimdi benim bu sonuçlar (warpPerspective sonucunu sağ alt köşesinde bakmak) verir

points2D.push_back(cv::Point2f(0, 0)); 
points2D.push_back(cv::Point2f(50, 0)); 
points2D.push_back(cv::Point2f(50, 50)); 
points2D.push_back(cv::Point2f(0, 50)); 

Mat perspectiveMat = cv::getPerspectiveTransform(points2D, imagePoints); 
cv::warpPerspective(*_image, *_undistortedImage, M, cv::Size(_image->cols, _image->rows)); 

kullanıyorum

Muhtemelen sonuç görüntüsünün, sonuç resminin sol üst köşesinde tanınmış işaretçi içerdiğini görürsünüz. Benim sorunum, tüm görüntüyü (kırpmadan) yakalamak istediğimden, o görüntüdeki diğer işaretleyicileri daha sonra algılayabilmem.

Bunu nasıl yapabilirim? Belki solvePnP işlevinden döndürme/çeviri vektörleri kullanmalıyım?

DÜZENLEME:

Maalesef görüntü hala çok işaretleyici sol üst köşesi resmin sol üst köşesinde olduğu çevrilmiştir çünkü çarpık görüntünün boyutu, çok yardımcı olmamaktadır değişen. böylece,

photo 4 photo 5

cevap

3

Kodunuz tamamlanmış görünmüyor:

cv::warpPerspective(*_image, *_undistortedImage, M, cv::Size(2*_image->cols, 2*_image->rows)); 

Ben bu görüntüleri alınan ettik:

Mesela ben kullanarak boyutunu iki katına zaman sorunun ne olduğunu söylemek zor.

Her durumda, çarpık görüntünün giriş görüntüsüyle karşılaştırıldığında tamamen farklı boyutları olabilir, bu nedenle warpPerspective için kullandığınız boyut parametresini ayarlamanız gerekir.

Örneğin boyutunu iki katına deneyin:

cv::warpPerspective(*_image, *_undistortedImage, M, 2*cv::Size(_image->cols, _image->rows)); 

Düzenleme:

Görüntünün tamamı bu görüntünün içinde olduğundan emin olmak için, orijinal görüntünün tüm köşeleri çıkan içinde olmak çarpık olmalıdır görüntüsü. Bu nedenle, köşe noktalarının her biri için çarpık hedefi hesaplayın ve buna göre hedef noktaları ayarlayın.

daha bazı örnek kod temizlemek yapmak için:

// calculate transformation 
cv::Matx33f M = cv::getPerspectiveTransform(points2D, imagePoints); 

// calculate warped position of all corners 

cv::Point3f a = M.inv() * cv::Point3f(0, 0, 1); 
a = a * (1.0/a.z); 

cv::Point3f b = M.inv() * cv::Point3f(0, _image->rows, 1); 
b = b * (1.0/b.z); 

cv::Point3f c = M.inv() * cv::Point3f(_image->cols, _image->rows, 1); 
c = c * (1.0/c.z); 

cv::Point3f d = M.inv() * cv::Point3f(_image->cols, 0, 1); 
d = d * (1.0/d.z); 

// to make sure all corners are in the image, every position must be > (0, 0) 
float x = ceil(abs(min(min(a.x, b.x), min(c.x, d.x)))); 
float y = ceil(abs(min(min(a.y, b.y), min(c.y, d.y)))); 

// and also < (width, height) 
float width = ceil(abs(max(max(a.x, b.x), max(c.x, d.x)))) + x; 
float height = ceil(abs(max(max(a.y, b.y), max(c.y, d.y)))) + y; 

// adjust target points accordingly 
for (int i=0; i<4; i++) { 
    points2D[i] += cv::Point2f(x,y); 
} 

// recalculate transformation 
M = cv::getPerspectiveTransform(points2D, imagePoints); 

// get result 
cv::Mat result; 
cv::warpPerspective(*_image, result, M, cv::Size(width, height), cv::WARP_INVERSE_MAP); 
+0

Ben çıkış görüntü farklı dimenstions sahip olabileceğini biliyorum, (sonuçlar için düzenlenmiş soruya bak) onları iki katına ile denedim, ama etmedi bana yararlı sonuçlar verdi. Kodumun eksik olduğunu söylüyorsunuz - ne eklemeliyim? Dönüşüm matrisi elde etmek için 'getPerspectiveTransform' kullanıyorum ve 'dst' matrisi olarak tespit edilen işaretleyici köşelerinin koordinatlarını kullanıyorum (OpenCV belgelerine göre - http://docs.opencv.org/modules/imgproc /doc/geometric_transformations.html#getperspectivetransform). – Axadiw

+0

Sanırım (-6, -6) vb. Hedef koordinatlarınız biraz garip. Çünkü bu, hedef dikdörtgeninizin ortaya çıkan görüntüdeki bu koordinatlarda olacağı anlamına gelir. Onları hareket ettirmek için hedef dikdörtgeni sadece hedef görüntünün ortasına taşıyın. – littleimp

+0

Teşekkürler - Yanlış point2D dizisi gönderdiğimi anladım (şu anda soruda düzenledim). Bu noktaları kaydırmak, çıktı görüntüsünün tamamını biraz hareket ettirdi, ancak yine de bazı kısımlarını kırpıyorum. – Axadiw