Rectify image with known coordinates
I have calibration images from four cameras in a 1×4 array. For simplicity, I’m showing the processing for just one camera. The image shows a calibration plate that contains black dots at a know separation.
The image is in pixels. I already post processes the image and obtain a rectification mapping function image coordinates to world coordinates. I input the location of known location in the image in image coordinates and the coordinates of these points in the real world. The output is the function that can take any point in image coordinates and convert it to real world coordinates.
I can plot the points in real world coordinates using the ‘scatter function’ (as in the figure below) but I’m having problems rectifying the whole image. I have no idea how to reshape the image with the new real world coordinates.
Here’s the data and code (data was a bit over 5MB).
clear
clc
close all
% I = points in image coordinates
% W = same points as in I but in real world coordinates
% calImg = Raw image in image coordinates
load("calImg.mat")
rectify_quad = cell(length(calImg),1); imagePoints2 = rectify_quad;
% CALIBRATION: compute the image rectification function for this camera
% from the world coords and image coords of the calibration dots (using
% a quadratic transformation: order = 2)
trans_order = 2;
rectify_quad{1} = calibrate_camera(I,W,trans_order);
imagePoints2{1} = rectify_quad{1}(I);
figure(1)
subplot(121)
imagesc(calImg); hold on
colormap(gray)
scatter(I(:,1), I(:,2), ‘r’, ‘LineWidth’,1)
axis equal
xlabel(‘pixel’)
ylabel(‘pixel’)
title(‘Image and detected points (Image coord)’)
subplot(122)
% I want to plot the rectified image in world coordinates similar to subplot (121)
scatter(imagePoints2{1}(:,1),imagePoints2{1}(:,2), ‘r’, ‘LineWidth’,1);
axis equal
xlabel(‘meters’)
ylabel(‘meters’)
title(‘detected points (real world coord)’)
function rectify = calibrate_camera(I,W,order)
% calculate the transformation function to convert image coordinates to
% world (physical) coordinates, including calibration (converting pixels to
% meters), undistortion, and rectification
%
% rectify: function handle to map image coordinates to world coordinates
% I: set of known calibration points in image coordinates (n x 2 vector) [px]
% W: set of known calibration points in world coordinates (n x 2 vector) [m]
% order: 1 for linear transformation (corrects for camera viewing angle but not lens distortion),
% 2 for quadratic transformation (corrects for camera viewing angle and lens distortion)
%
% references: Fujita et al 1998 (Water Res.), Creutin et al 2003 (J. Hydrol.)
%
% to use function handle: points_m = rectify(points_px)
% points_px: set of points in image coordinates (m x 2 vector) [px]
% points_m: set of points converted to world coordinates (m x 2 vector) [px]
% find transformation coefficients
if order == 2
A = [I.^2, I, ones(size(I,1),1), -I(:,1).^2.*W(:,1), -I(:,2).^2.*W(:,1), -I(:,1).*W(:,1), -I(:,2).*W(:,1), zeros(size(I,1),5);
zeros(size(I,1),5), -I(:,1).^2.*W(:,2), -I(:,2).^2.*W(:,2), -I(:,1).*W(:,2), -I(:,2).*W(:,2), I.^2, I, ones(size(I,1),1)];
else
A = [I, ones(size(I,1),1), -I(:,1).*W(:,1), -I(:,2).*W(:,1), zeros(size(I,1),3);
zeros(size(I,1),3), -I(:,1).*W(:,2), -I(:,2).*W(:,2), I, ones(size(I,1),1)];
end
Z = [W(:,1); W(:,2)];
B = (A’*A)^-1*A’*Z;
% function to map image coords to world coords
if order == 2
rectify = @(I) [(B(1)*I(:,1).^2 + B(2)*I(:,2).^2 + B(3)*I(:,1) + B(4)*I(:,2) + B(5))./ …
(B(6)*I(:,1).^2 + B(7)*I(:,2).^2 + B(8)*I(:,1) + B(9)*I(:,2) + 1), …
(B(10)*I(:,1).^2 + B(11)*I(:,2).^2 + B(12)*I(:,1) + B(13)*I(:,2) + B(14))./ …
(B(6)*I(:,1).^2 + B(7)*I(:,2).^2 + B(8)*I(:,1) + B(9)*I(:,2) + 1)];
else
rectify = @(I) [(B(1)*I(:,1) + B(2)*I(:,2) + B(3))./ …
(B(4)*I(:,1) + B(5)*I(:,2) + 1), …
(B(6)*I(:,1) + B(7)*I(:,2) + B(8))./ …
(B(4)*I(:,1) + B(5)*I(:,2) + 1)];
end
end
And here is an figure as reference. I want to rectify the raw image (convert it to real world coordinates) and plot it like in subplot(121)I have calibration images from four cameras in a 1×4 array. For simplicity, I’m showing the processing for just one camera. The image shows a calibration plate that contains black dots at a know separation.
The image is in pixels. I already post processes the image and obtain a rectification mapping function image coordinates to world coordinates. I input the location of known location in the image in image coordinates and the coordinates of these points in the real world. The output is the function that can take any point in image coordinates and convert it to real world coordinates.
I can plot the points in real world coordinates using the ‘scatter function’ (as in the figure below) but I’m having problems rectifying the whole image. I have no idea how to reshape the image with the new real world coordinates.
Here’s the data and code (data was a bit over 5MB).
clear
clc
close all
% I = points in image coordinates
% W = same points as in I but in real world coordinates
% calImg = Raw image in image coordinates
load("calImg.mat")
rectify_quad = cell(length(calImg),1); imagePoints2 = rectify_quad;
% CALIBRATION: compute the image rectification function for this camera
% from the world coords and image coords of the calibration dots (using
% a quadratic transformation: order = 2)
trans_order = 2;
rectify_quad{1} = calibrate_camera(I,W,trans_order);
imagePoints2{1} = rectify_quad{1}(I);
figure(1)
subplot(121)
imagesc(calImg); hold on
colormap(gray)
scatter(I(:,1), I(:,2), ‘r’, ‘LineWidth’,1)
axis equal
xlabel(‘pixel’)
ylabel(‘pixel’)
title(‘Image and detected points (Image coord)’)
subplot(122)
% I want to plot the rectified image in world coordinates similar to subplot (121)
scatter(imagePoints2{1}(:,1),imagePoints2{1}(:,2), ‘r’, ‘LineWidth’,1);
axis equal
xlabel(‘meters’)
ylabel(‘meters’)
title(‘detected points (real world coord)’)
function rectify = calibrate_camera(I,W,order)
% calculate the transformation function to convert image coordinates to
% world (physical) coordinates, including calibration (converting pixels to
% meters), undistortion, and rectification
%
% rectify: function handle to map image coordinates to world coordinates
% I: set of known calibration points in image coordinates (n x 2 vector) [px]
% W: set of known calibration points in world coordinates (n x 2 vector) [m]
% order: 1 for linear transformation (corrects for camera viewing angle but not lens distortion),
% 2 for quadratic transformation (corrects for camera viewing angle and lens distortion)
%
% references: Fujita et al 1998 (Water Res.), Creutin et al 2003 (J. Hydrol.)
%
% to use function handle: points_m = rectify(points_px)
% points_px: set of points in image coordinates (m x 2 vector) [px]
% points_m: set of points converted to world coordinates (m x 2 vector) [px]
% find transformation coefficients
if order == 2
A = [I.^2, I, ones(size(I,1),1), -I(:,1).^2.*W(:,1), -I(:,2).^2.*W(:,1), -I(:,1).*W(:,1), -I(:,2).*W(:,1), zeros(size(I,1),5);
zeros(size(I,1),5), -I(:,1).^2.*W(:,2), -I(:,2).^2.*W(:,2), -I(:,1).*W(:,2), -I(:,2).*W(:,2), I.^2, I, ones(size(I,1),1)];
else
A = [I, ones(size(I,1),1), -I(:,1).*W(:,1), -I(:,2).*W(:,1), zeros(size(I,1),3);
zeros(size(I,1),3), -I(:,1).*W(:,2), -I(:,2).*W(:,2), I, ones(size(I,1),1)];
end
Z = [W(:,1); W(:,2)];
B = (A’*A)^-1*A’*Z;
% function to map image coords to world coords
if order == 2
rectify = @(I) [(B(1)*I(:,1).^2 + B(2)*I(:,2).^2 + B(3)*I(:,1) + B(4)*I(:,2) + B(5))./ …
(B(6)*I(:,1).^2 + B(7)*I(:,2).^2 + B(8)*I(:,1) + B(9)*I(:,2) + 1), …
(B(10)*I(:,1).^2 + B(11)*I(:,2).^2 + B(12)*I(:,1) + B(13)*I(:,2) + B(14))./ …
(B(6)*I(:,1).^2 + B(7)*I(:,2).^2 + B(8)*I(:,1) + B(9)*I(:,2) + 1)];
else
rectify = @(I) [(B(1)*I(:,1) + B(2)*I(:,2) + B(3))./ …
(B(4)*I(:,1) + B(5)*I(:,2) + 1), …
(B(6)*I(:,1) + B(7)*I(:,2) + B(8))./ …
(B(4)*I(:,1) + B(5)*I(:,2) + 1)];
end
end
And here is an figure as reference. I want to rectify the raw image (convert it to real world coordinates) and plot it like in subplot(121) I have calibration images from four cameras in a 1×4 array. For simplicity, I’m showing the processing for just one camera. The image shows a calibration plate that contains black dots at a know separation.
The image is in pixels. I already post processes the image and obtain a rectification mapping function image coordinates to world coordinates. I input the location of known location in the image in image coordinates and the coordinates of these points in the real world. The output is the function that can take any point in image coordinates and convert it to real world coordinates.
I can plot the points in real world coordinates using the ‘scatter function’ (as in the figure below) but I’m having problems rectifying the whole image. I have no idea how to reshape the image with the new real world coordinates.
Here’s the data and code (data was a bit over 5MB).
clear
clc
close all
% I = points in image coordinates
% W = same points as in I but in real world coordinates
% calImg = Raw image in image coordinates
load("calImg.mat")
rectify_quad = cell(length(calImg),1); imagePoints2 = rectify_quad;
% CALIBRATION: compute the image rectification function for this camera
% from the world coords and image coords of the calibration dots (using
% a quadratic transformation: order = 2)
trans_order = 2;
rectify_quad{1} = calibrate_camera(I,W,trans_order);
imagePoints2{1} = rectify_quad{1}(I);
figure(1)
subplot(121)
imagesc(calImg); hold on
colormap(gray)
scatter(I(:,1), I(:,2), ‘r’, ‘LineWidth’,1)
axis equal
xlabel(‘pixel’)
ylabel(‘pixel’)
title(‘Image and detected points (Image coord)’)
subplot(122)
% I want to plot the rectified image in world coordinates similar to subplot (121)
scatter(imagePoints2{1}(:,1),imagePoints2{1}(:,2), ‘r’, ‘LineWidth’,1);
axis equal
xlabel(‘meters’)
ylabel(‘meters’)
title(‘detected points (real world coord)’)
function rectify = calibrate_camera(I,W,order)
% calculate the transformation function to convert image coordinates to
% world (physical) coordinates, including calibration (converting pixels to
% meters), undistortion, and rectification
%
% rectify: function handle to map image coordinates to world coordinates
% I: set of known calibration points in image coordinates (n x 2 vector) [px]
% W: set of known calibration points in world coordinates (n x 2 vector) [m]
% order: 1 for linear transformation (corrects for camera viewing angle but not lens distortion),
% 2 for quadratic transformation (corrects for camera viewing angle and lens distortion)
%
% references: Fujita et al 1998 (Water Res.), Creutin et al 2003 (J. Hydrol.)
%
% to use function handle: points_m = rectify(points_px)
% points_px: set of points in image coordinates (m x 2 vector) [px]
% points_m: set of points converted to world coordinates (m x 2 vector) [px]
% find transformation coefficients
if order == 2
A = [I.^2, I, ones(size(I,1),1), -I(:,1).^2.*W(:,1), -I(:,2).^2.*W(:,1), -I(:,1).*W(:,1), -I(:,2).*W(:,1), zeros(size(I,1),5);
zeros(size(I,1),5), -I(:,1).^2.*W(:,2), -I(:,2).^2.*W(:,2), -I(:,1).*W(:,2), -I(:,2).*W(:,2), I.^2, I, ones(size(I,1),1)];
else
A = [I, ones(size(I,1),1), -I(:,1).*W(:,1), -I(:,2).*W(:,1), zeros(size(I,1),3);
zeros(size(I,1),3), -I(:,1).*W(:,2), -I(:,2).*W(:,2), I, ones(size(I,1),1)];
end
Z = [W(:,1); W(:,2)];
B = (A’*A)^-1*A’*Z;
% function to map image coords to world coords
if order == 2
rectify = @(I) [(B(1)*I(:,1).^2 + B(2)*I(:,2).^2 + B(3)*I(:,1) + B(4)*I(:,2) + B(5))./ …
(B(6)*I(:,1).^2 + B(7)*I(:,2).^2 + B(8)*I(:,1) + B(9)*I(:,2) + 1), …
(B(10)*I(:,1).^2 + B(11)*I(:,2).^2 + B(12)*I(:,1) + B(13)*I(:,2) + B(14))./ …
(B(6)*I(:,1).^2 + B(7)*I(:,2).^2 + B(8)*I(:,1) + B(9)*I(:,2) + 1)];
else
rectify = @(I) [(B(1)*I(:,1) + B(2)*I(:,2) + B(3))./ …
(B(4)*I(:,1) + B(5)*I(:,2) + 1), …
(B(6)*I(:,1) + B(7)*I(:,2) + B(8))./ …
(B(4)*I(:,1) + B(5)*I(:,2) + 1)];
end
end
And here is an figure as reference. I want to rectify the raw image (convert it to real world coordinates) and plot it like in subplot(121) image processing, image analysis, orthorectification MATLAB Answers — New Questions