Commit 47ace827 authored by Daniel Bourgault's avatar Daniel Bourgault
Browse files

The cdoe can now deal with GCPs with eleation. Plus the code now comes with m_map.

parent 13a4218a
...@@ -33,20 +33,18 @@ dH = 0.0; ...@@ -33,20 +33,18 @@ dH = 0.0;
dtheta = 20.0; dtheta = 20.0;
% Order of the polynomial correction (0, 1 or 2) % Order of the polynomial correction (0, 1 or 2)
polyOrder = 1; polyOrder = 0;
% To save memory calculation can be done in single precision. % To save memory calculation can be done in single precision.
% For higher precision set the variable 'precision' to 'double'; % For higher precision set the variable 'precision' to 'double';
precision = 'double'; precision = 'double';
% Ground Control Points (GCP). % Ground Control Points (GCP).
% The data must come right after the gcpData = true % The data must come right after the gcpData = true
gcpData = true; gcpData = true;
360 829 -70.561367 47.303783 360 829 -70.561367 47.303783 0
54 719 -70.54500 47.335 54 719 -70.54500 47.335 0
99 661 -70.505 47.375 99 661 -70.505 47.375 0
452 641 -70.435 47.389 452 641 -70.435 47.389 0
429 633 -70.418 47.408 429 633 -70.418 47.408 0
816 644 -70.393 47.368 816 644 -70.393 47.368 0
\ No newline at end of file \ No newline at end of file
...@@ -45,18 +45,18 @@ precision = 'double'; ...@@ -45,18 +45,18 @@ precision = 'double';
% Ground Control Points (GCP). % Ground Control Points (GCP).
gcpData = true; gcpData = true;
2999 226 0.500 0.00 2999 226 0.500 0.00 0
1694 220 1.500 0.00 1694 220 1.500 0.00 0
528 677 2.290 0.50 528 677 2.290 0.50 0
289 1231 2.290 1.00 289 1231 2.290 1.00 0
3819 686 0.000 0.50 3819 686 0.000 0.50 0
4018 1266 0.000 1.00 4018 1266 0.000 1.00 0
2566 1235 0.890 0.99 2566 1235 0.890 0.99 0
3806 2118 0.255 1.56 3806 2118 0.255 1.56 0
4131 1580 0.000 1.23 4131 1580 0.000 1.23 0
521 2548 1.910 1.82 521 2548 1.910 1.82 0
248 2328 2.060 1.71 248 2328 2.060 1.71 0
14 1868 2.290 1.46 14 1868 2.290 1.46 0
......
...@@ -4,7 +4,7 @@ function errGeoFit = g_error_geofit(cv,imgWidth,imgHeight,xp,yp,ic,jc,... ...@@ -4,7 +4,7 @@ function errGeoFit = g_error_geofit(cv,imgWidth,imgHeight,xp,yp,ic,jc,...
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_gcp,lat_gcp,... i_gcp,j_gcp,lon_gcp0,lat_gcp0,h_gcp,...
theOrder,field); theOrder,field);
...@@ -20,7 +20,6 @@ end ...@@ -20,7 +20,6 @@ end
[LON LAT] = g_pix2ll(xp,yp,imgWidth,imgHeight,ic,jc,... [LON LAT] = g_pix2ll(xp,yp,imgWidth,imgHeight,ic,jc,...
hfov,lambda,phi,theta,H,LON0,LAT0,field); hfov,lambda,phi,theta,H,LON0,LAT0,field);
% Calculate the error between ground control points (GCPs) % Calculate the error between ground control points (GCPs)
% and image control points once georectified. % and image control points once georectified.
% %
...@@ -35,8 +34,11 @@ ngcp = length(i_gcp); ...@@ -35,8 +34,11 @@ ngcp = length(i_gcp);
ngcpFinite = 0; ngcpFinite = 0;
errGeoFit = 0.0; errGeoFit = 0.0;
for k = 1:ngcp % Project the GCPs onto the water surface given their elevation
[lon_gcp,lat_gcp] = g_proj_GCP(LON0,LAT0,H,lon_gcp0,lat_gcp0,h_gcp,field);
for k = 1:ngcp
% Calculate the distance (i.e. error) between GCP and rectificed ICPs. % Calculate the distance (i.e. error) between GCP and rectificed ICPs.
distance = g_dist(lon_gcp(k),lat_gcp(k),LON(k),LAT(k),field); distance = g_dist(lon_gcp(k),lat_gcp(k),LON(k),LAT(k),field);
...@@ -63,17 +65,3 @@ if abs(phi - phiGuess) > dphi; errGeoFit = inf; end ...@@ -63,17 +65,3 @@ if abs(phi - phiGuess) > dphi; errGeoFit = inf; end
if abs(H - HGuess) > dH; errGeoFit = inf; end if abs(H - HGuess) > dH; errGeoFit = inf; end
if abs(theta - thetaGuess) > dtheta; errGeoFit = inf; end if abs(theta - thetaGuess) > dtheta; errGeoFit = inf; end
%fprintf('\n')
%fprintf('Field of view (fov): %f\n',hfov)
%fprintf('Dip angle (lambda): %f\n',lambda)
%fprintf('Tilt angle (phi): %f\n',phi)
%fprintf('Camera altitude (H): %f\n',H)
%fprintf('View angle from North (theta): %f\n',theta)
%fprintf('RMS error (m): %f\n',errGeoFit)
%fprintf('\n')
%figure(100)
%hold on;
%plot(errGeoFit);
...@@ -61,7 +61,6 @@ vfov = 2*atand(tand(hfov/2)/aspectRatio); ...@@ -61,7 +61,6 @@ vfov = 2*atand(tand(hfov/2)/aspectRatio);
fx = (imgWidth/2)/tand(hfov/2); fx = (imgWidth/2)/tand(hfov/2);
fy = (imgHeight/2)/tand(vfov/2); fy = (imgHeight/2)/tand(vfov/2);
% Subtract the principal point % Subtract the principal point
x_p = xp - x_c + (jc); x_p = xp - x_c + (jc);
y_p = yp - y_c + (ic); y_p = yp - y_c + (ic);
......
function [lon_gcp,lat_gcp] = g_proj_GCP(LON0,LAT0,H,lon_gcp0,lat_gcp0,h_gcp,field)
%G_PROJ_GCP
%
% This function projects the GCPs that have an elevation greater than 0
% onto the water level of zero elevation. This is a trick in order to be
% able to deal with GCPs that have elevation. The principle can be
% illustrated in 1D like this. Consider the position x of a GCP that has an
% elevation h. Then, the projection (xp) of this GCP onto the plane that has
% zero elevation and along a line that joins the camera position of elevation
% H and the GCP is given by:
%
% xp = x * (H - h)/H
%
% INPUTS:
%
% LON0: The longitiude of the camera
% LAT0: The latitude of the camera
% H: The elevation of the camera
% lon_gcp0: The longitudes of the GCPs
% lat_gcp0: The latitudes of the GCPs
% h_gcp: The elevations of the GCPs
%
% OUTPUTS:
% lon_gcp: The projected longitudes of the GCPs
% lat_gcp: The projected latitudes of the GCPs
%
n_gcp = length(h_gcp);
for i = 1:n_gcp
if field == true
% The calculation for the distance between the GCPs and the camera
% is done on an elliptical earth and this takes a long calculation
% with the command m_idist from the m_map package. Therefore, the
% calculation is done only on the GCPs with no elevation, hence
% the 'if' condition here.
if h_gcp(i) > 0
[range,a12,a21] = m_idist(LON0,LAT0,lon_gcp0(i),lat_gcp0(i));
proj_factor = H/(H-h_gcp(i));
new_range = range*proj_factor;
[lon_gcp(i),lat_gcp(i),a21] = m_fdist(LON0,LAT0,a12,new_range);
lon_gcp(i) = lon_gcp(i) - 360;
else
% If there's no elevation, then there's nothing to do.
lon_gcp(i) = lon_gcp0(i);
lat_gcp(i) = lat_gcp0(i);
end
else
% For lab situations where positions are provided in meters rather
% than in latitude longitude the calculation is simpler.
dx = lon_gcp0(i) - LON0;
dy = lat_gcp0(i) - LAT0;
range = sqrt(dx^2 + dy^2);
proj_factor = H/(H-h_gcp(i));
new_range = range*proj_factor;
beta = atan2(dy,dx);
lon_gcp(i) = new_range*cos(beta) + LON0;
lat_gcp(i) = new_range*sin(beta) + LAT0;
end
end
\ No newline at end of file
This diff is collapsed.
...@@ -18,6 +18,12 @@ function [h_figure,h_pcolor,h_datetext] = g_viz_field(imgFname,rectFile,varargin ...@@ -18,6 +18,12 @@ function [h_figure,h_pcolor,h_datetext] = g_viz_field(imgFname,rectFile,varargin
% corresponding objects in the figure, for use in g_viz_anim % corresponding objects in the figure, for use in g_viz_anim
% %
% Set some plotting parameters
ms = 10; % Marker Size
fs = 10; % Font size
lw = 2; % Line width
% Option
show_time = 0; show_time = 0;
show_land = 0; show_land = 0;
land_color = [241 235 144]/255; land_color = [241 235 144]/255;
...@@ -34,30 +40,21 @@ if length(varargin) > 1 ...@@ -34,30 +40,21 @@ if length(varargin) > 1
end end
end end
% Load the georectification file
% Set some plotting parameters
ms = 10; % Marker Size
fs = 10; % Font size
lw = 2; % Line width
load(rectFile); load(rectFile);
%p = size(LON,3); % Determine the region to plot, delimited by the GCP and the camera
% position. Add a factor (fac) all around
lon_min = min(lon_gcp);
lon_max = max(lon_gcp);
lat_min = min(lat_gcp);
lat_max = max(lat_gcp);
lon_min = min(lon_min,LON0);
lon_max = max(lon_max,LON0);
lat_min = min(lat_min,LAT0);
lat_max = max(lat_max,LAT0);
fac = 0.1; fac = 0.1;
lon_min= lon_min - fac*abs(lon_max-lon_min); lon_min = min([lon_gcp,LON0]);
lon_max= lon_max + fac*abs(lon_max-lon_min); lon_max = max([lon_gcp,LON0]);
lat_min= lat_min - fac*abs(lat_max-lat_min); lat_min = min([lat_gcp,LAT0]);
lat_max= lat_max + fac*abs(lat_max-lat_min); lat_max = max([lat_gcp,LAT0]);
lon_min = lon_min - fac*abs(lon_max - lon_min);
lon_max = lon_max + fac*abs(lon_max - lon_min);
lat_min = lat_min - fac*abs(lat_max - lat_min);
lat_max = lat_max + fac*abs(lat_max - lat_min);
rgb0 = double(imread(imgFname))/255; rgb0 = double(imread(imgFname))/255;
...@@ -70,19 +67,19 @@ end ...@@ -70,19 +67,19 @@ end
clear rgb0; clear rgb0;
int = int'; int = int';
int = int - nanmean(nanmean(int)); % Normalize the image if wanted
%int = int - nanmean(nanmean(int));
figure('Renderer', 'painters', 'Position', [100 100 900 700]) %figure('Renderer', 'painters', 'Position', [100 100 900 700])
figure
m_proj('mercator','longitudes',[lon_min lon_max],'latitudes',[lat_min lat_max]); m_proj('mercator','longitudes',[lon_min lon_max],'latitudes',[lat_min lat_max]);
hold on; hold on;
[X,Y] = m_ll2xy(LON,LAT);
cmap = contrast(int,256); cmap = contrast(int,256);
colormap(cmap); colormap(cmap);
h = pcolor(X,Y,int); h = m_pcolor(LON,LAT,int);
shading('interp'); shading('interp');
% Uncomment one of these lines if you want the coastline to be plotted. % Uncomment one of these lines if you want the coastline to be plotted.
if show_land if show_land
if strcmpi(show_land,'fjord') if strcmpi(show_land,'fjord')
...@@ -109,7 +106,14 @@ m_plot(LON0,LAT0,'kx','markersize',ms,'linewidth',lw); % Camera location ...@@ -109,7 +106,14 @@ m_plot(LON0,LAT0,'kx','markersize',ms,'linewidth',lw); % Camera location
%% Plot GCPs and ICPs. %% Plot GCPs and ICPs.
for n=1:length(i_gcp) for n=1:length(i_gcp)
% Plot the original GCPs that may have elevations
m_plot(lon_gcp0(n),lat_gcp0(n),'ko','markersize',ms,'linewidth',lw);
% Plot the projected GCPs that are actually used for the minimization
m_plot(lon_gcp(n),lat_gcp(n),'bo','markersize',ms,'linewidth',lw); m_plot(lon_gcp(n),lat_gcp(n),'bo','markersize',ms,'linewidth',lw);
% Plot the Image Control Points once georectified
m_plot(LON(i_gcp(n),j_gcp(n)),LAT(i_gcp(n),j_gcp(n)),'rx','MarkerSize',ms,'linewidth',lw); m_plot(LON(i_gcp(n),j_gcp(n)),LAT(i_gcp(n),j_gcp(n)),'rx','MarkerSize',ms,'linewidth',lw);
end end
...@@ -118,7 +122,7 @@ end ...@@ -118,7 +122,7 @@ end
clear LON LAT X Y clear LON LAT X Y
m_grid_old('box','fancy','fontsize',fs); m_grid('box','fancy','fontsize',fs);
%m_gshhs('f','patch', 'gray'); %m_gshhs('f','patch', 'gray');
%print('g_rect_drone_1', '-dpng') %print('g_rect_drone_1', '-dpng')
if nargout > 1 if nargout > 1
......
function g_viz_lab(imgFname,outputFname); function g_viz_lab(imgFname,rectFile);
% Set some plotting parameters % Set some plotting parameters
ms = 10; % Marker Size ms = 10; % Marker Size
fs = 10; % Font size fs = 10; % Font size
lw = 2; % Line width lw = 2; % Line width
load(outputFname); load(rectFile);
lon_min = min(lon_gcp);
lon_max = max(lon_gcp);
lat_min = min(lat_gcp);
lat_max = max(lat_gcp);
lon_min = min(lon_min,LON0);
lon_max = max(lon_max,LON0);
lat_min = min(lat_min,LAT0);
lat_max = max(lat_max,LAT0);
% Determine the region to plot, delimited by the GCP and the camera
% position. Add a factor (fac) all around
fac = 0.1; fac = 0.1;
lon_min= lon_min - fac*abs(lon_max-lon_min); lon_min = min([lon_gcp,LON0]);
lon_max= lon_max + fac*abs(lon_max-lon_min); lon_max = max([lon_gcp,LON0]);
lat_min= lat_min - fac*abs(lat_max-lat_min); lat_min = min([lat_gcp,LAT0]);
lat_max= lat_max + fac*abs(lat_max-lat_min); lat_max = max([lat_gcp,LAT0]);
lon_min = lon_min - fac*abs(lon_max - lon_min);
lon_max = lon_max + fac*abs(lon_max - lon_min);
lat_min = lat_min - fac*abs(lat_max - lat_min);
lat_max = lat_max + fac*abs(lat_max - lat_min);
rgb0 = double(imread(imgFname))/255; rgb0 = double(imread(imgFname))/255;
...@@ -35,18 +33,23 @@ int = int'; ...@@ -35,18 +33,23 @@ int = int';
hold on; hold on;
X = LON;
Y = LAT;
colormap(gray); colormap(gray);
h = pcolor(X,Y,int); pcolor(LON,LAT,int);
shading('flat'); shading('flat');
plot(LON0,LAT0,'kx','markersize',ms,'linewidth',lw); % Camera location plot(LON0,LAT0,'kx','markersize',ms,'linewidth',lw); % Camera location
%% Plot GCPs and ICPs. %% Plot GCPs and ICPs.
for n=1:length(i_gcp) for n=1:length(i_gcp)
plot(lon_gcp(n),lat_gcp(n),'bo','markersize',ms,'linewidth',lw);
plot(LON(i_gcp(n),j_gcp(n)),LAT(i_gcp(n),j_gcp(n)),'rx','MarkerSize',ms,'linewidth',lw); % Plot the original GCPs that may have elevations
plot(lon_gcp0(n),lat_gcp0(n),'ko','markersize',ms,'linewidth',lw);
% Plot the projected GCPs that are actually used for the minimization
plot(lon_gcp(n),lat_gcp(n),'bo','markersize',ms,'linewidth',lw);
% Plot the Image Control Points once georectified
plot(LON(i_gcp(n),j_gcp(n)),LAT(i_gcp(n),j_gcp(n)),'rx','MarkerSize',ms,'linewidth',lw);
end end
axis([lon_min lon_max lat_min lat_max]);
\ No newline at end of file
function g_roi2(imgFname)
% G_ROI is a function to determine regions of interest in an image.
%
% This function allows the user to define a series of polygons
% on an image in order to define regions of interest (roi) for
% image stabilization. The result is a 2D matrix roi with 1s and 0s.
% Just follow the instructions.
%
% Input: imgFname: the image filename
% Output: The 2D matrix roi written to filename roi.mat
%
% ** There is tips to modifie and adjuste the roi before saving it in the
% help menu of the impoly function.
% Example : Hold the button A and click on the polygon border to add
% points.
%
% Author: Daniel Bourgault - 2011
%
% Updated : - 11/05/19 - Show the lines while creating the polygon.
% Updated : - 08/08/19 - Enable modification of the polygon before saving.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Reading reference images
im = imread(imgFname);
[m,n,~] = size(im);
roi(1:m,1:n) = 0; % Create ROI matrix
%% Generating Region of Interest
imagesc(im)
hold on
colormap(gray);
continue_draw = 'y';
while continue_draw == 'y'
% Instructions
fprintf(' Make a polygon with left click on the mouse\n')
fprintf(' Right click to link the last and first point\n')
fprintf(' Double click on the polygon when you are done arranging points\n')
fprintf(' You will have the option to make more polygons when done with this one\n')
% Drawing
h=impoly;
wait(h);
Mask = createMask(h);
roi = roi+Mask;
continue_draw = input('Draw another polygon (y/n) ? ','s');
end
hold off
ij = roi > 1;
roi(ij) = 1;
% Final figure
figure(2)
imagesc(roi)
save([imgFname(1:end-4),'_roi.mat'],'roi','imgFname');
\ No newline at end of file
% M_Map - mapping toolbox (Author: rich@eos.ubc.ca)
% Version 1.4m Feb 2020
%
% You have collected your data, loaded it into Matlab, analyzed
% everything to death, and now you want to make a simple map showing
% how it relates to the world.
%
% But you can't.
%
% Instead you have to figure out how to save all your data, and
% then read it into a mapping program, and then spend all that extra
% time figuring out why the mapping program doesn't give you what
% you expected it would...
%
% No more!
%
% Announcing M_Map v1.4!
%
% M_Map is a set of mapping tools written for Matlab v5. These include:
%
% 1. Routines to project data in 18 different spherical
% projections (and determine inverse mappings)
% 2. A grid generation routine to make nice axes with
% limits either in long/lat terms or in planar
% X/Y terms.
% 3. A coastline database (with 1/4 degree resolution)
% 4. A global elevation database (1 degree resolution)
% 5. Hooks into freely available high-resolution coastlines and
% bathymetry/topography.
%
% M_Map v1.4 is available via the web at
%
% http://www.eos.ubc.ca/~rich/
%
%
% Toolbox contents
%
% Contents.m - This file
% m_demo.m - demonstrates a few different maps.
%
% User-callable functions
%
% m_proj.m - initializes projections
% m_coord.m - sets geomagnetic or geographic coordinate system
%
% m_grid.m - draws grids
% m_utmgrid.m - draws a UTM grid for UTM projection maps
% m_scale.m - forces map to a given scale.
% m_ruler.m - draws a scale ruler
% m_northarrow.m - draws a north arrow
%
% m_ungrid.m - erases map elements (if you want to change parameters)
%
% m_coast.m - draws a coastline
% m_elev.m - draws elevation data from 1 degree database
% m_tbase.m - draws elevation data from 5-minute TerrainBase database
% m_etopo2.m - draws elevation data from ETOPO2 database
% m_gshhs.m - draws coastline from GSHHS with specified resolution
% m_gshhs_c.m - draws coastline from GSHHS crude database
% m_gshhs_l.m - draws coastline from GSHHS low-resolution database
% m_gshhs_i.m - draws coastline from GSHHS intermediate-resolution database
% m_gshhs_h.m - draws coastline from GSHHS high-resolution database
% m_gshhs_f.m - draws coastline from GSHHS full database
% m_plotbndry.m - draws a political boundary from the DCW
% m_usercoast.m - draws a coastline using a user-specified subset database.
% m_shaperead.m - reads ESRI shapefiles
%
% m_plot.m - draws line data in map coords
% m_line.m - draws line data in map coords
% m_text.m - adds text data in map coords
% m_legend.m - draws a legend box
% m_quiver.m - draws arrows for vector data
% m_contour.m - draws contour lines for gridded data
% m_contourf.m - draws filled contours
% m_patch.m - draws patch data
% m_pcolor.m - draws pcolor data
% m_image.m - draws image data
% m_streamline.m - draws streamlines
% m_scatter.m - draws scatter plot
% m_annotation.m - annotation lines/boxes/text
% m_ginput.m - gets points in a ginput-like way (only better)
% m_shadedrelief.m-shaded relief mapping.
%
% m_track.m - draws annotated tracklines
% m_hatch.m - hatched or speckled patches.
% m_range_ring.m - draws range rings (spherical coords)
% m_ellipse.m - draws tidal ellipses (most requested ocean feature!)
% m_windrose.m - draws wind rose diagrams at specified locations.
%
% m_ll2xy.m - converts from long/lat to map coordinates
% m_xy2ll.m - converts from map coordinates to long/lat
%
% m_geo2mag.m - converts from long/lat to geomagnetic coordinates
% m_mag2geo.m - converts from geomagnetic coordinates to long/lat
%
% m_lldist - spherical distance/geodesics between points (long/lat coordinates)
% m_xydist - spherical distance between points (map projection coordinates)
%
% m_fdist - ellipsoidal geodesic forward calculation
% m_idist - ellipsoidal geodesic inverse calculation
% m_geodesic - points along ellipsoidal geodesics
%
% m_tba2b.m - used in installing high-resolution elevation database.
%
% m_vec.m - fancy arrows
% m_windbarb.m - barbed wind arrows
%
% m_contfbar.m - draws colorbars for contourf plots
% m_colmap.m - useful perceptually uniform colourmaps.
% mygrid_sand2.m - reads Sandwell and Smith bathymetry file
%
% wysiwyg.m - Sets figure window to match size/aspect of printed output
%
% Internal functions (not meant to be user-callable)
%
% private/mp_azim.m - azimuthal projections
% private/mp_cyl.m - cylindrical projections (equatorial)
% private/mp_conic.m - conic projections
% private/mp_tmerc.m - transverse cylindrical projections
% private/mp_utm.m - elliptical universal transverse cylindrical projections
% private/mp_omerc.m - oblique cylindrical projection
%
% private/mu_util.m - various utility routines
% private/mu_coast.m - routines to handle coastlines.
%
% private/mc_coords.m - coordinate systems based on different poles.
% private/mc_igrf.m - parameters for IGRF geomagnetic coord systems.