#ifndef  QB_IMGPROCESS_H
#define  QB_IMGPROCESS_H

#ifdef  IMGPROCESS_EXPORTS
#define IMGPROCESS_API __declspec(dllexport)
#else
#define IMGPROCESS_API __declspec(dllimport)
#endif

// OpenCV
#include <opencv2\opencv.hpp>  
using namespace cv;

// 情报数据通用结构
#include "QBStru.h"


// 1. 图像去雾控制 算法:王家星

//1.1 功能:图像去雾控制(暗通道先验)
//输入:	1. qbData 通用情报数据结构体
//		    2. A_MAX  控制去雾效果, A_MAX < 0 时,自适应计算(特别耗时); 有效范围【0,255】
//		    3. degree 控制去雾效果, 有效范围【0,1】
//          4. bSrcFirst 默认时,优先处理srcImg, srcImg-->dstImg
//                       否则,优先处理dstImg,dstImg——>dstImg               

//输出:	1. qbData 含去雾后图像的情报数据结构体
//          2. 返回值:处理成功返回true,失败返回false
//说明: 首先判断图像数据有效性标识位,无效时直接返回,不做任何处理;
IMGPROCESS_API bool DoDehazeCtrl(QBStru *qbData, 
	                             int A_MAX = -1, 
								 double degree = 0.78, 
								 bool bSrcFirst = true);


//1.2 功能:图像去雾控制(函数重载)
//输入:	1. src 输入图像结构体
//		    2. A_MAX  控制去雾效果, A_MAX < 0 时,自适应计算(特别耗时); 有效范围【0,255】
//		    3. degree 控制去雾效果, 有效范围【0,1】

//输出:	1. dst 输出图像结构体
//          2. 返回值:处理成功返回true,失败返回false
IMGPROCESS_API bool DoDehazeCtrl(ImgStru* src, 
	                             ImgStru* dst, 
								 int A_MAX = -1, 
								 double degree = 0.78);



// 2. 图像亮度控制 算法:王家星

//2.1 功能:图像亮度控制
//输入:	1. qbData 通用情报数据结构体
//		    2. degree 控制亮度, 有效范围【0,20】,值越小越暗,越大越亮
//          3. bSrcFirst 默认时,优先处理srcImg, srcImg-->dstImg
//                       否则,优先处理dstImg,  dstImg——>dstImg                         

//输出:	1. qbData 含亮度变化后图像的情报数据结构体
//          2. 返回值:处理成功返回true,失败返回false
//说明: 首先判断图像数据有效性标识位,无效时直接返回,不做任何处理;
IMGPROCESS_API bool DoIntensityCtrl(QBStru *qbData, 
									int degree = 10, 
									bool bSrcFirst = true);


//2.2 功能:图像亮度控制(函数重载)
//输入:	1. src 输入图像结构体
//		    2. degree 控制亮度,有效范围【0,20】,值越小越暗,越大越亮

//输出:	1. dst 输出图像结构体
//          2. 返回值:处理成功返回true,失败返回false
IMGPROCESS_API bool DoIntensityCtrl(ImgStru* src, 
									ImgStru* dst, 
									int degree = 10);



// 3. 图像对比度控制 算法:王家星

//3.1 功能:图像对比度控制
//输入:	1. qbData 通用情报数据结构体
//		    2. degree 控制对比度
//          3. bSrcFirst 默认时,优先处理srcImg, srcImg-->dstImg
//                       否则,优先处理dstImg,dstImg——>dstImg    

//输出:	1. qbData 含对比度变化后图像的情报数据结构体
//          2. 返回值:处理成功返回true,失败返回false
//说明:     首先判断图像数据有效性标识位,无效时直接返回,不做任何处理;
IMGPROCESS_API bool DoContrastCtrl(QBStru *qbData, 
								   int degree = 10, 
								   bool bSrcFirst = true);

//3.2 功能:图像对比度控制(函数重载)
//输入:	1. src 输入图像结构体
//		    2. degree 对比度亮度,有效范围【0,20】,值越大对比度越强

//输出:	1. dst 输出图像结构体
//          2. 返回值:处理成功返回true,失败返回false
IMGPROCESS_API bool DoContrastCtrl(ImgStru* src, 
								   ImgStru* dst, 
								   int degree = 10);


// 4. 图像清晰度

//4.1 功能:图像清晰度控制
//输入:	1. qbData 通用情报数据结构体
//		    2. degree 控制清晰度
//          3. bSrcFirst 默认时,优先处理srcImg, srcImg-->dstImg
//                       否则,优先处理dstImg,dstImg——>dstImg    

//输出:	1. qbData 含清晰度变化后图像的情报数据结构体
//          2. 返回值:处理成功返回true,失败返回false
//说明:     首先判断图像数据有效性标识位,无效时直接返回,不做任何处理;
IMGPROCESS_API bool DoDefinitionCtrl(QBStru *qbData, 
	                                 int degree = 10, 
									 bool bSrcFirst = true);


//4.2 功能:图像清晰度控制(函数重载)
//输入:	1. src 输入图像结构体
//		    2. degree 清晰度控制,有效范围【0,20】,值越大清晰度越好

//输出:	1. dst 输出图像结构体
//          2. 返回值:处理成功返回true,失败返回false
IMGPROCESS_API bool DoDefinitionCtrl(ImgStru* src, 
	                                 ImgStru* dst, 
									 int degree = 10);


// 5. 单帧图像目标定位 算法:王家星

//5.1 功能:计算图像中心点经纬度坐标、载荷等效俯仰角和方位角
//输入:	1. frame  输入复接数据
//      
//输出:	1. Lon     图像中心点经度
//          2. Lat:   图像中心点纬度
//          3. 返回值:处理成功返回true,失败返回false
IMGPROCESS_API bool DoCalImgCenterCoordinate(double &Lon, 
	                                         double &Lat, 
											 double &H, 
											 const struQB_FJ *frame);


//5.2 功能:计算图像中任意点经纬度坐标
//输入:	1. frame  输入复接数据
//          2. pt_x: 列
//          3. pt_y: 行
//      
//输出:	1. Lon     经度
//          2. Lat:   纬度
//          3. 返回值:处理成功返回true,失败返回false
IMGPROCESS_API bool DoCalAnyPtCoordinate(double &Lon, 
										 double &Lat, 
										 double &H, 
										 const struQB_FJ *frame, 
										 int pt_x, 
										 int pt_y);


// 6. 几何校正 算法:王家星

//6.1 功能:基于复接数据的图像系统级几何校正
//输入:	1. qbData 通用情报数据结构体
//          2. bSrcFirst 默认时,优先对srcImg进行几何校正,否则对dstImg进行几何校正

//输出:	1. qbData 含系统级几何校正后图像的情报数据结构体
//          2. 返回值:处理成功返回true,失败返回false
IMGPROCESS_API bool DoSysGeoCorrect(QBStru *qbData, 
	                                bool bSrcFirst = true);


//6.2 功能:基于复接数据的图像系统级几何校正(重载)
//输入:	1. srcImg 输入图像数据
//          2. qbData 输入复接数据

//输出:	1. dstImg 输出图像数据
//          2. 返回值:处理成功返回true,失败返回false
IMGPROCESS_API bool DoSysGeoCorrect(ImgStru *dstImg, 
									const ImgStru *srcImg, 
									const struQB_FJ *qbData);


//6.3 功能:基于地面控制点的几何精校正
//输入:	1. srcImg 输入图像数据
//          2. GCP_XY 控制点(像素坐标)
//          3. GCP_LonLat 控制点(经纬度坐标)
//          4. type: 变换类型 -1:自适应 0:线性 1:二次多项式

//输出:	1. dstImg 输出图像数据
//          2. 返回值:处理成功返回true,失败返回false
IMGPROCESS_API bool DoGCPGeoCorrectImg(ImgStru *dstImg, 
									   const ImgStru *srcImg, 
									   const std::vector<Point2d>& GCP_XY, 
									   const std::vector<Point2d>& GCP_LonLat,
									   int type = -1);


//6.4 功能: OpenCV图像格式基于地面控制点的几何精校正
//输入:	1. srcImg 输入图像数据
//          2. GCP_XY 控制点(像素坐标)
//          3. GCP_LonLat 控制点(经纬度坐标)
//          4. type: 变换类型 -1:自适应 0:线性 1:二次多项式

//输出:	1. dstImg 输出图像数据
//          2. LBbox 经纬度边界
//          3. 返回值:处理成功返回true,失败返回false
IMGPROCESS_API bool DoGCPGeoCorrectImg( cv::Mat& dstImg, 
	                                    GeoBoundingBox& LBbox, 
										const cv::Mat& srcImg, 
										const std::vector<cv::Point2d>& GCP_XY, 
										const std::vector<cv::Point2d>& GCP_LonLat,
										int type = -1);


//6.5 功能:基于控制点的几何校正
//输入:	1. srcImg 输入图像数据
//          2. GCP_xy 控制点(畸变像素坐标)
//          3. GCP_XY 控制点(参考图像像素坐标)

//输出:	1. dstImg 输出图像数据
//          2. 返回值:处理成功返回true,失败返回false
IMGPROCESS_API bool DoCPBasedImgCorrect( cv::Mat &dstImg, 
	                                     const cv::Mat &srcImg, 
										 const std::vector<cv::Point2d>& GCP_xy, 
										 const std::vector<cv::Point2d>& GCP_XY);


// 7. GeoTIFF文件生成保存 算法:王家星

//7.1 功能:保存情报数据至本地文件(GeoTiff格式)
//输入:	1. qbData 通用情报数据结构体
//          2. savePath Tiff文件保存路径

//输出:	1. 返回值:保存成功返回true,失败返回false
//说明:    可能会先执行几何校正操作,再保存;
IMGPROCESS_API bool SaveToGeoTIFF(QBStru *qbData, 
	                              string savePath = "");


//7.2 功能:保存图像数据至本地文件(GeoTiff格式)
//输入:	1. Img 通用情报数据结构体
//          2. savePath Tiff文件保存路径

//输出:	1. 返回值:保存成功返回true,失败返回false
IMGPROCESS_API bool SaveToGeoTIFF(const ImgStru *Img, 
	                              string savePath = "");


//7.3 功能:保存图像数据至本地文件(GeoTiff格式)
//输入:	1. Img OpenCV图像
//          2. LBbox 经纬度边界
//          3. savePath Tiff文件保存路径


//输出:	1. 返回值:保存成功返回true,失败返回false
IMGPROCESS_API bool SaveToGeoTIFF(cv::Mat& Img, 
	                              GeoBoundingBox& LBbox, 
								  string savePath = "");




// 8. 距离、方位量算 算法:王家星

//8.1 功能:计算图像(几何校正前)中两点间的距离和方位(重载)
//输入:	1. frameData 通用复接数据结构体
//          2. pt1 起点(像素坐标)
//          3. pt2 终点(像素坐标)

//输出:	1. distance 距离
//          2. azAngle  方位,起点点到终点
//          3. 返回值:计算有效返回true,否则返回false
IMGPROCESS_API bool CalculateTwoPtsDistanceAzimuth( double &distance, 
													double &azAngle,
													const struQB_FJ *frameData, 
													cv::Point pt1, 
													cv::Point pt2);

//8.2 功能:计算图像中两点间的距离和方位
//输入:	1. qbData 通用情报数据结构体
//          2. pt1 起点(像素坐标)
//          3. pt2 终点(像素坐标)
//          4. flags:flags = 0:标识pt1、pt2为几何校正前图像中的点
//                    flags = 1:标识pt1、pt2为几何校正后图像中的点 

//输出:	1. distance 距离
//          2. azAngle  方位,起点点到终点
//          3. 返回值:计算有效返回true,否则返回false
IMGPROCESS_API bool CalculateTwoPtsDistanceAzimuth( double &distance, 
													double &azAngle,
													const QBStru *qbData, 
													cv::Point pt1, 
													cv::Point pt2, 
													int flags = 0);




// 9. 面积量算 算法:王家星

//9.1 功能:计算图像(几何校正前)中多点组成的多边形面积
//输入:	1. frameData 复接数据
//          2. points 指向点坐标的指针
//          3. count: 点数目

//输出:	1. area  :多边形面积
//          2. 返回值:计算有效返回true,否则返回false
IMGPROCESS_API bool CalculatePloygonArea(double &area, 
										 const struQB_FJ *frameData, 
										 cv::Point *points, 
										 int count);

//9.2 功能:计算图像中多边形面积
//输入:	1. qbData 通用情报数据结构体
//          2. point  多点指针(像素坐标)
//          3. count  点数目
//          4. flags:flags = 0:标识为几何校正前图像中的点
//                    flags = 1:标识为几何校正后图像中的点 

//输出:	1. area 面积(平方米)
//          2. 返回值:计算有效返回true,否则返回false
//说明:    各点应为顺序或者逆序,不能乱序
IMGPROCESS_API bool CalculatePloygonArea(double &area, 
	                                     const QBStru *qbData, 
										 cv::Point* point, 
										 int count, 
										 int flags = 0);

//10 功能:基于经纬度读取地面高程
//输入:
//    1. fLonDeg: 经度(度)
//    2. fLatDeg: 纬度(度)
//    3. sDir: 高程数据文件存储路径, 默认设为:"D:\\ElevationData"
// 
//输出:
//    1. fElevator:高程(米)
//
//返回值:若函数运行成功,返回true,否则返回false
IMGPROCESS_API bool GetElevation( float& fElevator, double dLonDeg, double dLatDeg, string sDir, bool bNearst = false);
IMGPROCESS_API void ClearDem();

// 11 图像融合算法

// 11.1 功能:函数 DoFastFuseImgRGBplusIR() 快速融合两幅输入图像
// 输入:    
//	        img1: 输入图像1:RGB:三通道
//	        img2: 输入图像2:IR:三通道或单通道
// 输出:  
//          dst: 融合图像
// 返回值:
//          运算有效返回true,否则返回false
IMGPROCESS_API bool DoFastFuseImgRGBplusIR(cv::Mat &dst, const cv::Mat RGBimg, const cv::Mat IRimg);


// 11.2 功能:函数 DoFuseImgRGBplusIR() 基于小波变换融合两幅输入图像
// 输入:    
//	        img1: 输入图像1:RGB:三通道
//	        img2: 输入图像2:IR:三通道或单通道
//          wname: 小波名称
//                 支持小波:
//							1. haar
//							2. symN  [1, 10]
//							3. dbN   [1, 10]
//							4. coifN [1, 5]
//          level:小波分解层数
// 输出:  
//          dst: 融合图像
// 返回值:
//          运算有效返回true,否则返回false
IMGPROCESS_API bool DoFuseImgRGBplusIR(cv::Mat &dst, const cv::Mat RGBimg, const cv::Mat IRimg, const string wname = "sym5", const unsigned int level = 10);



// 11.3 功能:函数 FuseImg() 基于小波变换融合两幅输入图像
// 输入:    
//	        img1: 输入图像1
//	        img2: 输入图像2
//          wname: 小波名称
//                 支持小波:
//							1. haar
//							2. symN  [1, 10]
//							3. dbN   [1, 10]
//							4. coifN [1, 10]
//          level:小波分解层数
// 输出:  
//          dst: 融合图像
// 返回值:
//          运算有效返回true,否则返回false
IMGPROCESS_API bool DoFuseImg(cv::Mat &dst, const cv::Mat img1, const cv::Mat img2, const string wname = "sym5", const unsigned int level = 10);


// 12 超分重建
// 功能:灰度图像(红外图像)超分辨率构建
// 输入:    
//	        imgDeque: 输入图像序列,要求图像尺寸相同,类型为CV_8UC1
// 输出:  
//          dst:  输出超分图像
// 返回重建中有效的图像数目
IMGPROCESS_API int GetSuperResolutionImg(cv::Mat &dst, const std::deque<cv::Mat> &imgDeque, double multiple = 2);


#endif