Вращение и перевод из основной матрицы неверны

В настоящее время у меня есть настройки стерео камеры. Я откалибровал обе камеры, и у меня есть встроенная матрица для обеих камер K1 а также K2,

K1 = [2297.311,      0,       319.498;
      0,       2297.313,      239.499;
      0,             0,       1];

K2 = [2297.304,      0,       319.508;
      0,       2297.301,      239.514;
      0,             0,       1];

Я также определил Фундаментальную матрицу F между двумя камерами, используя findFundamentalMat() от OpenCV. Я проверил эпиполярное ограничение, используя пару соответствующих точек x1 а также x2 (в пиксельных координатах), и это очень близко к 0,

F = [5.672563368940768e-10, 6.265600996978877e-06, -0.00150188302445251;
     6.766518121363063e-06, 4.758206104804563e-08,  0.05516598334827842;
     -0.001627120880791009, -0.05934224611334332,   1];

x1 = 133,75    
x2 = 124.661,67.6607

transpose(x2)*F*x1 = -0.0020

От F Я могу получить Основную Матрицу E как E = K2'*F*K1, Я разлагаю E используя функцию MATLAB SVD, чтобы получить 4 возможности вращения и перемещения K2 в отношении K1,

E = transpose(K2)*F*K1;
svd(E);

[U,S,V] = svd(E);

diag_110 = [1 0 0; 0 1 0; 0 0 0];
newE = U*diag_110*transpose(V);
[U,S,V] = svd(newE); //Perform second decompose to get S=diag(1,1,0)

W = [0 -1 0; 1 0 0; 0 0 1];

R1 = U*W*transpose(V);
R2 = U*transpose(W)*transpose(V);
t1 = U(:,3); //norm = 1
t2 = -U(:,3); //norm = 1

Скажем так K1 используется в качестве системы координат, для которой мы делаем все измерения. Поэтому центр K1 я сидела C1 = (0,0,0), При этом должно быть возможно применить правильное вращение R и перевод t такой, что C2 = R*(0,0,0)+t (то есть центр K2 измеряется относительно центра K1)

Теперь скажем, что используя мои соответствующие пары x1 а также x2, Если я знаю длину каждого пикселя в обеих своих камерах и поскольку я знаю фокусное расстояние из встроенной матрицы, я смогу определить два вектора v1 а также v2 для обеих камер, которые пересекаются в одной точке, как показано ниже.

pixel_length = 7.4e-6; //in meters
focal_length = 17e-3;  //in meters

dx1 = (133-319.5)*pixel_length; //x-distance from principal point of 640*480 image
dy1 = (75-239.5) *pixel_length; //y-distance from principal point of 640*480 image
v1  = [dx1 dy1 focal_length] - (0,0,0); //vector found using camera center and corresponding image point on the image plane

dx2 = (124.661-319.5)*pixel_length; //same idea 
dy2 = (67.6607-239.5)*pixel_length; //same idea
v2  = R * ( [dx2 dy2 focal_length] - (0,0,0) ) + t; //apply R and t to measure v2 with respect to K1 frame

С этим вектором и зная линейное уравнение в параметрической форме, мы можем затем приравнять две линии для триангуляции и решения двух скалярных величин s и t через левую функцию деления в MATLAB, чтобы решить для системы уравнений.

C1 + s*v1 = C2 + t*v2
C1-C2 = tranpose([v2 v1])*transpose([s t]) //solve Ax = B form system to find s and t

С s а также t определил, что мы можем найти триангулированную точку, подключившись обратно к уравнению линии. Тем не менее, мой процесс не был успешным, так как я не могу найти ни одного R а также t решение, в котором точка находится перед обеими камерами и где обе камеры направлены вперед.

Что-то не так с моим конвейером или мыслительным процессом? Можно ли вообще получить каждый отдельный пиксельный луч?

3 ответа

Когда вы разлагаете основную матрицу на R а также t Вы получаете 4 разных решения. Три из них проецируют точки позади одной или обеих камер, и одна из них правильная. Вы должны проверить, какая из них правильная, с помощью триангуляции некоторых точек выборки.

В наборе инструментов Computer Vision в MATLAB есть функция, которая называется cameraPose, который сделает это для вас.

Должно ли это быть не C1-C2 = transpose([v2 -v1] * transpose([t s]), Это работает.

Проверил ваш код и обнаружил, что определители R1 и R2 равны -1, что неверно, поскольку в качестве матрицы вращения R должен иметь определитель, равный 1. Просто возьмите R=-R и попробуй еще раз.

Другие вопросы по тегам