Commit 1eda8cb8 authored by Daniel Bourgault's avatar Daniel Bourgault
Browse files

Change the nameing convention of the figures produced (_GCP and _grect).

parent 729a68ae
function g_rect function g_rect
%G_RECT - Main function for georectifying oblique images. %G_RECT - Main function for georectifying oblique images.
% %
% Syntax: Simply type g_rect at the command line and follow the % Syntax: Simply type g_rect at the command line and follow the
% instructions. % instructions.
% %
% Inputs: % Inputs:
% The function G_RECT reads an input parameter file that contains all % The function G_RECT reads an input parameter file that contains all
% information required to perfrorm a georectification of a given image. % information required to perfrorm a georectification of a given image.
% The format of this parameter file is detailed on-line on the G_RECT % The format of this parameter file is detailed on-line on the G_RECT
% Wiki page. % Wiki page.
% %
% Outputs: % Outputs:
% The function G_RECT creates an output file that contains the following % The function G_RECT creates an output file that contains the following
% variables: % variables:
% %
% imgFname: The reference image for the georectification. % imgFname: The reference image for the georectification.
% %
% firstImgFname: The first image of a sequence of images to which the % firstImgFname: The first image of a sequence of images to which the
% georectification could be applied to. This is really % georectification could be applied to. This is really
% just a comment. % just a comment.
% %
% lastImgFname: The last image of a sequence of images to which the % lastImgFname: The last image of a sequence of images to which the
% georectification could be applied to. This is really % georectification could be applied to. This is really
% just a comment. % just a comment.
% %
% LON: The main matrix that contain the longitude of each % LON: The main matrix that contain the longitude of each
% pixel of the referecne image (imgFname). Note that % pixel of the referecne image (imgFname). Note that
% if the package is used to rectify lab images this % if the package is used to rectify lab images this
% matrix rather contains the distance in meters from % matrix rather contains the distance in meters from
% a predefined x-origin. % a predefined x-origin.
% %
% LAT: Same as LON but for the latitude. % LAT: Same as LON but for the latitude.
% %
% LON0: A scalar for the longitude of the camera or, in the % LON0: A scalar for the longitude of the camera or, in the
% case of a lab setup its cartesian coordinate in meters. % case of a lab setup its cartesian coordinate in meters.
% %
% LAT0: Same as LON0 but for the latitude. % LAT0: Same as LON0 but for the latitude.
% %
% lon0_gcp: A vector containing the longitude of each ground % lon0_gcp: A vector containing the longitude of each ground
% control points (GCP). For the lab case this is the % control points (GCP). For the lab case this is the
% cartesian coordinate in meters. These GCPs may have % cartesian coordinate in meters. These GCPs may have
% elevations. % elevations.
% %
% lat0_gcp: Same as lon_gcp for latitude. % lat0_gcp: Same as lon_gcp for latitude.
% %
% lon_gcp: A vector containing the longitude of each ground % lon_gcp: A vector containing the longitude of each ground
% control points (GCP) projected onto the water level % control points (GCP) projected onto the water level
% i.e. at 0 m of elevation. For the lab case this is % i.e. at 0 m of elevation. For the lab case this is
% the cartesian coordinate in meters. % the cartesian coordinate in meters.
% %
% lat_gcp: Same as lon_gcp for latitude. % lat_gcp: Same as lon_gcp for latitude.
% %
% h_gcp: The elevation in meter of the GCPs. The elevation is % h_gcp: The elevation in meter of the GCPs. The elevation is
% 0 m if taken at water level. % 0 m if taken at water level.
% %
% i_gcp: The horizontal index of the image ground control % i_gcp: The horizontal index of the image ground control
% points. % points.
% %
% j_gcp: The vertical index of the image ground control % j_gcp: The vertical index of the image ground control
% points. % points.
% %
% hfov: The camera horizontal field of view [degree]. % hfov: The camera horizontal field of view [degree].
% %
% phi: Camera tilt angle [degree]. % phi: Camera tilt angle [degree].
% %
% lambda: Camera dip angle [degree]. % lambda: Camera dip angle [degree].
% %
% H: The camera altitude relative to the water [m]. % H: The camera altitude relative to the water [m].
% %
% theta: View angle clockwise from North [degree]. % theta: View angle clockwise from North [degree].
% %
% errGeoFit: The rms error of the georectified image after % errGeoFit: The rms error of the georectified image after
% geometrical transformation [m]. % geometrical transformation [m].
% %
% errPolyFit: The rms error of the georectified image after % errPolyFit: The rms error of the georectified image after
% geometrical transformation and the polynomial % geometrical transformation and the polynomial
% correction [m]. % correction [m].
% %
% precision: Calculation can be done in single or double % precision: Calculation can be done in single or double
% precisions as defined by the user in the parameter % precisions as defined by the user in the parameter
% file. With today's computers this is now obsolete % file. With today's computers this is now obsolete
% and calculations can always be done in double % and calculations can always be done in double
% precision. % precision.
% %
% Delta: The effective resolution of the georectified image. % Delta: The effective resolution of the georectified image.
% %
% Other m-files required: Works best with the m_map package for % Other m-files required: Works best with the m_map package for
% visualization. % visualization.
% Subfunctions: all functions contained within the G_RECT folder. % Subfunctions: all functions contained within the G_RECT folder.
% %
% Author: Daniel Bourgault % Author: Daniel Bourgault
% Institut des sciences de la mer de Rimouski % Institut des sciences de la mer de Rimouski
% email: daniel_bourgault@uqar.ca % email: daniel_bourgault@uqar.ca
% Website: https://srwebpolr01.uqar.ca/g_rect/ % Website: https://srwebpolr01.uqar.ca/g_rect/
% February 2013 % February 2013
% %
%% %%
% The minimization is repeated nMinimize times where each time a random % The minimization is repeated nMinimize times where each time a random
% combination of the initial guesses is chosen within the given % combination of the initial guesses is chosen within the given
% uncertainties provided by the user. This is becasue the algorithm often % uncertainties provided by the user. This is becasue the algorithm often
% converges toward a local minimum. The repetition is used to increase chances % converges toward a local minimum. The repetition is used to increase chances
% that the minimum found is a true minimum within the uncertainties provided. % that the minimum found is a true minimum within the uncertainties provided.
nMinimize = 50; nMinimize = 50;
%% Read the parameter file %% Read the parameter file
% Count the number of header lines before the ground control points (GCPs) % Count the number of header lines before the ground control points (GCPs)
% The GCPs start right after the variable gcpData is set to true. % The GCPs start right after the variable gcpData is set to true.
display(' '); display(' ');
display(' Welcome to g_rect: a package for georectifying oblique images on a flat ocean'); display(' Welcome to g_rect: a package for georectifying oblique images on a flat ocean');
display(' Authors: Daniel Bourgault and Rich Pawlowicz'); display(' Authors: Daniel Bourgault and Rich Pawlowicz');
display(' '); display(' ');
inputFname = input(' Enter the filename for the input parameters: ','s'); inputFname = input(' Enter the filename for the input parameters: ','s');
fid = fopen(inputFname); fid = fopen(inputFname);
nHeaderLine = 0; nHeaderLine = 0;
gcpData = false; gcpData = false;
% Read and execute each line of the parameter file until gcpData = true % Read and execute each line of the parameter file until gcpData = true
% after which the GCP data appear and are read below with the importdata % after which the GCP data appear and are read below with the importdata
% function. % function.
while gcpData == false while gcpData == false
eval(fgetl(fid)); eval(fgetl(fid));
nHeaderLine = nHeaderLine + 1; nHeaderLine = nHeaderLine + 1;
end end
fclose(fid); fclose(fid);
%% Import the GCP data at the end of the parameter file %% Import the GCP data at the end of the parameter file
gcp = importdata(inputFname,' ',nHeaderLine); gcp = importdata(inputFname,' ',nHeaderLine);
i_gcp = gcp.data(:,1); i_gcp = gcp.data(:,1);
j_gcp = gcp.data(:,2); j_gcp = gcp.data(:,2);
lon_gcp0 = gcp.data(:,3); lon_gcp0 = gcp.data(:,3);
lat_gcp0 = gcp.data(:,4); lat_gcp0 = gcp.data(:,4);
[ngcp n_column] = size(gcp.data) [ngcp n_column] = size(gcp.data)
% If there are 5 columns it means that elevation are provided % If there are 5 columns it means that elevation are provided
if n_column == 5 if n_column == 5
h_gcp = gcp.data(:,5); h_gcp = gcp.data(:,5);
else % otherwise elevation are considered to be zero else % otherwise elevation are considered to be zero
h_gcp(1:ngcp) = 0.0; h_gcp(1:ngcp) = 0.0;
end end
%% %%
% Check if the elevation of the GCPs are not too high and above % Check if the elevation of the GCPs are not too high and above
% a certain fraction (gamma) of the camera height. If so, stop. % a certain fraction (gamma) of the camera height. If so, stop.
gamma = 0.75; gamma = 0.75;
i_bad = find(h_gcp > gamma*(H+dH)); i_bad = find(h_gcp > gamma*(H+dH));
if length(i_bad) > 0 if length(i_bad) > 0
display([' ']); display([' ']);
display([' WARNING:']); display([' WARNING:']);
for i = 1:length(i_bad) for i = 1:length(i_bad)
display([' The elevation of GCP #',num2str(i_bad(i)),' is greater than ',num2str(gamma),'*(H+dH).']); display([' The elevation of GCP #',num2str(i_bad(i)),' is greater than ',num2str(gamma),'*(H+dH).']);
end end
display([' FIX AND RERUN.']); display([' FIX AND RERUN.']);
return return
end end
% Get the image size % Get the image size
imgInfo = imfinfo(imgFname); imgInfo = imfinfo(imgFname);
imgWidth = imgInfo.Width; imgWidth = imgInfo.Width;
imgHeight = imgInfo.Height; imgHeight = imgInfo.Height;
if precision == 'single' if precision == 'single'
imgWidth = single(imgWidth); imgWidth = single(imgWidth);
imgHeight = single(imgHeight); imgHeight = single(imgHeight);
end end
%% Display information %% Display information
fprintf('\n') fprintf('\n')
fprintf(' INPUT PARAMETERS\n') fprintf(' INPUT PARAMETERS\n')
fprintf(' Image filename: (imgFname):........... %s\n',imgFname) fprintf(' Image filename: (imgFname):........... %s\n',imgFname)
fprintf(' First image: (firstImgFname):......... %s\n',firstImgFname) fprintf(' First image: (firstImgFname):......... %s\n',firstImgFname)
fprintf(' Last image: (lastImgFname):........... %s\n',lastImgFname) fprintf(' Last image: (lastImgFname):........... %s\n',lastImgFname)
fprintf(' Output filename: (outputFname):....... %s\n',outputFname); fprintf(' Output filename: (outputFname):....... %s\n',outputFname);
fprintf(' Image width (imgWidth):............... %i\n',imgWidth) fprintf(' Image width (imgWidth):............... %i\n',imgWidth)
fprintf(' Image width (imgHeight):.............. %i\n',imgHeight) fprintf(' Image width (imgHeight):.............. %i\n',imgHeight)
fprintf(' Camera longitude (LON0):.............. %f\n',LON0) fprintf(' Camera longitude (LON0):.............. %f\n',LON0)
fprintf(' Camera latitude (LAT0):............... %f\n',LAT0) fprintf(' Camera latitude (LAT0):............... %f\n',LAT0)
fprintf(' Principal point offset (ic):.......... %f\n',ic) fprintf(' Principal point offset (ic):.......... %f\n',ic)
fprintf(' Principal point offset (jc):.......... %f\n',jc) fprintf(' Principal point offset (jc):.......... %f\n',jc)
fprintf(' Field of view (hfov):................. %f\n',hfov) fprintf(' Field of view (hfov):................. %f\n',hfov)
fprintf(' Dip angle (lambda):................... %f\n',lambda) fprintf(' Dip angle (lambda):................... %f\n',lambda)
fprintf(' Tilt angle (phi):..................... %f\n',phi) fprintf(' Tilt angle (phi):..................... %f\n',phi)
fprintf(' Camera altitude (H):.................. %f\n',H) fprintf(' Camera altitude (H):.................. %f\n',H)
fprintf(' View angle from North (theta):........ %f\n',theta) fprintf(' View angle from North (theta):........ %f\n',theta)
fprintf(' Uncertainty in hfov (dhfov):.......... %f\n',dhfov) fprintf(' Uncertainty in hfov (dhfov):.......... %f\n',dhfov)
fprintf(' Uncertainty in dip angle (dlambda):... %f\n',dlambda) fprintf(' Uncertainty in dip angle (dlambda):... %f\n',dlambda)
fprintf(' Uncertainty in tilt angle (dphi):..... %f\n',dphi) fprintf(' Uncertainty in tilt angle (dphi):..... %f\n',dphi)
fprintf(' Uncertainty in altitude (dH):......... %f\n',dH) fprintf(' Uncertainty in altitude (dH):......... %f\n',dH)
fprintf(' Uncertainty in view angle (dtheta):... %f\n',dtheta) fprintf(' Uncertainty in view angle (dtheta):... %f\n',dtheta)
fprintf(' Polynomial order (polyOrder):......... %i\n',polyOrder) fprintf(' Polynomial order (polyOrder):......... %i\n',polyOrder)
fprintf(' Number of GCPs (ngcp):................ %i\n',ngcp) fprintf(' Number of GCPs (ngcp):................ %i\n',ngcp)
fprintf(' Precision (precision):................ %s\n',precision) fprintf(' Precision (precision):................ %s\n',precision)
fprintf(' Field or lab (field=true; lab=false):. %i\n',field) fprintf(' Field or lab (field=true; lab=false):. %i\n',field)
fprintf('\n') fprintf('\n')
% Display the image with GCPs; % Display the image with GCPs;
% image(imread(imgFname)); %image(imread(imgFname));
imagesc(imread(imgFname)); imagesc(imread(imgFname));
colormap(gray); colormap(gray);
hold on hold on
for i = 1:ngcp for i = 1:ngcp
plot(i_gcp(i),j_gcp(i),'r.'); plot(i_gcp(i),j_gcp(i),'r.');
text(i_gcp(i),j_gcp(i),[num2str(i),'(',num2str(h_gcp(i)),')'],... text(i_gcp(i),j_gcp(i),[' ',num2str(i),'(',num2str(h_gcp(i)),')'],...
'color','r',... 'color','r',...
'horizontalalignment','right',... 'horizontalalignment','left',...
'fontsize',16); 'fontsize',10);
end end
title('Ground Control Points Number (elevation in meters)','color','r'); title('Ground Control Points Number (elevation in meters)','color','r');
daspect([1 1 1]);
print -dpng -r300 image1.png print('-dpng','-r300',[imgFname(1:end-4),'_GCP.png']);
fprintf('\n') fprintf('\n')
ok = input('Is it ok to proceed with the rectification (y/n): ','s'); ok = input('Is it ok to proceed with the rectification (y/n): ','s');
if ok ~= 'y' if ok ~= 'y'
return return
end end
%% %%
nUnknown = 0; nUnknown = 0;
if dhfov > 0.0; nUnknown = nUnknown+1; end if dhfov > 0.0; nUnknown = nUnknown+1; end
if dlambda > 0.0; nUnknown = nUnknown+1; end if dlambda > 0.0; nUnknown = nUnknown+1; end
if dphi > 0.0; nUnknown = nUnknown+1; end if dphi > 0.0; nUnknown = nUnknown+1; end
if dH > 0.0; nUnknown = nUnknown+1; end if dH > 0.0; nUnknown = nUnknown+1; end
if dtheta > 0.0; nUnknown = nUnknown+1; end if dtheta > 0.0; nUnknown = nUnknown+1; end
if nUnknown > ngcp if nUnknown > ngcp
fprintf('\n') fprintf('\n')
fprintf('WARNING: \n'); fprintf('WARNING: \n');
fprintf(' The number of GCPs is < number of unknown parameters.\n'); fprintf(' The number of GCPs is < number of unknown parameters.\n');
fprintf(' Program stopped.\n'); fprintf(' Program stopped.\n');
return return
end end
% Check for consistencies between number of GCPs and order of the polynomial % Check for consistencies between number of GCPs and order of the polynomial
% correction % correction
ngcp = length(i_gcp); ngcp = length(i_gcp);
if ngcp < 3*polyOrder if ngcp < 3*polyOrder
fprintf('\n') fprintf('\n')
fprintf('WARNING: \n'); fprintf('WARNING: \n');
fprintf(' The number of GCPs is inconsistent with the order of the polynomial correction.\n'); fprintf(' The number of GCPs is inconsistent with the order of the polynomial correction.\n');
fprintf(' ngcp should be >= 3*polyOrder.\n'); fprintf(' ngcp should be >= 3*polyOrder.\n');
fprintf(' Polynomial correction will not be applied.\n'); fprintf(' Polynomial correction will not be applied.\n');
polyCorrection = false; polyCorrection = false;
else else
polyCorrection = true; polyCorrection = true;
end end
if polyOrder == 0 if polyOrder == 0
polyCorrection = false; polyCorrection = false;
end end
%% This is the main section for the minimization algorithm %% This is the main section for the minimization algorithm
if nUnknown > 0 if nUnknown > 0
% Options for the fminsearch function. May be needed for some particular % Options for the fminsearch function. May be needed for some particular
% problems but in general the default values should work fine. % problems but in general the default values should work fine.
%options=optimset('MaxFunEvals',100000,'MaxIter',100000); %options=optimset('MaxFunEvals',100000,'MaxIter',100000);
%options=optimset('MaxFunEvals',100000,'MaxIter',100000,'TolX',1.d-12,'TolFun',1.d-12); %options=optimset('MaxFunEvals',100000,'MaxIter',100000,'TolX',1.d-12,'TolFun',1.d-12);
options = []; options = [];
% Only feed the minimization algorithm with the GCPs. xp and yp are the % Only feed the minimization algorithm with the GCPs. xp and yp are the
% image coordinate of these GCPs. % image coordinate of these GCPs.
xp = i_gcp; xp = i_gcp;
yp = j_gcp; yp = j_gcp;
% This is the call to the minimization % This is the call to the minimization
bestErrGeoFit = Inf; bestErrGeoFit = Inf;
% Save inital guesses in new variables. % Save inital guesses in new variables.
hfovGuess = hfov; hfovGuess = hfov;
lambdaGuess = lambda; lambdaGuess = lambda;
phiGuess = phi; phiGuess = phi;
HGuess = H; HGuess = H;
thetaGuess = theta; thetaGuess = theta;
for iMinimize = 1:nMinimize for iMinimize = 1:nMinimize
% First guesses for the minimization % First guesses for the minimization
if iMinimize == 1 if iMinimize == 1
hfov0 = hfov; hfov0 = hfov;
lambda0 = lambda; lambda0 = lambda;
phi0 = phi; phi0 = phi;
H0 = H; H0 = H;
theta0 = theta; theta0 = theta;
else else
% Select randomly new initial guesses within the specified % Select randomly new initial guesses within the specified
% uncertainties. % uncertainties.
hfov0 = (hfovGuess - dhfov) + 2*dhfov*rand(1); hfov0 = (hfovGuess - dhfov) + 2*dhfov*rand(1);
lambda0 = (lambdaGuess - dlambda) + 2*dlambda*rand(1); lambda0 = (lambdaGuess - dlambda) + 2*dlambda*rand(1);
phi0 = (phiGuess - dphi) + 2*dphi*rand(1); phi0 = (phiGuess - dphi) + 2*dphi*rand(1);
H0 = (HGuess - dH) + 2*dH*rand(1); H0 = (HGuess - dH) + 2*dH*rand(1);
theta0 = (thetaGuess - dtheta) + 2*dtheta*rand(1); theta0 = (thetaGuess - dtheta) + 2*dtheta*rand(1);
end end
% Create vector cv0 for the initial guesses. % Create vector cv0 for the initial guesses.
i = 0; i = 0;
if dhfov > 0.0 if dhfov > 0.0
i = i+1; i = i+1;
cv0(i) = hfov0; cv0(i) = hfov0;
theOrder(i) = 1; theOrder(i) = 1;
end end
if dlambda > 0.0 if dlambda > 0.0
i = i + 1; i = i + 1;
cv0(i) = lambda0; cv0(i) = lambda0;
theOrder(i) = 2; theOrder(i) = 2;
end end
if dphi > 0.0 if dphi > 0.0
i = i + 1; i = i + 1;
cv0(i) = phi0; cv0(i) = phi0;
theOrder(i) = 3; theOrder(i) = 3;
end end
if dH > 0.0 if dH > 0.0
i = i + 1; i = i + 1;
cv0(i) = H0; cv0(i) = H0;
theOrder(i) = 4; theOrder(i) = 4;
end end
if dtheta > 0.0 if dtheta > 0.0
i = i + 1; i = i + 1;
cv0(i) = theta0; cv0(i) = theta0;
theOrder(i) = 5; theOrder(i) = 5;
end end
[cv, errGeoFit] = fminsearch('g_error_geofit',cv0,options, ... [cv, errGeoFit] = fminsearch('g_error_geofit',cv0,options, ...
imgWidth,imgHeight,xp,yp,ic,jc,... imgWidth,imgHeight,xp,yp,ic,jc,...
hfov,lambda,phi,H,theta,... hfov,lambda,phi,H,theta,...
hfov0,lambda0,phi0,H0,theta0,... hfov0,lambda0,phi0,H0,theta0,...
hfovGuess,lambdaGuess,phiGuess,HGuess,thetaGuess,... hfovGuess,lambdaGuess,phiGuess,HGuess,thetaGuess,...
dhfov,dlambda,dphi,dH,dtheta,... dhfov,dlambda,dphi,dH,dtheta,...
LON0,LAT0,... LON0,LAT0,...
i_gcp,j_gcp,lon_gcp0,lat_gcp0,h_gcp,... i_gcp,j_gcp,lon_gcp0,lat_gcp0,h_gcp,...
theOrder,field); theOrder,field);
if errGeoFit < bestErrGeoFit if errGeoFit < bestErrGeoFit
bestErrGeoFit = errGeoFit; bestErrGeoFit = errGeoFit;
cvBest = cv; cvBest = cv;
end end
fprintf('\n') fprintf('\n')
fprintf(' Iteration # (iMinimize): %i\n',iMinimize); fprintf(' Iteration # (iMinimize): %i\n',iMinimize);
fprintf(' Max. number of iteration (nMinimize): %i\n',nMinimize); fprintf(' Max. number of iteration (nMinimize): %i\n',nMinimize);
fprintf(' RSM error (m) for this iteration (errGeoFit): %f\n',errGeoFit); fprintf(' RSM error (m) for this iteration (errGeoFit): %f\n',errGeoFit);
fprintf(' Best RSM error (m) so far (bestErrGeoFit): %f\n',bestErrGeoFit);