Я пытаюсь реализовать алгоритм Чжана для калибровки камеры в 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 ТОЧНО верны, а остальные просто сложный бред.
Не могли бы вы помочь?Я был бы очень признателен!