Как я могу неискажать изображение в Matlab, используя известные параметры камеры?

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


person twerdster    schedule 24.08.2012    source источник


Ответы (2)


Теперь вы можете сделать это, начиная с версии R2013B, с помощью набора инструментов Computer Vision System Toolbox. Существует приложение с графическим интерфейсом, которое называется Camera Calibrator. функция undistortImage.

person Dima    schedule 14.11.2013

Самый простой и наиболее распространенный способ устранения искажений (также называемый устранением искажения или компенсацией искажения объектива) заключается в прямом искажении выбранного размера выходной фотографии, а затем обратном отображении с использованием билинейной интерполяции.

Вот код, который я написал для этого:

function I = undistort(Idistorted, params)
fx = params.fx;
fy = params.fy;
cx = params.cx;
cy = params.cy;
k1 = params.k1;
k2 = params.k2;
k3 = params.k3;
p1 = params.p1;
p2 = params.p2;

K = [fx 0 cx; 0 fy cy; 0 0 1];

I = zeros(size(Idistorted));
[i j] = find(~isnan(I));

% Xp = the xyz vals of points on the z plane
Xp = inv(K)*[j i ones(length(i),1)]';

% Now we calculate how those points distort i.e forward map them through the distortion
r2 = Xp(1,:).^2+Xp(2,:).^2;
x = Xp(1,:);
y = Xp(2,:);

x = x.*(1+k1*r2 + k2*r2.^2) + 2*p1.*x.*y + p2*(r2 + 2*x.^2);
y = y.*(1+k1*r2 + k2*r2.^2) + 2*p2.*x.*y + p1*(r2 + 2*y.^2);

% u and v are now the distorted cooridnates
u = reshape(fx*x + cx,size(I));
v = reshape(fy*y + cy,size(I));

% Now we perform a backward mapping in order to undistort the warped image coordinates
I = interp2(Idistorted, u, v);

Для его использования необходимо знать параметры используемой камеры. В настоящее время я использую PMD CamboardNano, который, согласно форумам Cayim.com, имеет параметры, используемые здесь:

params = struct('fx',104.119, 'fy', 103.588, 'cx', 81.9494, 'cy', 59.4392, 'k1', -0.222609, 'k2', 0.063022, 'k3', 0, 'p1', 0.002865, 'p2', -0.001446);

I = undistort(Idistorted, params);

subplot(121); imagesc(Idistorted);
subplot(122); imagesc(I);

Вот пример вывода Camboard Nano. Примечание. Я искусственно добавил граничные линии, чтобы увидеть, как влияет искажение ближе к краям (оно гораздо более выражено): введите описание изображения здесь

person twerdster    schedule 24.08.2012
comment
Какие типы данных поддерживает ваша функция? Я не могу заставить его работать ни с одним, что я пробовал... Кстати: спасибо за функцию, странно, что в Matlab это не реализовано - person Ander Biguri; 25.03.2013
comment
@AnderBiguri, по крайней мере, он должен работать с одноканальным типом double. Первое, что нужно сделать, это преобразовать любое изображение в двойное. Кроме того, если у вас есть изображение в градациях серого или изображение глубины, оно должно работать нормально, просто вызывая неискажение с правильными параметрами. Если у вас есть 3-канальное цветное изображение, вам нужно будет устранить искажения отдельно для каждого канала. - person twerdster; 26.03.2013
comment
Это не работает с растровыми изображениями в градациях серого, но я конвертирую их в двойные и попробую! - person Ander Biguri; 26.03.2013