Merge pull request #3616 from marvins:gdal-fixes

This commit is contained in:
Vadim Pisarevsky 2015-01-20 12:31:14 +00:00
commit f647054c8c
5 changed files with 55 additions and 37 deletions

View File

@ -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
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
addition, we will show some an example of how OpenCV can use this data for novel and interesting
purposes.
@ -13,8 +13,8 @@ Goals
The primary objectives for this tutorial:
- How to use OpenCV 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 satellite imagery.
- 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
image to find elevations for each pixel.
- Show a basic, easy-to-implement example of a terrain heat map.
@ -54,9 +54,9 @@ signed shorts.
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
is accurate enough to make the point. A better coordinate system would be Universal Transverse
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.
[<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)
![](images/gdal_output.jpg)
![Input Image](images/gdal_output.jpg)
![](images/gdal_heat-map.jpg)
![Heat Map](images/gdal_heat-map.jpg)
![](images/gdal_flood-zone.jpg)
![Heat Map Overlay](images/gdal_flood-zone.jpg)

View File

@ -90,6 +90,8 @@ enum { IMWRITE_PNG_STRATEGY_DEFAULT = 0,
/** @brief Loads an image from a file.
@anchor imread
@param filename Name of file to be loaded.
@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

View File

@ -38,10 +38,17 @@
// the use of this software, even if advised of the possibility of such damage.
//
//M*/
#include "grfmt_gdal.hpp"
#include "precomp.hpp"
// GDAL Macros
#include "cvconfig.h"
#ifdef HAVE_GDAL
// Our Header
#include "grfmt_gdal.hpp"
/// C++ Standard Libraries
#include <iostream>
#include <stdexcept>
@ -195,7 +202,10 @@ GdalDecoder::~GdalDecoder(){
/**
* Convert data range
*/
double range_cast( const GDALDataType& gdalType, const int& cvDepth, const double& value ){
double range_cast( const GDALDataType& gdalType,
const int& cvDepth,
const double& value )
{
// uint8 -> uint8
if( gdalType == GDT_Byte && cvDepth == CV_8U ){

View File

@ -42,16 +42,15 @@
#ifndef __GRFMT_GDAL_HPP__
#define __GRFMT_GDAL_HPP__
/// OpenCV FMT Base Type
#include "grfmt_base.hpp"
/// Macro to make sure we specified GDAL in CMake
#ifdef HAVE_GDAL
/// C++ Libraries
#include <iostream>
/// OpenCV Libraries
#include "grfmt_base.hpp"
#include "precomp.hpp"
/// Geospatial Data Abstraction Library
#include <gdal/cpl_conv.h>
#include <gdal/gdal_priv.h>
@ -61,6 +60,13 @@
/// Start of CV Namespace
namespace cv {
/**
* Convert GDAL Pixel Range to OpenCV Pixel Range
*/
double range_cast( const GDALDataType& gdalType,
const int& cvDepth,
const double& value );
/**
* Convert GDAL Palette Interpretation to OpenCV Pixel Type
*/

View File

@ -1,13 +1,13 @@
/**
/*
* 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/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
/// C++ Standard Libraries
// C++ Standard Libraries
#include <cmath>
#include <iostream>
#include <stdexcept>
@ -15,22 +15,22 @@
using namespace std;
/// define the corner points
/// Note that GDAL can natively determine this
// define the corner points
// Note that GDAL library can natively determine this
cv::Point2d tl( -122.441017, 37.815664 );
cv::Point2d tr( -122.370919, 37.815311 );
cv::Point2d bl( -122.441533, 37.747167 );
cv::Point2d br( -122.3715, 37.746814 );
/// determine dem corners
// determine dem corners
cv::Point2d dem_bl( -122.0, 38);
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;
/// List of all function prototypes
// List of all function prototypes
cv::Point2d lerp( const cv::Point2d&, const cv::Point2d&, 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
* p1 - Point 1
* 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));
}
/**
/*
* Interpolate Colors
*/
template <typename DATATYPE, int N>
@ -69,7 +69,7 @@ cv::Vec<DATATYPE,N> lerp( cv::Vec<DATATYPE,N> const& minColor,
return output;
}
/**
/*
* Compute the dem color
*/
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);
}
/**
/*
* Given a pixel coordinate and the size of the input image, compute the pixel location
* on the DEM image.
*/
@ -122,7 +122,7 @@ cv::Point2d world2dem( cv::Point2d const& coordinate, const cv::Size& dem_size
return output;
}
/**
/*
* Convert a pixel coordinate to world coordinates
*/
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 );
}
/**
/*
* Add color to a specific pixel color value
*/
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
*/
int main( int argc, char* argv[] ){
/**
/*
* Check input arguments
*/
if( argc < 3 ){
@ -163,22 +163,22 @@ int main( int argc, char* argv[] ){
return 1;
}
/// 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
/// at the top of this file
// 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
// at the top of this file
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 );
/// create our output products
// create our output products
cv::Mat output_dem( 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"); }
/// 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
// 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));