mirror of
https://github.com/opencv/opencv.git
synced 2024-11-24 19:20:28 +08:00
Merge pull request #3616 from marvins:gdal-fixes
This commit is contained in:
commit
f647054c8c
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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 ){
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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));
|
||||
|
Loading…
Reference in New Issue
Block a user