Получение комплексных чисел при расчете внутренних параметров камеры - PullRequest
0 голосов
/ 30 сентября 2018

Я пытаюсь реализовать алгоритм Чжана для калибровки камеры в MATlab.Шаги для этого должны быть довольно просты и просты в реализации, особенно с использованием MATLab.Тем не менее, я застрял в точке, где я получаю комплексные числа, где я должен получать реальные числа.

Если кто-то из вас делал это раньше, вы точно знаете, что нужно сделать.Первым шагом было бы взять изображения шахматной доски и вычислить отображение гомографии между плоскостью модели и плоскостью изображения, используя приведенное ниже уравнение (я в основном собираюсь включить большую часть своего кода, потому что он очень маленький):

for i=1:n
    p=[X(i,:) z -x(i,1).*X(i,1) -x(i,1).*X(i,2) -x(i,1)];
    q=[z X(i,:) -x(i,2).*X(i,1) -x(i,2).*X(i,2) -x(i,2)];
    E=[E;p;q];
end

где X содержит однородные координаты углов шахматной доски в мировой плоскости, а x содержит однородные координаты в плоскости изображения.

Следующим шагом будет решение уравнения EH = 0, чтобы получить H:

  [u d v]=svd(E);
  H= v(:,end);
  H= reshape(H,3,3)';

Я не буду вдаваться в подробности того, что каждая переменная в оставшемся коде, потому что я предполагаю, что я буду получать помощь от людей, которые уже сделали это (это довольнопопулярный алгоритм), поэтому я просто добавлю код как есть с некоторыми комментариями:

vij = @(i,j,H) [ H(i,1)*H(j,1)
                     H(i,1)*H(j,2) + H(i,2)*H(j,1)
                     H(i,2)*H(j,2)
                     H(i,3)*H(j,1) + H(i,1)*H(j,3)
                     H(i,3)*H(j,2) + H(i,2)*H(j,3)
                     H(i,3)*H(j,3) ];
G = [ vij(1,2,H)'; (vij(1,1,H)-vij(2,2,H))' ];
V = [ V; G ];

, конечно, в приведенном выше фрагментекод, который мы находимся в цикле, который выполняется столько раз, сколько существует изображений

Далее - самая прямолинейная часть всего алгоритма, где вы просто не ошибетесь, где мы вычисляем внутренние параметры:

[u1,d1,v1] = svd( V );
b = v1(:,end);
v0 = ( b(2)*b(4)-b(1)*b(5) ) / ( b(1)*b(3)-b(2)^2 );
lambda = b(6) - ( b(4)^2 + v0*(b(2)*b(4)-b(1)*b(5)) ) / b(1);
b(1)
alpha = sqrt( lambda / b(1) );
beta = sqrt( lambda*b(1) / (b(1)*b(3)-b(2)^2) );
gamma = -b(2)*alpha^2*beta / lambda;
u0 = gamma*v0 / beta - b(4)*alpha^2 / lambda;
A = [ alpha  gamma  u0;
      0      beta   v0;
      0      0      1   ]

Затем нам нужно учесть разницу в размерах квадратов между плоскостью изображения и мировой плоскостью, поэтому мы построим матрицу нормализации:

N = [ 2/width     0      -1
                0     2/height  -1
                0        0       1 ];

Где высота и ширинаэто изображения в пикселях.

Наконец, матрица встроенных функций A может быть получена с помощью следующей строки:

A = N\A;

Теперь, чтобы убедиться, что я получаю точные результаты,Я сравнил свои результаты с инструментом калибровки от Caltech (Bouget), и по какой-то причине я правильно получаю значения u0 и v0, но остальные (альфа, бета, гамма) далеко, на самом деле это комплексные числа.

И я понимаю, что это потому, что лямбда может быть отрицательной.Кроме того, это не должно быть!и это проблема!

Я посмотрел буквально сотни онлайн-реализаций, и все они очень близки к моей, но все они правильно поняли ВСЕ свои сущности.Что меня поражает, так это то, что мои u0 и v0 ТОЧНО верны, а остальные просто сложный бред.

Не могли бы вы помочь?Я был бы очень признателен!

1 Ответ

0 голосов
/ 11 октября 2018

Возможно, это немного слишком тривиально, но вы пытались использовать другие имена переменных, кроме i и j?

...