You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

400 lines
9.4 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include "stdafx.h"
#include <opencv2\opencv.hpp>
using namespace cv;
#include "GeoTIFFEdit.h"
// tif 图像
#include <ogr_srs_api.h>
#include <ogr_spatialref.h>
#include <gdal.h>
#include <gdal_priv.h>
// 几何校正
#include "SysGeoCorrect.h"
// 保存情报数据为tiff文件
bool SaveQBDataToGeoTIFF(QBStru *qbData, string savePath)
{
try
{
if (qbData == NULL || savePath == "")
{
return false;
}
// 图像数据有效性验证
if (qbData->image.bValid == false)
{
return false;
}
else
{
if ( false == SaveImgStruToGeoTIFF(&qbData->image.geoImg, savePath))
{
if (true == SysGeoCorrectImg(qbData, false)) // 几何校正
{
return SaveImgStruToGeoTIFF(&qbData->image.geoImg, savePath);
}
else
{
return false;
}
}
}
}
catch(cv::Exception &e)
{
string str = e.msg;
return false;
}
catch(...)
{
return false;
}
return true;
}
//功能保存图像结构体至本地文件GeoTiff格式
//输入: 1. qbData 通用图像数据结构体
// 2. savePath Tiff文件保存路径
//输出: 1. 返回值保存成功返回true失败返回false
bool SaveImgStruToGeoTIFF(const ImgStru *Img, string savePath)
{
try
{
if (Img == NULL || savePath == "")
{
return false;
}
// 判断路径后缀的有效性
string postfix = savePath.substr(savePath.rfind('.') + 1, savePath.length());
if ("tif" != postfix)
{
return false;
}
// 图像数据有效性验证
if (Img->ImgWidth <= 0 ||
Img->ImgHeight <= 0 ||
Img->bitcount <= 0 ||
Img->buff == NULL)
{
return false;
}
// 经纬度边界有效性验证
double NorthLat = Img->BoundingBox.NorthLat;
double SouthLat = Img->BoundingBox.SouthLat;
double WestLon = Img->BoundingBox.WestLon;
double EastLon = Img->BoundingBox.EastLon;
// 纬度验证
if (NorthLat > 90 || NorthLat < -90 ||
SouthLat > 90 || SouthLat < -90 ||
NorthLat - SouthLat <= 0)
{
return false;
}
// 经度验证
if (WestLon > 180 || WestLon < -180 ||
EastLon > 180 || EastLon < -180 ||
EastLon - WestLon <= 0)
{
return false;
}
// 数据有效,执行下属操作
int ImgWidth = Img->ImgWidth;
int ImgHeight = Img->ImgHeight;
int Imgchannels = Img->bitcount / 8;
if (Img->bitcount != 8 && Img->bitcount != 24)
{
return false;
}
// 创建临时图像
cv::Mat geoImg;
if (Img->bitcount == 8)
{
geoImg = cv::Mat(ImgHeight, ImgWidth, CV_8UC1);
}
else
{
geoImg = cv::Mat(ImgHeight, ImgWidth, CV_8UC3);
}
// 创建失败,直接返回
if (geoImg.empty() == true)
{
return false;
}
else
{
// 复制数据
int lineByte = ImgWidth * Img->bitcount / 8;
unsigned int imgBufSize = static_cast<unsigned int>(ImgHeight * lineByte);
memcpy(geoImg.data, Img->buff, imgBufSize);
}
// 经纬度 分辨率
double Lon_resolution = (EastLon - WestLon) / ImgWidth;
double Lat_resolution = (SouthLat - NorthLat) / ImgHeight;
// 注册
GDALAllRegister();
CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO");
//创建数据集
GDALDataset* poDstDS = NULL;
char** papszOptions = NULL;
string fomat;
fomat = "GTiff";
GDALDriver *poDriver = GetGDALDriverManager()->GetDriverByName( fomat.c_str());
double adfGeoTransform[6];
adfGeoTransform[0] = WestLon; /* top left x */
adfGeoTransform[1] = Lon_resolution;/* w-e pixel resolution */
adfGeoTransform[2] = 0; /* rotation, 0 if image is "north up" */
adfGeoTransform[3] = NorthLat; /* top left y */
adfGeoTransform[4] = 0; /* rotation, 0 if image is "north up" */
adfGeoTransform[5] = Lat_resolution;/* n-s pixel resolution */
if (Imgchannels == 1)
{
// 创建图像
poDstDS = poDriver->Create( savePath.c_str(), ImgWidth, ImgHeight, 1, GDT_Byte, papszOptions );
//设置椭球体信息
poDstDS->SetGeoTransform( adfGeoTransform );
OGRSpatialReference oSRS;
char* pszWKT = NULL;
oSRS.SetWellKnownGeogCS( "WGS84" );
oSRS.exportToWkt( &pszWKT );
poDstDS->SetProjection( pszWKT );
//遥感的一个波段
GDALRasterBand *poBand = poDstDS->GetRasterBand( 1 );
//分波段输出数据到tiff文件
poBand->RasterIO( GF_Write, 0, 0, ImgWidth, ImgHeight, geoImg.data, ImgWidth, ImgHeight, GDT_Byte, 0, 0 );
GDALFlushCache( poDstDS );
GDALClose( poDstDS );
GetGDALDriverManager()->DeregisterDriver(poDriver);
GDALDestroyDriverManager();
poDstDS = NULL;
poDriver = NULL;
}
else
{
// 创建图像
poDstDS = poDriver->Create( savePath.c_str(), ImgWidth, ImgHeight, 3, GDT_Byte, papszOptions );
//设置椭球体信息
poDstDS->SetGeoTransform( adfGeoTransform );
OGRSpatialReference oSRS;
char* pszWKT = NULL;
oSRS.SetWellKnownGeogCS( "WGS84" );
oSRS.exportToWkt( &pszWKT );
poDstDS->SetProjection( pszWKT );
//遥感的一个波段
GDALRasterBand *poBand1 = poDstDS->GetRasterBand( 1 );
GDALRasterBand *poBand2 = poDstDS->GetRasterBand( 2 );
GDALRasterBand *poBand3 = poDstDS->GetRasterBand( 3 );
std::vector<cv::Mat> planes;
cv::split(geoImg, planes);
//分波段输出数据到tiff文件
poBand1->RasterIO( GF_Write, 0, 0, ImgWidth, ImgHeight, planes[2].data, ImgWidth, ImgHeight, GDT_Byte, 0, 0 );
poBand2->RasterIO( GF_Write, 0, 0, ImgWidth, ImgHeight, planes[1].data, ImgWidth, ImgHeight, GDT_Byte, 0, 0 );
poBand3->RasterIO( GF_Write, 0, 0, ImgWidth, ImgHeight, planes[0].data, ImgWidth, ImgHeight, GDT_Byte, 0, 0 );
GDALFlushCache( poDstDS );
GDALClose( poDstDS );
GetGDALDriverManager()->DeregisterDriver(poDriver);
GDALDestroyDriverManager();
poDstDS = NULL;
poDriver = NULL;
}
return true;
}
catch(cv::Exception &e)
{
string str = e.msg;
return false;
}
catch(...)
{
return false;
}
}
//功能保存图像数据至本地文件GeoTiff格式
//输入: 1. Img OpenCV图像
// 2. LBbox 经纬度边界
// 3. savePath Tiff文件保存路径
//输出: 1. 返回值保存成功返回true失败返回false
bool SaveImgStruToGeoTIFF(cv::Mat& img, GeoBoundingBox& LBbox, string savePath)
{
try
{
// 图像有效性验证
if (img.empty() == true || savePath == "")
{
return false;
}
if (img.type() != CV_8UC1 && img.type() != CV_8UC3)
{
return false;
}
// 经纬度边界有效性验证
double NorthLat = LBbox.NorthLat;
double SouthLat = LBbox.SouthLat;
double WestLon = LBbox.WestLon;
double EastLon = LBbox.EastLon;
// 纬度验证
if (NorthLat > 90 || NorthLat < -90 ||
SouthLat > 90 || SouthLat < -90 ||
NorthLat - SouthLat <= 0)
{
return false;
}
// 经度验证
if (WestLon > 180 || WestLon < -180 ||
EastLon > 180 || EastLon < -180 ||
EastLon - WestLon <= 0)
{
return false;
}
// 经纬度 分辨率
double Lon_resolution = (EastLon - WestLon) / img.cols;
double Lat_resolution = (SouthLat - NorthLat) / img.rows;
// 判断路径后缀的有效性
if ("tif" != savePath.substr(savePath.find_first_of('.'), savePath.length()))
{
return false;
}
// 注册
GDALAllRegister();
CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO");
//创建数据集
GDALDataset* poDstDS = NULL;
char** papszOptions = NULL;
string fomat;
fomat = "GTiff";
GDALDriver *poDriver = GetGDALDriverManager()->GetDriverByName( fomat.c_str());
double adfGeoTransform[6];
adfGeoTransform[0] = WestLon; /* top left x */
adfGeoTransform[1] = Lon_resolution;/* w-e pixel resolution */
adfGeoTransform[2] = 0; /* rotation, 0 if image is "north up" */
adfGeoTransform[3] = NorthLat; /* top left y */
adfGeoTransform[4] = 0; /* rotation, 0 if image is "north up" */
adfGeoTransform[5] = Lat_resolution;/* n-s pixel resolution */
if (img.type() == 0)
{
// 创建图像
poDstDS = poDriver->Create( savePath.c_str(), img.cols, img.rows, 1, GDT_Byte, papszOptions );
//设置椭球体信息
poDstDS->SetGeoTransform( adfGeoTransform );
OGRSpatialReference oSRS;
char* pszWKT = NULL;
oSRS.SetWellKnownGeogCS( "WGS84" );
oSRS.exportToWkt( &pszWKT );
poDstDS->SetProjection( pszWKT );
//遥感的一个波段
GDALRasterBand *poBand = poDstDS->GetRasterBand( 1 );
//分波段输出数据到tiff文件
poBand->RasterIO( GF_Write, 0, 0, img.cols, img.rows, img.data, img.cols, img.rows, GDT_Byte, 0, 0 );
GDALFlushCache( poDstDS );
GDALClose( poDstDS );
GetGDALDriverManager()->DeregisterDriver(poDriver);
GDALDestroyDriverManager();
poDstDS = NULL;
poDriver = NULL;
}
else
{
// 创建图像
poDstDS = poDriver->Create( savePath.c_str(), img.cols, img.rows, 3, GDT_Byte, papszOptions );
//设置椭球体信息
poDstDS->SetGeoTransform( adfGeoTransform );
OGRSpatialReference oSRS;
char* pszWKT = NULL;
oSRS.SetWellKnownGeogCS( "WGS84" );
oSRS.exportToWkt( &pszWKT );
poDstDS->SetProjection( pszWKT );
//遥感的一个波段
GDALRasterBand *poBand1 = poDstDS->GetRasterBand( 1 );
GDALRasterBand *poBand2 = poDstDS->GetRasterBand( 2 );
GDALRasterBand *poBand3 = poDstDS->GetRasterBand( 3 );
std::vector<cv::Mat> planes;
cv::split(img, planes);
//分波段输出数据到tiff文件
poBand1->RasterIO( GF_Write, 0, 0, img.cols, img.rows, planes[2].data, img.cols, img.rows, GDT_Byte, 0, 0 );
poBand2->RasterIO( GF_Write, 0, 0, img.cols, img.rows, planes[1].data, img.cols, img.rows, GDT_Byte, 0, 0 );
poBand3->RasterIO( GF_Write, 0, 0, img.cols, img.rows, planes[0].data, img.cols, img.rows, GDT_Byte, 0, 0 );
GDALFlushCache( poDstDS );
GDALClose( poDstDS );
GetGDALDriverManager()->DeregisterDriver(poDriver);
GDALDestroyDriverManager();
poDstDS = NULL;
poDriver = NULL;
}
return true;
}
catch(cv::Exception &e)
{
string str = e.msg;
return false;
}
catch(...)
{
return false;
}
}