2013-05-19 31 views
10

Tôi đang cố gắng tính toán vị trí máy ảnh mới dựa trên chuyển động của hình ảnh tương ứng. các hình ảnh phù hợp với mô hình máy ảnh pinhole.Chuyển động camera từ hình ảnh tương ứng

Thực ra, tôi không nhận được kết quả hữu ích, vì vậy tôi cố gắng mô tả quy trình của mình và hy vọng rằng ai đó có thể giúp tôi.

Tôi khớp các tính năng của hình ảnh tương ứng với SIFT, khớp chúng với FlannBasedMatcher của OpenCV và tính ma trận cơ bản với hàm findFundamentalMat của OpenCV (phương thức RANSAC).

Sau đó, tôi tính toán ma trận cần thiết bởi máy ảnh ma trận nội tại (K):

Mat E = K.t() * F * K; 

tôi phân hủy ma trận cần thiết để luân chuyển và dịch với số ít phân hủy giá trị:

SVD decomp = SVD(E); 
Matx33d W(0,-1,0, 
      1,0,0, 
      0,0,1); 
Matx33d Wt(0,1,0, 
      -1,0,0, 
      0,0,1); 
R1 = decomp.u * Mat(W) * decomp.vt; 
R2 = decomp.u * Mat(Wt) * decomp.vt; 
t1 = decomp.u.col(2); //u3 
t2 = -decomp.u.col(2); //u3 

Sau đó, tôi cố gắng để tìm ra giải pháp đúng bằng cách triangulation. (phần này là từ http://www.morethantechnical.com/2012/01/04/simple-triangulation-with-opencv-from-harley-zisserman-w-code/ vì vậy tôi nghĩ rằng nên làm việc chính xác).

Vị trí mới thì được tính bằng:

new_pos = old_pos + -R.t()*t; 

nơi new_pos & old_pos là vectơ (3x1), R ma trận xoay (3x3) và t vector dịch (3x1).

Thật không may là tôi không có kết quả hữu ích, vì vậy có thể ai đó có ý tưởng gì có thể sai.

Dưới đây là một số kết quả (chỉ trong trường hợp ai đó có thể khẳng định rằng bất kỳ trong số họ chắc chắn là sai):

F = [8.093827077399547e-07, 1.102681999632987e-06, -0.0007939604310854831; 
    1.29246107737264e-06, 1.492629957878578e-06, -0.001211264339006535; 
    -0.001052930954975217, -0.001278667878010564, 1] 

K = [150, 0, 300; 
    0, 150, 400; 
    0, 0, 1] 

E = [0.01821111092414898, 0.02481034499174221, -0.01651092283654529; 
    0.02908037424088439, 0.03358417405226801, -0.03397110489649674; 
    -0.04396975675562629, -0.05262169424538553, 0.04904210357279387] 

t = [0.2970648246214448; 0.7352053067682792; 0.6092828956013705] 

R = [0.2048034356172475, 0.4709818957303019, -0.858039396912323; 
    -0.8690270040802598, -0.3158728880490416, -0.3808101689488421; 
    -0.4503860776474556, 0.8236506374002566, 0.3446041331317597] 
+1

Có thêm một lỗi trong tính toán của bạn. 'SVD decomp = SVD (E);' là ok nhưng bạn phải tính toán một 'newE = U * diag (1,1,0) * Vt' và sau đó một lần nữa bạn phải có' SVD decomp2 = SVD (newE) ; '. – who9vy

+0

thú vị. Tôi chưa bao giờ đọc về điều đó. Vì vậy, tôi đã làm tính toán R và t với decomp2? btw: cảm ơn câu trả lời chi tiết của bạn. Tôi phải kiểm tra tất cả mọi thứ và sẽ trả lời càng sớm càng tốt. – 3x14159265

+0

Có, bạn phải tính toán R và t với decomp2. Một mô tả chi tiết được đưa ra ở đây (trang 257-260) http://www.robots.ox.ac.uk/~vgg/hzbook/hzbook2/HZepipolar.pdf – who9vy

Trả lời

10

Trước hết bạn nên kiểm tra nếu

x' * F * x = 0 

cho thư từ quan điểm của bạn x'x. Điều này nên tất nhiên chỉ là trường hợp cho các nội tuyến của ước lượng ma trận cơ bản với RANSAC.

Sau đó, bạn phải chuyển đổi thư từ quan điểm của bạn để tọa độ hình ảnh bình thường (NCC) như thế này

xn = inv(K) * x 
xn' = inv(K') * x' 

nơi K' là ma trận camera nội tại của hình ảnh thứ hai và x' là những điểm của bức ảnh thứ hai. Tôi nghĩ trong trường hợp của bạn là K = K'.

Với các NCC này, bạn có thể phân hủy ma trận thiết yếu như mô tả. Bạn triangulate tọa độ camera bình thường và kiểm tra độ sâu của các điểm tam giác của bạn. Nhưng hãy cẩn thận, trong văn học, họ nói rằng một điểm là đủ để có được phép quay và dịch đúng. Từ kinh nghiệm của tôi, bạn nên kiểm tra một vài điểm vì một điểm có thể là một ngoại lệ ngay cả sau RANSAC.

Trước khi bạn phân hủy ma trận thiết yếu, hãy đảm bảo rằng E=U*diag(1,1,0)*Vt. Điều kiện này là cần thiết để có được kết quả chính xác cho bốn lựa chọn có thể có của ma trận chiếu.

Khi bạn đã có phép quay và dịch đúng, bạn có thể triangulate tất cả các điểm tương ứng của bạn (các giá trị của ước tính ma trận cơ bản với RANSAC). Sau đó, bạn nên tính toán reprojection error. Trước tiên, bạn tính toán vị trí bị từ chối như thế này

xp = K * P * X 
xp' = K' * P' * X 

trong đó X là vị trí 3D được tính toán (đồng nhất). PP' là các ma trận chiếu 3x4. Ma trận chiếu P thường được đưa ra bởi danh tính. P' = [R, t] được đưa ra bởi ma trận xoay trong 3 cột và hàng đầu tiên và bản dịch trong cột thứ tư, sao cho P là ma trận 3x4. Điều này chỉ hoạt động nếu bạn chuyển đổi vị trí 3D của mình thành homogeneous coordinates, tức là các vector 4x1 thay vì 3x1. Sau đó, xpxp' cũng là tọa độ đồng nhất đại diện cho vị trí 2D (được chiếu lại) của các điểm tương ứng của bạn.

Tôi nghĩ rằng

new_pos = old_pos + -R.t()*t; 

là không chính xác bởi vì trước hết, bạn chỉ dịch old_pos và bạn không xoay nó và thứ hai, bạn dịch nó với một vector sai. Cách chính xác được đưa ra ở trên.

Vì vậy, sau khi bạn tính các điểm được chiếu lại, bạn có thể tính toán lỗi tái phát. Vì bạn đang làm việc với các tọa độ đồng nhất, bạn phải chuẩn hóa chúng (xp = xp/xp(2), chia cho tọa độ cuối cùng). Điều này được đưa ra bởi

error = (x(0)-xp(0))^2 + (x(1)-xp(1))^2 

Nếu lỗi lớn như 10^2 hiệu chỉnh máy ảnh nội tại hoặc xoay/dịch không chính xác (có thể cả hai). Tùy thuộc vào hệ tọa độ của bạn, bạn có thể thử đảo ngược ma trận chiếu của mình. Trên tài khoản đó, bạn cần chuyển đổi chúng thành các tọa độ đồng nhất trước khi bạn không thể đảo ngược ma trận 3x4 (không có nghịch đảo giả). Do đó, thêm hàng thứ tư [0 0 0 1], tính toán nghịch đảo và loại bỏ hàng thứ tư.

Có một điều nữa với lỗi tái phát. Nói chung, lỗi tái phát là khoảng cách bình phương giữa tương ứng điểm gốc của bạn (trong mỗi hình ảnh) và vị trí được chiếu lại. Bạn có thể lấy căn bậc hai để lấy khoảng cách Euclide giữa hai điểm.

+0

là phương trình 'x '* F * x = 0' trong thực tế chính xác 0, quá? các giá trị như 1.12345 * e^-14 vẫn tốt? Tôi có đúng là tôi có thể loại bỏ tất cả các ngoại lệ trước khi tính toán NCC không? – 3x14159265

+0

Tôi đã thử những điều bạn mô tả và kết thúc bằng ma trận chiếu. lỗi tái phát là <10^2. nhưng những gì tôi không nhận được là làm thế nào để di chuyển vị trí máy ảnh trong tọa độ thế giới.Tôi muốn tính toán theo hướng nào (x, y, z) camera di chuyển. Tôi nghĩ rằng điều này được thực hiện bởi 'new_pos = old_pos + -R.t() * t;'. kể từ khi bạn nói đó là sai, bạn có biết làm thế nào tôi có thể làm điều đó với ma trận chiếu? – 3x14159265

+2

Một camera nằm trong '(0, 0, 0)' và một camera khác nằm trong 't'. Hơn nữa, camera thứ hai được quay bởi 'R'. Ma trận 'P' (được gọi là ma trận chiếu) được tạo thành từ' R' và 't'is chuyển đổi cơ thể cứng nhắc chuyển đổi mỗi điểm 3D' p' từ hệ tọa độ được biểu diễn bằng ma trận nhận dạng thành hệ tọa độ được biểu diễn bằng 'P' . Phép biến đổi được thực hiện bởi 'newp = P * p', trong đó' P' là ma trận 3x4 hoặc 4x4 và 'p' là một điểm 3D đồng nhất, tức là 4-vectơ. Nói chung, thành phần cuối cùng của 'p' bằng 1. – who9vy

0

Để cập nhật vị trí máy ảnh, bạn phải cập nhật bản dịch trước, sau đó cập nhật ma trận xoay.

t_ref += lambda * (R_ref * t); 
R_ref = R * R_ref; 

nơi t_ref và R_ref là trạng thái máy ảnh của bạn, R và t là xoay và dịch máy ảnh mới được tính toán và lambda là hệ số tỷ lệ.

Các vấn đề liên quan