Updated gdal tutorial to include comments.
This commit is contained in:
parent
9a1a9d9aff
commit
91fbe00caa
@ -3,7 +3,7 @@ Reading Geospatial Raster files with GDAL {#tutorial_raster_io_gdal}
|
|||||||
|
|
||||||
Geospatial raster data is a heavily used product in Geographic Information Systems and
|
Geospatial raster data is a heavily used product in Geographic Information Systems and
|
||||||
Photogrammetry. Raster data typically can represent imagery and Digital Elevation Models (DEM). The
|
Photogrammetry. Raster data typically can represent imagery and Digital Elevation Models (DEM). The
|
||||||
standard library for loading GIS imagery is the Geographic Data Abstraction Library (GDAL). In this
|
standard library for loading GIS imagery is the Geographic Data Abstraction Library [(GDAL)](http://www.gdal.org). In this
|
||||||
example, we will show techniques for loading GIS raster formats using native OpenCV functions. In
|
example, we will show techniques for loading GIS raster formats using native OpenCV functions. In
|
||||||
addition, we will show some an example of how OpenCV can use this data for novel and interesting
|
addition, we will show some an example of how OpenCV can use this data for novel and interesting
|
||||||
purposes.
|
purposes.
|
||||||
@ -13,8 +13,8 @@ Goals
|
|||||||
|
|
||||||
The primary objectives for this tutorial:
|
The primary objectives for this tutorial:
|
||||||
|
|
||||||
- How to use OpenCV imread to load satellite imagery.
|
- How to use OpenCV [imread](@ref imread) to load satellite imagery.
|
||||||
- How to use OpenCV imread to load SRTM Digital Elevation Models
|
- How to use OpenCV [imread](@ref imread) to load SRTM Digital Elevation Models
|
||||||
- Given the corner coordinates of both the image and DEM, correllate the elevation data to the
|
- Given the corner coordinates of both the image and DEM, correllate the elevation data to the
|
||||||
image to find elevations for each pixel.
|
image to find elevations for each pixel.
|
||||||
- Show a basic, easy-to-implement example of a terrain heat map.
|
- Show a basic, easy-to-implement example of a terrain heat map.
|
||||||
@ -54,9 +54,9 @@ signed shorts.
|
|||||||
Notes
|
Notes
|
||||||
-----
|
-----
|
||||||
|
|
||||||
### Lat/Lon (Geodetic) Coordinates should normally be avoided
|
### Lat/Lon (Geographic) Coordinates should normally be avoided
|
||||||
|
|
||||||
The Geodetic Coordinate System is a spherical coordinate system, meaning that using them with
|
The Geographic Coordinate System is a spherical coordinate system, meaning that using them with
|
||||||
Cartesian mathematics is technically incorrect. This demo uses them to increase the readability and
|
Cartesian mathematics is technically incorrect. This demo uses them to increase the readability and
|
||||||
is accurate enough to make the point. A better coordinate system would be Universal Transverse
|
is accurate enough to make the point. A better coordinate system would be Universal Transverse
|
||||||
Mercator.
|
Mercator.
|
||||||
@ -94,8 +94,8 @@ Below is the output of the program. Use the first image as the input. For the DE
|
|||||||
the SRTM file located at the USGS here.
|
the SRTM file located at the USGS here.
|
||||||
[<http://dds.cr.usgs.gov/srtm/version2_1/SRTM1/Region_04/N37W123.hgt.zip>](http://dds.cr.usgs.gov/srtm/version2_1/SRTM1/Region_04/N37W123.hgt.zip)
|
[<http://dds.cr.usgs.gov/srtm/version2_1/SRTM1/Region_04/N37W123.hgt.zip>](http://dds.cr.usgs.gov/srtm/version2_1/SRTM1/Region_04/N37W123.hgt.zip)
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
|
@ -90,6 +90,8 @@ enum { IMWRITE_PNG_STRATEGY_DEFAULT = 0,
|
|||||||
|
|
||||||
/** @brief Loads an image from a file.
|
/** @brief Loads an image from a file.
|
||||||
|
|
||||||
|
@anchor imread
|
||||||
|
|
||||||
@param filename Name of file to be loaded.
|
@param filename Name of file to be loaded.
|
||||||
@param flags Flags specifying the color type of a loaded image:
|
@param flags Flags specifying the color type of a loaded image:
|
||||||
- CV_LOAD_IMAGE_ANYDEPTH - If set, return 16-bit/32-bit image when the input has the
|
- CV_LOAD_IMAGE_ANYDEPTH - If set, return 16-bit/32-bit image when the input has the
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
/**
|
/*
|
||||||
* gdal_image.cpp -- Load GIS data into OpenCV Containers using the Geospatial Data Abstraction Library
|
* gdal_image.cpp -- Load GIS data into OpenCV Containers using the Geospatial Data Abstraction Library
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/// OpenCV Headers
|
// OpenCV Headers
|
||||||
#include "opencv2/core/core.hpp"
|
#include "opencv2/core/core.hpp"
|
||||||
#include "opencv2/imgproc/imgproc.hpp"
|
#include "opencv2/imgproc/imgproc.hpp"
|
||||||
#include "opencv2/highgui/highgui.hpp"
|
#include "opencv2/highgui/highgui.hpp"
|
||||||
|
|
||||||
/// C++ Standard Libraries
|
// C++ Standard Libraries
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
@ -15,22 +15,22 @@
|
|||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
/// define the corner points
|
// define the corner points
|
||||||
/// Note that GDAL can natively determine this
|
// Note that GDAL library can natively determine this
|
||||||
cv::Point2d tl( -122.441017, 37.815664 );
|
cv::Point2d tl( -122.441017, 37.815664 );
|
||||||
cv::Point2d tr( -122.370919, 37.815311 );
|
cv::Point2d tr( -122.370919, 37.815311 );
|
||||||
cv::Point2d bl( -122.441533, 37.747167 );
|
cv::Point2d bl( -122.441533, 37.747167 );
|
||||||
cv::Point2d br( -122.3715, 37.746814 );
|
cv::Point2d br( -122.3715, 37.746814 );
|
||||||
|
|
||||||
/// determine dem corners
|
// determine dem corners
|
||||||
cv::Point2d dem_bl( -122.0, 38);
|
cv::Point2d dem_bl( -122.0, 38);
|
||||||
cv::Point2d dem_tr( -123.0, 37);
|
cv::Point2d dem_tr( -123.0, 37);
|
||||||
|
|
||||||
/// range of the heat map colors
|
// range of the heat map colors
|
||||||
std::vector<std::pair<cv::Vec3b,double> > color_range;
|
std::vector<std::pair<cv::Vec3b,double> > color_range;
|
||||||
|
|
||||||
|
|
||||||
/// List of all function prototypes
|
// List of all function prototypes
|
||||||
cv::Point2d lerp( const cv::Point2d&, const cv::Point2d&, const double& );
|
cv::Point2d lerp( const cv::Point2d&, const cv::Point2d&, const double& );
|
||||||
|
|
||||||
cv::Vec3b get_dem_color( const double& );
|
cv::Vec3b get_dem_color( const double& );
|
||||||
@ -43,7 +43,7 @@ void add_color( cv::Vec3b& pix, const uchar& b, const uchar& g, const uchar& r )
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* Linear Interpolation
|
* Linear Interpolation
|
||||||
* p1 - Point 1
|
* p1 - Point 1
|
||||||
* p2 - Point 2
|
* p2 - Point 2
|
||||||
@ -54,7 +54,7 @@ cv::Point2d lerp( cv::Point2d const& p1, cv::Point2d const& p2, const double& t
|
|||||||
((1-t)*p1.y) + (t*p2.y));
|
((1-t)*p1.y) + (t*p2.y));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* Interpolate Colors
|
* Interpolate Colors
|
||||||
*/
|
*/
|
||||||
template <typename DATATYPE, int N>
|
template <typename DATATYPE, int N>
|
||||||
@ -69,7 +69,7 @@ cv::Vec<DATATYPE,N> lerp( cv::Vec<DATATYPE,N> const& minColor,
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* Compute the dem color
|
* Compute the dem color
|
||||||
*/
|
*/
|
||||||
cv::Vec3b get_dem_color( const double& elevation ){
|
cv::Vec3b get_dem_color( const double& elevation ){
|
||||||
@ -103,7 +103,7 @@ cv::Vec3b get_dem_color( const double& elevation ){
|
|||||||
return lerp( color_range[idx].first, color_range[idx+1].first, t);
|
return lerp( color_range[idx].first, color_range[idx+1].first, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* Given a pixel coordinate and the size of the input image, compute the pixel location
|
* Given a pixel coordinate and the size of the input image, compute the pixel location
|
||||||
* on the DEM image.
|
* on the DEM image.
|
||||||
*/
|
*/
|
||||||
@ -122,7 +122,7 @@ cv::Point2d world2dem( cv::Point2d const& coordinate, const cv::Size& dem_size
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* Convert a pixel coordinate to world coordinates
|
* Convert a pixel coordinate to world coordinates
|
||||||
*/
|
*/
|
||||||
cv::Point2d pixel2world( const int& x, const int& y, const cv::Size& size ){
|
cv::Point2d pixel2world( const int& x, const int& y, const cv::Size& size ){
|
||||||
@ -139,7 +139,7 @@ cv::Point2d pixel2world( const int& x, const int& y, const cv::Size& size ){
|
|||||||
return lerp( leftSide, rightSide, rx );
|
return lerp( leftSide, rightSide, rx );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* Add color to a specific pixel color value
|
* Add color to a specific pixel color value
|
||||||
*/
|
*/
|
||||||
void add_color( cv::Vec3b& pix, const uchar& b, const uchar& g, const uchar& r ){
|
void add_color( cv::Vec3b& pix, const uchar& b, const uchar& g, const uchar& r ){
|
||||||
@ -150,12 +150,12 @@ void add_color( cv::Vec3b& pix, const uchar& b, const uchar& g, const uchar& r )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* Main Function
|
* Main Function
|
||||||
*/
|
*/
|
||||||
int main( int argc, char* argv[] ){
|
int main( int argc, char* argv[] ){
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* Check input arguments
|
* Check input arguments
|
||||||
*/
|
*/
|
||||||
if( argc < 3 ){
|
if( argc < 3 ){
|
||||||
@ -163,22 +163,22 @@ int main( int argc, char* argv[] ){
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// load the image (note that we don't have the projection information. You will
|
// load the image (note that we don't have the projection information. You will
|
||||||
/// need to load that yourself or use the full GDAL driver. The values are pre-defined
|
// need to load that yourself or use the full GDAL driver. The values are pre-defined
|
||||||
/// at the top of this file
|
// at the top of this file
|
||||||
cv::Mat image = cv::imread(argv[1], cv::IMREAD_LOAD_GDAL | cv::IMREAD_COLOR );
|
cv::Mat image = cv::imread(argv[1], cv::IMREAD_LOAD_GDAL | cv::IMREAD_COLOR );
|
||||||
|
|
||||||
/// load the dem model
|
// load the dem model
|
||||||
cv::Mat dem = cv::imread(argv[2], cv::IMREAD_LOAD_GDAL | cv::IMREAD_ANYDEPTH );
|
cv::Mat dem = cv::imread(argv[2], cv::IMREAD_LOAD_GDAL | cv::IMREAD_ANYDEPTH );
|
||||||
|
|
||||||
/// create our output products
|
// create our output products
|
||||||
cv::Mat output_dem( image.size(), CV_8UC3 );
|
cv::Mat output_dem( image.size(), CV_8UC3 );
|
||||||
cv::Mat output_dem_flood( image.size(), CV_8UC3 );
|
cv::Mat output_dem_flood( image.size(), CV_8UC3 );
|
||||||
|
|
||||||
/// for sanity sake, make sure GDAL Loads it as a signed short
|
// for sanity sake, make sure GDAL Loads it as a signed short
|
||||||
if( dem.type() != CV_16SC1 ){ throw std::runtime_error("DEM image type must be CV_16SC1"); }
|
if( dem.type() != CV_16SC1 ){ throw std::runtime_error("DEM image type must be CV_16SC1"); }
|
||||||
|
|
||||||
/// define the color range to create our output DEM heat map
|
// define the color range to create our output DEM heat map
|
||||||
// Pair format ( Color, elevation ); Push from low to high
|
// Pair format ( Color, elevation ); Push from low to high
|
||||||
// Note: This would be perfect for a configuration file, but is here for a working demo.
|
// Note: This would be perfect for a configuration file, but is here for a working demo.
|
||||||
color_range.push_back( std::pair<cv::Vec3b,double>(cv::Vec3b( 188, 154, 46), -1));
|
color_range.push_back( std::pair<cv::Vec3b,double>(cv::Vec3b( 188, 154, 46), -1));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user