为实现这些目标,以下代码将数字高程模型以及旧金山的GeoTiff影像作为输入。图像和DEM数据经过处理后,生成图像的地形热力图,并标注出海湾水位上升10米、50米和100米时会受影响的城市区域。
#include <cmath>
#include <iostream>
#include <stdexcept>
#include <vector>
std::vector<std::pair<cv::Vec3b,double> > color_range;
((1-t)*p1.
y) + (t*p2.
y));
}
template <typename DATATYPE, int N>
double const& t ){
for( int i=0; i<N; i++ ){
output[i] = (
uchar)(((1-t)*minColor[i]) + (t * maxColor[i]));
}
return output;
}
cv::Vec3b get_dem_color(
const double& elevation ){
if( elevation < color_range[0].second ){
return color_range[0].first;
}
if( elevation > color_range.back().second ){
return color_range.back().first;
}
int idx=0;
double t = 0;
for( int x=0; x<(int)(color_range.size()-1); x++ ){
if( elevation < color_range[x+1].second ){
idx=x;
t = (color_range[x+1].second - elevation)/
(color_range[x+1].second - color_range[x].second);
break;
}
}
return lerp( color_range[idx].first, color_range[idx+1].first, t);
}
double demRatioX = ((dem_tr.x - coordinate.
x)/(dem_tr.x - dem_bl.x));
double demRatioY = 1-((dem_tr.y - coordinate.
y)/(dem_tr.y - dem_bl.y));
output.
x = demRatioX * dem_size.
width;
output.
y = demRatioY * dem_size.
height;
return output;
}
double rx = (double)x /
size.width;
double ry = (double)y /
size.height;
return lerp( leftSide, rightSide, rx );
}
if( pix[0] + b < 255 && pix[0] + b >= 0 ){ pix[0] += b; }
if( pix[1] + g < 255 && pix[1] + g >= 0 ){ pix[1] += g; }
if( pix[2] + r < 255 && pix[2] + r >= 0 ){ pix[2] += r; }
}
int main(
int argc,
char* argv[] ){
if( argc < 3 ){
cout << "usage: " << argv[0] << " <image_name> <dem_model_name>" << endl;
return -1;
}
if( dem.
type() !=
CV_16SC1 ){
throw std::runtime_error(
"DEM image type must be CV_16SC1"); }
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( 110, 220, 110), 0.25));
color_range.push_back( std::pair<cv::Vec3b,double>(
cv::Vec3b( 150, 250, 230), 20));
color_range.push_back( std::pair<cv::Vec3b,double>(
cv::Vec3b( 160, 220, 200), 75));
color_range.push_back( std::pair<cv::Vec3b,double>(
cv::Vec3b( 220, 190, 170), 100));
color_range.push_back( std::pair<cv::Vec3b,double>(
cv::Vec3b( 250, 180, 140), 200));
double minElevation = -10;
for(
int y=0; y<image.
rows; y++ ){
for(
int x=0; x<image.
cols; x++ ){
double dz;
if( dem_coordinate.
x >= 0 && dem_coordinate.
y >= 0 &&
dem_coordinate.
x < dem.
cols && dem_coordinate.
y < dem.
rows ){
dz = dem.
at<
short>(dem_coordinate);
}else{
dz = minElevation;
}
if( dz < 10 ){
add_color( output_dem_flood.at<
cv::Vec3b>(y,x), 90, 0, 0 );
}
else if( dz < 50 ){
add_color( output_dem_flood.at<
cv::Vec3b>(y,x), 0, 90, 0 );
}
else if( dz < 100 ){
add_color( output_dem_flood.at<
cv::Vec3b>(y,x), 0, 0, 90 );
}
}}
return 0;
}
MatSize size
定义 mat.hpp:2187
_Tp & at(int i0=0)
返回指定数组元素的引用。
int rows
当矩阵维度超过2时,为行数和列数,或(-1, -1)
定义 mat.hpp:2165
int type() const
返回矩阵元素的类型。
_Tp y
点的 y 坐标
定义 types.hpp:202
_Tp x
点的 x 坐标
定义 types.hpp:201
用于指定图像或矩形大小的模板类。
Definition types.hpp:335
_Tp height
高度
Definition types.hpp:363
_Tp width
宽度
Definition types.hpp:362
用于短数值向量的模板类,是Matx的一个特例。
定义 matx.hpp:369
Point_< double > Point2d
定义 types.hpp:208
#define CV_16SC1
定义 interface.h:106
@ IMREAD_ANYDEPTH
如果设置,当输入具有相应的深度时返回16位/32位图像,否则将其转换为...
定义 imgcodecs.hpp:74
@ IMREAD_LOAD_GDAL
如果设置,使用 GDAL 驱动程序加载图像。
定义 imgcodecs.hpp:76
@ IMREAD_COLOR
与 IMREAD_COLOR_BGR 相同。
定义 imgcodecs.hpp:73
CV_EXPORTS_W bool imwrite(const String &filename, InputArray img, const std::vector< int > ¶ms=std::vector< int >())
将图像保存到指定文件。
CV_EXPORTS_W Mat imread(const String &filename, int flags=IMREAD_COLOR_BGR)
从文件加载图像。
int main(int argc, char *argv[])
定义 highgui_qt.cpp:3
GOpaque< Size > size(const GMat &src)
从 Mat 获取维度。
加载数字高程模型时,每个像素的实际数值至关重要,不能进行缩放或截断。例如,在图像数据中,一个值为1的双精度像素与一个值为255的无符号字符像素在外观上是相同的。而对于地形数据,像素值代表以米为单位的高程。为了确保OpenCV保留原始值,请在imread中使用GDAL标志并结合ANYDEPTH标志。
如果您事先知道正在加载的DEM模型类型,那么使用断言或其他机制测试 Mat::type() 或 Mat::depth() 可能是稳妥的做法。NASA或DOD规范文档可以提供各种高程模型的输入类型。主要类型,SRTM和DTED,都是带符号的短整型。
地理坐标系是球形坐标系,这意味着将其与笛卡尔数学结合使用在技术上是不正确的。本演示使用它们是为了提高可读性,并且其精度足以说明问题。更好的坐标系将是通用横轴墨卡托(Universal Transverse Mercator)。
\f$> gdalinfo N37W123.hgt
Driver: SRTMHGT/SRTMHGT File Format
Files: N37W123.hgt
Size is 3601, 3601
Coordinate System is
GEOGCS["WGS 84",
DATUM["WGS_1984",
... more output ...
Corner Coordinates
Upper Left (-123.0001389, 38.0001389) (123d 0' 0.50"W, 38d 0' 0.50"N)
Lower Left (-123.0001389, 36.9998611) (123d 0' 0.50"W, 36d59'59.50"N)
Upper Right (-121.9998611, 38.0001389) (121d59'59.50"W, 38d 0' 0.50"N)
Lower Right (-121.9998611, 36.9998611) (121d59'59.50"W, 36d59'59.50"N)
Center (-122.5000000, 37.5000000) (122d30' 0.00"W, 37d30' 0.00"N)
... more output ...