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

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;
dtheta = 20.0;
% Order of the polynomial correction (0, 1 or 2)
polyOrder = 1;
polyOrder = 0;
% To save memory calculation can be done in single precision.
% For higher precision set the variable 'precision' to 'double';
precision = 'double';
% Ground Control Points (GCP).
% The data must come right after the gcpData = true
gcpData = true;
360 829 -70.561367 47.303783
54 719 -70.54500 47.335
99 661 -70.505 47.375
452 641 -70.435 47.389
429 633 -70.418 47.408
816 644 -70.393 47.368
\ No newline at end of file
360 829 -70.561367 47.303783 0
54 719 -70.54500 47.335 0
99 661 -70.505 47.375 0
452 641 -70.435 47.389 0
429 633 -70.418 47.408 0
816 644 -70.393 47.368 0
\ No newline at end of file
......@@ -45,18 +45,18 @@ precision = 'double';
% Ground Control Points (GCP).
gcpData = true;
2999 226 0.500 0.00
1694 220 1.500 0.00
528 677 2.290 0.50
289 1231 2.290 1.00
3819 686 0.000 0.50
4018 1266 0.000 1.00
2566 1235 0.890 0.99
3806 2118 0.255 1.56
4131 1580 0.000 1.23
521 2548 1.910 1.82
248 2328 2.060 1.71
14 1868 2.290 1.46
2999 226 0.500 0.00 0
1694 220 1.500 0.00 0
528 677 2.290 0.50 0
289 1231 2.290 1.00 0
3819 686 0.000 0.50 0
4018 1266 0.000 1.00 0
2566 1235 0.890 0.99 0
3806 2118 0.255 1.56 0
4131 1580 0.000 1.23 0
521 2548 1.910 1.82 0
248 2328 2.060 1.71 0
14 1868 2.290 1.46 0
......
......@@ -4,7 +4,7 @@ function errGeoFit = g_error_geofit(cv,imgWidth,imgHeight,xp,yp,ic,jc,...
hfovGuess,lambdaGuess,phiGuess,HGuess,thetaGuess,...
dhfov,dlambda,dphi,dH,dtheta,...
LON0,LAT0,...
i_gcp,j_gcp,lon_gcp,lat_gcp,...
i_gcp,j_gcp,lon_gcp0,lat_gcp0,h_gcp,...
theOrder,field);
......@@ -20,7 +20,6 @@ end
[LON LAT] = g_pix2ll(xp,yp,imgWidth,imgHeight,ic,jc,...
hfov,lambda,phi,theta,H,LON0,LAT0,field);
% Calculate the error between ground control points (GCPs)
% and image control points once georectified.
%
......@@ -35,8 +34,11 @@ ngcp = length(i_gcp);
ngcpFinite = 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.
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
if abs(H - HGuess) > dH; 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);
fx = (imgWidth/2)/tand(hfov/2);
fy = (imgHeight/2)/tand(vfov/2);
% Subtract the principal point
x_p = xp - x_c + (jc);
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
% 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_land = 0;
land_color = [241 235 144]/255;
......@@ -34,30 +40,21 @@ if length(varargin) > 1
end
end
% Set some plotting parameters
ms = 10; % Marker Size
fs = 10; % Font size
lw = 2; % Line width
% Load the georectification file
load(rectFile);
%p = size(LON,3);
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;
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);
lon_min = min([lon_gcp,LON0]);
lon_max = max([lon_gcp,LON0]);
lat_min = min([lat_gcp,LAT0]);
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;
......@@ -70,19 +67,19 @@ end
clear rgb0;
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]);
hold on;
[X,Y] = m_ll2xy(LON,LAT);
cmap = contrast(int,256);
colormap(cmap);
h = pcolor(X,Y,int);
h = m_pcolor(LON,LAT,int);
shading('interp');
% Uncomment one of these lines if you want the coastline to be plotted.
if show_land
if strcmpi(show_land,'fjord')
......@@ -109,7 +106,14 @@ m_plot(LON0,LAT0,'kx','markersize',ms,'linewidth',lw); % Camera location
%% Plot GCPs and ICPs.
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);
% 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);
end
......@@ -118,7 +122,7 @@ end
clear LON LAT X Y
m_grid_old('box','fancy','fontsize',fs);
m_grid('box','fancy','fontsize',fs);
%m_gshhs('f','patch', 'gray');
%print('g_rect_drone_1', '-dpng')
if nargout > 1
......
function g_viz_lab(imgFname,outputFname);
function g_viz_lab(imgFname,rectFile);
% Set some plotting parameters
ms = 10; % Marker Size
fs = 10; % Font size
lw = 2; % Line width
load(outputFname);
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);
load(rectFile);
% Determine the region to plot, delimited by the GCP and the camera
% position. Add a factor (fac) all around
fac = 0.1;
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);
lon_min = min([lon_gcp,LON0]);
lon_max = max([lon_gcp,LON0]);
lat_min = min([lat_gcp,LAT0]);
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;
......@@ -35,18 +33,23 @@ int = int';
hold on;
X = LON;
Y = LAT;
colormap(gray);
h = pcolor(X,Y,int);
pcolor(LON,LAT,int);
shading('flat');
plot(LON0,LAT0,'kx','markersize',ms,'linewidth',lw); % Camera location
%% Plot GCPs and ICPs.
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
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.
% private/mc_ellips.m - parameters of different ellipsoidal earth models
%
% private/m_coasts.mat- low-res coastline data
%
% HTML documentation
%
% map.html - Home page, examples
% mapug.html - User's guide
% doc/*png - examples.
%
%
% Questions or problems; email me - rich@eos.ubc.ca.
%
% Rich Pawlowicz
% Dept. of Earth, Ocean, Atmospheric Sciences, Univ. of British Columbia,
% 2207 Main Mall, Vancouver, B.C. CANADA V6T 1Z4
% email: rich@eos.ubc.ca
%
%
function h = m_annotation( varargin )
% M_ANNOTATION Creates an annotation object
% M_ANNOTATION Generally passes its arguments through to ANNOTATION,
% bur accepts lon/lat arguments.
%
% ANNOTATION(ANNOTATIONTYPE) creates a default annotation of type
% ANNOTATIONTYPE in the current figure. ANNOTATIONTYPE may be one of the
% following:
% 'rectangle'
% 'ellipse'
% 'textbox'
% 'line'
% 'arrow'
% 'doublearrow' = two headed arrow
% 'textarrow' = arrow with text at tail end
%
% ANNOTATION('rectangle',POSITION) creates a rectangle annotation at the
% position specified in normalized figure units by the vector POSITION
% ANNOTATION('ellipse',POSITION) creates an ellise annotation at the
% position specified in normalized figure units by the vector POSITION
% ANNOTATION('textbox',POSITION) creates a textbox annotation at the
% position specified in normalized figure units by the vector POSITION
%
% POSTITION = [LON_LEFT LAT_BOTTOM WIDTH HEIGHT] where WIDTH and HEIGHT
% are normalized to the size of the axis.
%
% ANNOTATION('line',LON,LAT) creates a line annotation with endpoints
% specified in normalized figure coordinates by the vectors LON and LAT
% ANNOTATION('arrow',LON,LAT) creates an arrow annotation with endpoints
% specified in normalized figure coordinates by the vectors LON and LAT.
% LON(1) and LAT(1) specify the position of the tail end of the arrow
% and LON(2) and LAT(2) specify the position at the tip of the arrow head.
% ANNOTATION('doublearrow',LON,LAT) creates a doublearrow annotation with
% endpoints specified in normalized figure coordinates by the vectors LON
% and LAT.
% ANNOTATION('textarrow',LON,LAT) creates a textarrow annotation with
% endpoints specified in normalized figure coordinates by the vectors LON
% and LAT. LON(1) and LAT(1) specify the position of the tail end of the
% arrow and LON(2) and LAT(2) specify the position at the tip of the arrow
% head.
%
% You should (optionally) call ORIENT first, and then WYSIWYG to see how
% the printed version will look, because otherwise the location of the
% annotation may not look right.
%
% M_ANNOTATION(HANDLE,...) creates the annotation in the AXES specified
% by HANDLE (note - ANNOTATION requires a FIGURE handle)
%
% H=M_ANNOTATION(...) returns a handle to the annotation object
%
% The arguments to ANNOTATION can be followed by parameter/value pairs to
% specify additional properties of the annotation object. The X and Y or