Dies ist einfach in OpenCV zu tun, aber ich möchte eine native Matlab-Implementierung, die ziemlich effizient ist und leicht geändert werden kann. Die Methode sollte in der Lage sein, die Kameraparameter wie im obigen Link angegeben zu übernehmen.Wie kann ich ein Bild in Matlab mit den bekannten Kameraparametern entziffern?
Antwort
Sie jetzt tun können, dass ab Release R2013B, die Computer Vision System Toolbox verwenden. Es gibt eine GUI-App namens Camera Calibrator und eine Funktion undistortImage.
Die einfachste und gebräuchlichste Art der Unverzerrung (auch als Unwarp oder zur Kompensation von Linsenverzerrungen) ist eine Vorwärtsverzerrung bei einer gewählten Ausgangsfotogröße und dann eine Umkehrabbildung mit bilinearer Interpolation.
Hier ist Code, den ich schrieb dies für die Durchführung:
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);
es zu benutzen, braucht man die Kameraparameter der Kamera zu wissen, verwendet wird. Ich bin derzeit die PMD CamboardNano, die nach den Cayim.com Foren, um die Parameter hier verwendet hat:
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);
Hier ist ein Beispiel für die Ausgabe von dem Camboard Nano. Anmerkung: Ich Grenzlinien künstlich hinzugefügt, um zu sehen, was die Wirkung der Verzerrung war nahe an den Rändern (seine viel stärker ausgeprägt):
Welche Datentypen unterstützt Ihre Funktion? Ich kann es nicht mit irgendwelchen arbeiten lassen, die ich versuchte ... BTW: Danke für die Funktion, es ist komisch, wie Matlab das –
@AnderBiguri nicht implementiert hat, sollte es mindestens mit Single-Channel-Typ "double" arbeiten. Das erste, was zu tun ist, konvertieren Sie ein Bild in Double. Auch wenn Sie ein Bild haben, das Graustufen oder ein Tiefenbild ist, dann sollte es gut funktionieren, nur Unistort mit den richtigen Parametern aufrufen. Wenn Sie ein 3-Kanal-Farbbild haben, müssen Sie auf jedem Kanal getrennt dissoziieren. – twerdster
Es funktioniert nicht mit Graustufen-Bitmaps, aber ich werde sie in Doppel konvertieren und versuchen! –
Endlich! Danke, dass du darauf hingewiesen hast – twerdster