|
|
// ImgShowDlg.cpp : 实现文件
|
|
|
//
|
|
|
|
|
|
#include "stdafx.h"
|
|
|
#include "ImgShowDlg.h"
|
|
|
#include "GlobalFunc.h"
|
|
|
#include "QB_ImgProcessFun.h"
|
|
|
#include "CvvImage.h"
|
|
|
#include "Markup.h"
|
|
|
|
|
|
// tif 图像
|
|
|
#include <ogr_srs_api.h>
|
|
|
#include <ogr_spatialref.h>
|
|
|
#include <gdal.h>
|
|
|
#include <gdal_priv.h>
|
|
|
|
|
|
// 文字编辑窗口
|
|
|
#include "AddTextDlg.h"
|
|
|
|
|
|
#include "MapPrj.h"
|
|
|
/*#include "GoogleTileOperation.h"*/
|
|
|
|
|
|
#include "TgtLocCalibrateDlg.h"
|
|
|
|
|
|
// CImgShowDlg 对话框
|
|
|
|
|
|
IMPLEMENT_DYNAMIC(CImgShowDlg, CDialog)
|
|
|
|
|
|
CImgShowDlg::CImgShowDlg(CWnd* pParent /*=NULL*/): CDialog(CImgShowDlg::IDD, pParent)
|
|
|
{
|
|
|
m_lpSendCoordinate = NULL;
|
|
|
m_lpSendPixInfoProc = NULL;
|
|
|
m_lpSendFilePath = NULL;
|
|
|
m_lpSendTgrLocLeadLonLat = NULL;
|
|
|
m_lpSendArtilleryReviseInfo = NULL;
|
|
|
|
|
|
m_ShowRegion = CRect(0,0,0,0);
|
|
|
|
|
|
m_ShowRegionOnScreen.left = 0;
|
|
|
m_ShowRegionOnScreen.right = 0;
|
|
|
m_ShowRegionOnScreen.top = 0;
|
|
|
m_ShowRegionOnScreen.bottom = 0;
|
|
|
|
|
|
m_PicCtrlWidth = 0;
|
|
|
m_PicCtrlHeight = 0;
|
|
|
|
|
|
m_LButtonDownPixelCoordinate = CPoint(0,0);
|
|
|
m_bStaisfyRoamImg = FALSE;
|
|
|
m_LatestPlotRect = CRect(0,0,0,0);
|
|
|
m_LButtonDblClkPixelCoordinate = CPoint(-1, -1);
|
|
|
|
|
|
m_bPlotRectOnPaint = TRUE;
|
|
|
|
|
|
m_NorthDirectionCenter.x = 0;
|
|
|
m_NorthDirectionCenter.y = 0;
|
|
|
|
|
|
m_bPlotDirectionOnPaint = TRUE;
|
|
|
|
|
|
m_LeftButtonDown.x = 0;
|
|
|
m_LeftButtonDown.y = 0;
|
|
|
|
|
|
m_RButtonPt.x = 0;
|
|
|
m_RButtonPt.y = 0;
|
|
|
|
|
|
m_SrcFrame = NULL;
|
|
|
m_ImgRatioOnScreen = 1.0F;
|
|
|
|
|
|
m_ImgShowShift.x = 0L;
|
|
|
m_ImgShowShift.y = 0L;
|
|
|
|
|
|
m_bFirstSignal = FALSE;
|
|
|
m_bSecondSignal = FALSE;
|
|
|
m_bSatisfyMove = FALSE;
|
|
|
|
|
|
m_iLatest = 0;
|
|
|
m_iPreLatest = 0;
|
|
|
|
|
|
m_bMemPreMultiFrame = FALSE;
|
|
|
|
|
|
m_LatestQuadrangle = CRect(0,0,0,0);
|
|
|
|
|
|
// 像素信息
|
|
|
m_imgPixel_XY_Coordinate.x = -1;
|
|
|
m_imgPixel_XY_Coordinate.y = -1;
|
|
|
m_imgPixel_LBH_Coordinate.x = -200.0;
|
|
|
m_imgPixel_LBH_Coordinate.y = -200.0;
|
|
|
m_imgPixel_LBH_Coordinate.z = -200.0;
|
|
|
|
|
|
|
|
|
m_bPlotRect = FALSE;
|
|
|
|
|
|
// 当前显示的图像序号
|
|
|
m_currentImgOrder = 0;
|
|
|
|
|
|
// 图像编辑类型
|
|
|
m_iImgEditType = 0;
|
|
|
|
|
|
m_bHaveOnPt = false;
|
|
|
|
|
|
m_bEnhanceEdit = true; // 增强
|
|
|
|
|
|
m_pFastLookUpDlg = NULL;
|
|
|
|
|
|
m_sSaveCurrentImgFolder = "";
|
|
|
m_sSavePreMultiImgFolder = "";
|
|
|
|
|
|
m_TargetCenter = cv::Point(-100, -100);
|
|
|
|
|
|
m_bDrawSquareOnImg = TRUE;
|
|
|
|
|
|
m_deltaLon = 0;
|
|
|
m_deltaLat = 0;
|
|
|
|
|
|
m_bCloseRughtBtnMenu = false;
|
|
|
|
|
|
m_sThemeText = "";
|
|
|
|
|
|
m_bGetTgtImgOn = false;
|
|
|
m_clipImgFirstPt = CPoint(0,0);
|
|
|
m_clipImgSecondPt = CPoint(0,0);
|
|
|
m_haveValidFirstPt = false;
|
|
|
|
|
|
// 图像裁剪开关
|
|
|
m_bClipImgOn = false;
|
|
|
|
|
|
m_hMutex_ProcessData = nullptr;
|
|
|
}
|
|
|
|
|
|
CImgShowDlg::~CImgShowDlg()
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
// 如果有图像 需要释放该图像
|
|
|
if (m_SrcFrame != NULL)
|
|
|
{
|
|
|
cvReleaseImage(&m_SrcFrame);
|
|
|
m_SrcFrame = NULL;
|
|
|
}
|
|
|
|
|
|
// 当前情报数据结构体:LatestQBData
|
|
|
ReleaseQBData(&m_LatestQBData);
|
|
|
|
|
|
|
|
|
WaitForSingleObject(m_hMutex_ProcessData, INFINITE);
|
|
|
// 情报队列销毁
|
|
|
if(m_QBDataDeque.size() > 0)
|
|
|
{
|
|
|
for (size_t i = 0; i < m_QBDataDeque.size(); ++i)
|
|
|
{
|
|
|
SAFE_DELETE_ARRAY(m_QBDataDeque[i].image.srcImg.buff);
|
|
|
SAFE_DELETE_ARRAY(m_QBDataDeque[i].image.dstImg.buff);
|
|
|
SAFE_DELETE_ARRAY(m_QBDataDeque[i].image.geoImg.buff);
|
|
|
}
|
|
|
m_QBDataDeque.clear();
|
|
|
}
|
|
|
ReleaseMutex(m_hMutex_ProcessData);
|
|
|
|
|
|
|
|
|
|
|
|
// midImg 释放
|
|
|
SAFE_DELETE_ARRAY(m_midImg.buff);
|
|
|
|
|
|
// 释放快速查找图像对话框
|
|
|
if (m_pFastLookUpDlg != NULL)
|
|
|
{
|
|
|
delete m_pFastLookUpDlg;
|
|
|
m_pFastLookUpDlg = NULL;
|
|
|
}
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.what();
|
|
|
std::abort();
|
|
|
}
|
|
|
catch(...)
|
|
|
{
|
|
|
std::abort();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void CImgShowDlg::DoDataExchange(CDataExchange* pDX)
|
|
|
{
|
|
|
CDialog::DoDataExchange(pDX);
|
|
|
}
|
|
|
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CImgShowDlg, CDialog)
|
|
|
ON_WM_ERASEBKGND()
|
|
|
ON_WM_PAINT()
|
|
|
ON_WM_RBUTTONDOWN()
|
|
|
ON_COMMAND(ID_ZOOM_IN_IMG, &CImgShowDlg::OnZoomInImg)
|
|
|
ON_COMMAND(ID_ZOOM_OUT_IMG, &CImgShowDlg::OnZoomOutImg)
|
|
|
ON_COMMAND(ID_ZOOM_FIT_IMG, &CImgShowDlg::OnZoomFitImg)
|
|
|
ON_COMMAND(ID_CONCEL_TARGET_PLOT, &CImgShowDlg::OnConcelTargetPlot)
|
|
|
ON_COMMAND(ID_SAVE_CURRENT_FRAME, &CImgShowDlg::OnSaveCurrentFrame)
|
|
|
ON_WM_LBUTTONDOWN()
|
|
|
ON_WM_LBUTTONDBLCLK()
|
|
|
ON_WM_MOUSEMOVE()
|
|
|
ON_WM_MOUSEWHEEL()
|
|
|
ON_COMMAND(ID_CLEAR_MEMORY, &CImgShowDlg::OnClearMemory)
|
|
|
ON_COMMAND(ID_SAVE_IMG_TO_TIFF, &CImgShowDlg::OnSaveImgToTiff)
|
|
|
ON_COMMAND(ID_FAST_LOOKUP_IMGS, &CImgShowDlg::OnFastLookupImgs)
|
|
|
ON_COMMAND(ID_TGT_LOC_LEAD, &CImgShowDlg::OnTgtLocLead)
|
|
|
ON_COMMAND(ID_GEO_CORRECT_AND_SHOW, &CImgShowDlg::OnGeoCorrectAndShow)
|
|
|
ON_COMMAND(ID_DRAW_SQUARE_ON_IMG, &CImgShowDlg::OnDrawSqureOnImg)
|
|
|
ON_COMMAND(ID_OPEN_ONE_IMG, &CImgShowDlg::OnOpenOneImg)
|
|
|
ON_COMMAND(ID_TGTLOC_calibrate, &CImgShowDlg::OnTgtloccalibrate)
|
|
|
ON_COMMAND(ID_VIEW_DELTA_LON_LAT, &CImgShowDlg::OnViewDeltaLonLat)
|
|
|
ON_COMMAND(ID_GET_TARGET_IMG, &CImgShowDlg::OnGetTargetImg)
|
|
|
ON_COMMAND(ID_CLIP_IMG, &CImgShowDlg::OnClipImg)
|
|
|
END_MESSAGE_MAP()
|
|
|
|
|
|
|
|
|
// 1.1 功能:设置回调函数
|
|
|
BOOL CImgShowDlg::SetCallBackFun(SendCoordinateProc proc)
|
|
|
{
|
|
|
// 输入数据有效性判断
|
|
|
if (proc != NULL)
|
|
|
{
|
|
|
m_lpSendCoordinate = proc;
|
|
|
return TRUE;
|
|
|
}
|
|
|
return FALSE;
|
|
|
}
|
|
|
|
|
|
|
|
|
// 2 功能:设置回调函数,像素信息传递到外部CSU中
|
|
|
// 输入:
|
|
|
// 1.proc: 函数指针
|
|
|
//
|
|
|
// 输出: 设置成功返回TRUE,否则返回FALSE
|
|
|
BOOL CImgShowDlg::SetCallBackFun(SendPixInfoProc proc)
|
|
|
{
|
|
|
// 输入数据有效性判断
|
|
|
if (proc != NULL)
|
|
|
{
|
|
|
m_lpSendPixInfoProc = proc;
|
|
|
return TRUE;
|
|
|
}
|
|
|
return FALSE;
|
|
|
}
|
|
|
|
|
|
|
|
|
// 3 功能:设置回调函数,传递保存文件路径到外部CSU中
|
|
|
// 输入:
|
|
|
// 1.proc: 函数指针
|
|
|
//
|
|
|
// 输出: 设置成功返回TRUE,否则返回FALSE
|
|
|
BOOL CImgShowDlg::SetCallBackFun(SendFilePath proc)
|
|
|
{
|
|
|
// 输入数据有效性判断
|
|
|
if (proc != NULL)
|
|
|
{
|
|
|
m_lpSendFilePath = proc;
|
|
|
return TRUE;
|
|
|
}
|
|
|
return FALSE;
|
|
|
}
|
|
|
|
|
|
|
|
|
BOOL CImgShowDlg::SetCallBackFun(SendTgrLocLeadLonLatProc proc)
|
|
|
{
|
|
|
// 输入数据有效性判断
|
|
|
if (proc != NULL)
|
|
|
{
|
|
|
m_lpSendTgrLocLeadLonLat = proc;
|
|
|
return TRUE;
|
|
|
}
|
|
|
return FALSE;
|
|
|
}
|
|
|
|
|
|
// 功能:设置回调函数,目标定位导引经纬度到外部CSU中
|
|
|
// 输入:
|
|
|
// 1.proc: 函数指针
|
|
|
//
|
|
|
// 输出: 设置成功返回TRUE,否则返回FALSE
|
|
|
BOOL CImgShowDlg::SetCallBackFun(SendArtilleryReviseInfoProc proc)
|
|
|
{
|
|
|
// 输入数据有效性判断
|
|
|
if (proc != NULL)
|
|
|
{
|
|
|
m_lpSendArtilleryReviseInfo = proc;
|
|
|
return TRUE;
|
|
|
}
|
|
|
return FALSE;
|
|
|
}
|
|
|
|
|
|
// 1.2 功能:在对话框中显示一帧图像
|
|
|
BOOL CImgShowDlg::ShowOneImage(const BITMAPINFO* pImgInfo,
|
|
|
BYTE* pImgData,
|
|
|
BOOL isNeedClip,
|
|
|
const CRect &ShowRegion,
|
|
|
BOOL isNeedFlip,
|
|
|
float StrecthRatio,
|
|
|
POINT xyShift)
|
|
|
{
|
|
|
BOOL ret = FALSE;
|
|
|
|
|
|
try
|
|
|
{
|
|
|
// 数据有效性判断
|
|
|
if ( (pImgInfo == NULL) || (pImgData == NULL) )
|
|
|
{
|
|
|
return FALSE;
|
|
|
}
|
|
|
|
|
|
// 图像显示拉伸比例 有效性判定和修正
|
|
|
if ((StrecthRatio < 0.0F) || (StrecthRatio > 1.0F))
|
|
|
{
|
|
|
StrecthRatio = 1.0F;
|
|
|
}
|
|
|
|
|
|
// 图像属性提取
|
|
|
int imgWidth = static_cast<int>(pImgInfo->bmiHeader.biWidth);
|
|
|
int imgHeight = static_cast<int>(pImgInfo->bmiHeader.biHeight);
|
|
|
int nBitCount = static_cast<int>(pImgInfo->bmiHeader.biBitCount);
|
|
|
|
|
|
// 图像属性判断
|
|
|
if ( (imgWidth <= 0) || (imgHeight <= 0) )
|
|
|
{
|
|
|
return FALSE;
|
|
|
}
|
|
|
|
|
|
// 步长:每行像素所占字节数,必须扩展成4的倍数
|
|
|
int lineByte = (imgWidth * nBitCount / 8 + 3) / 4 * 4;
|
|
|
|
|
|
// 位图数据缓冲区的大小,即图像大小
|
|
|
unsigned int imgBufSize = static_cast<unsigned int>(imgHeight * lineByte);
|
|
|
|
|
|
// 将图像数据转换到 m_SrcFrame 再显示
|
|
|
if (m_SrcFrame != NULL) // 如果有图像
|
|
|
{
|
|
|
// 情况1:如果图像属性没有变化 直接更换原始图像数据即可,即复制图像数据,不需要再去创建一幅图像
|
|
|
// 情况2:如果图像属性发生了变化,需要先释放图像,再创建图像
|
|
|
|
|
|
// 情况1
|
|
|
if ((m_SrcFrame->width == imgWidth) &&
|
|
|
(m_SrcFrame->height == imgHeight) &&
|
|
|
(m_SrcFrame->depth * m_SrcFrame->nChannels == nBitCount) )
|
|
|
{
|
|
|
// 内存复制机制
|
|
|
int RealLineByte = (imgWidth * nBitCount / 8);
|
|
|
|
|
|
if (RealLineByte == lineByte)
|
|
|
{
|
|
|
memcpy(m_SrcFrame->imageData, pImgData, imgBufSize); // 图像数据复制
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
for (int i = 0; i < imgHeight; i++)
|
|
|
{
|
|
|
memcpy(m_SrcFrame->imageData + i * lineByte, pImgData + i * RealLineByte, RealLineByte);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
else // 情况2
|
|
|
{
|
|
|
// 释放图像
|
|
|
cvReleaseImage(&m_SrcFrame);
|
|
|
m_SrcFrame = NULL;
|
|
|
|
|
|
// 创建
|
|
|
m_SrcFrame = cvCreateImage(cvSize(imgWidth, imgHeight), 8, nBitCount/8); // 创建图像
|
|
|
|
|
|
if (m_SrcFrame != NULL) // 创建成功
|
|
|
{
|
|
|
// 内存复制机制
|
|
|
int RealLineByte = (imgWidth * nBitCount / 8);
|
|
|
|
|
|
if (RealLineByte == lineByte)
|
|
|
{
|
|
|
memcpy(m_SrcFrame->imageData, pImgData, imgBufSize); // 图像数据复制
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
for (int i = 0; i < imgHeight; i++)
|
|
|
{
|
|
|
memcpy(m_SrcFrame->imageData + i * lineByte, pImgData + i * RealLineByte, RealLineByte);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
return FALSE;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
else // 如果没有图像 需要先创建图像
|
|
|
{
|
|
|
m_SrcFrame = cvCreateImage(cvSize(imgWidth, imgHeight), 8, nBitCount/8); // 创建图像
|
|
|
|
|
|
if (m_SrcFrame != NULL) // 创建成功
|
|
|
{
|
|
|
// 内存复制机制
|
|
|
int RealLineByte = (imgWidth * nBitCount / 8);
|
|
|
|
|
|
if (RealLineByte == lineByte)
|
|
|
{
|
|
|
memcpy(m_SrcFrame->imageData, pImgData, imgBufSize); // 图像数据复制
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
for (int i = 0; i < imgHeight; i++)
|
|
|
{
|
|
|
memcpy(m_SrcFrame->imageData + i * lineByte, pImgData + i * RealLineByte, RealLineByte);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
return FALSE;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 如果需要反转 把 SrcFrame 反转 后面的函数就再也不用考虑反转的问题
|
|
|
if (isNeedFlip == TRUE)
|
|
|
{
|
|
|
cvFlip(m_SrcFrame); // 上下反转,改变自身
|
|
|
}
|
|
|
|
|
|
// 保存图像显示属性,如果该值不合理,会在随后的重载图像显示函数中被修改
|
|
|
this->m_ShowRegion = ShowRegion;
|
|
|
|
|
|
// 设置图像显示拉伸系数
|
|
|
if (StrecthRatio >= 0.0F && StrecthRatio <= 1.0F)
|
|
|
{
|
|
|
m_ImgRatioOnScreen = StrecthRatio;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
m_ImgRatioOnScreen = 1.0F;
|
|
|
}
|
|
|
|
|
|
|
|
|
// 转到函数1.3(重载)进行图像显示
|
|
|
ret = ShowOneImage(m_SrcFrame, isNeedClip, ShowRegion, m_ImgRatioOnScreen, xyShift);
|
|
|
|
|
|
return ret;
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.msg;
|
|
|
return FALSE;
|
|
|
}
|
|
|
catch(...)
|
|
|
{
|
|
|
return FALSE;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
// 1.3 功能:在对话框中显示一帧图像
|
|
|
BOOL CImgShowDlg::ShowOneImage(const IplImage* src,
|
|
|
BOOL isNeedClip,
|
|
|
const CRect &ShowRegion,
|
|
|
float StrecthRatio,
|
|
|
POINT xyShift)
|
|
|
{
|
|
|
BOOL ret = FALSE; // 返回值
|
|
|
|
|
|
try
|
|
|
{
|
|
|
// 图像数据有效性判断
|
|
|
if (src == NULL)
|
|
|
{
|
|
|
return FALSE;
|
|
|
}
|
|
|
|
|
|
// 定义变量,用于标识是否显示整个图像
|
|
|
// 原因:即使 isNeedClip 设置为TURE,ShowRegion不合理时,也要显示整个图像
|
|
|
BOOL ShowWholeImg = TRUE;
|
|
|
|
|
|
// 判断是否需要裁剪
|
|
|
if (isNeedClip == TRUE) // 如果需要裁剪
|
|
|
{
|
|
|
// 判断 ShowRegion 是否合理
|
|
|
// 如果 ShowRegion 出现任何不合理,则显示整个图像
|
|
|
if ((ShowRegion.left >= 0) && (ShowRegion.left < src->width) &&
|
|
|
(ShowRegion.right >= 0) && (ShowRegion.right < src->width) &&
|
|
|
(ShowRegion.top >= 0) && (ShowRegion.top < src->height) &&
|
|
|
(ShowRegion.bottom >= 0) && (ShowRegion.bottom < src->height) &&
|
|
|
(ShowRegion.right - ShowRegion.left > 0) && (ShowRegion.bottom - ShowRegion.top > 0) )
|
|
|
{
|
|
|
// 特殊情况:裁剪整个图像
|
|
|
if ((ShowRegion.right - ShowRegion.left + 1 == src->width) &&
|
|
|
(ShowRegion.bottom - ShowRegion.top + 1 == src->height))
|
|
|
{
|
|
|
ShowWholeImg = TRUE;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
ShowWholeImg = FALSE;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
// 显示区域设置不合理,显示全部图像
|
|
|
ShowWholeImg = TRUE;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 判断是否需要显示整个图像
|
|
|
if (ShowWholeImg == TRUE) // 如果显示整个图像
|
|
|
{
|
|
|
// 显示整个图像
|
|
|
ret = ShowWholeImage(src, StrecthRatio, xyShift);
|
|
|
|
|
|
// 更新图像显示区域 m_ShowRegion
|
|
|
// 目的:用于图像放大缩小等操作
|
|
|
this->m_ShowRegion.left = 0;
|
|
|
this->m_ShowRegion.right = src->width - 1;
|
|
|
this->m_ShowRegion.top = 0;
|
|
|
this->m_ShowRegion.bottom = src->height - 1;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
// 裁剪出显示区域
|
|
|
IplImage* validPart = NULL;
|
|
|
|
|
|
// 这时,ShowRegion肯定是有效的,可以直接创建图像
|
|
|
validPart = cvCreateImage(cvSize(ShowRegion.Width(), ShowRegion.Height()), src->depth, src->nChannels);
|
|
|
|
|
|
if (validPart != NULL) // 创建成功
|
|
|
{
|
|
|
cvZero(validPart); // 清零
|
|
|
|
|
|
// 设置 感兴趣区
|
|
|
cvSetImageROI( const_cast<IplImage*>(src), cvRect( static_cast<int>(ShowRegion.left), static_cast<int>(ShowRegion.top), ShowRegion.Width(), ShowRegion.Height()) );
|
|
|
|
|
|
// 叠加
|
|
|
cvAdd( src, validPart, validPart, NULL );
|
|
|
|
|
|
// 释放 感兴趣区
|
|
|
cvResetImageROI( const_cast<IplImage*>(src) );
|
|
|
|
|
|
// 显示图像 validPart
|
|
|
ret = ShowWholeImage(validPart, StrecthRatio, xyShift);
|
|
|
|
|
|
// 释放 validPart
|
|
|
cvReleaseImage(&validPart);
|
|
|
validPart = NULL;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
return FALSE;
|
|
|
}
|
|
|
}
|
|
|
return ret;
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.msg;
|
|
|
return FALSE;
|
|
|
}
|
|
|
catch(...)
|
|
|
{
|
|
|
return FALSE;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 1.4 功能:在对话框中显示一帧图像
|
|
|
BOOL CImgShowDlg::ShowWholeImage(const IplImage* src, float StrecthRatio, POINT &shift)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
// 数据有效性判断
|
|
|
if (src == NULL)
|
|
|
{
|
|
|
return FALSE;
|
|
|
}
|
|
|
|
|
|
// 图像显示拉伸比例 有效性判定和修正
|
|
|
if ((abs(StrecthRatio) <= 0.0F) || (StrecthRatio > 1.0F))
|
|
|
{
|
|
|
StrecthRatio = 1.0F;
|
|
|
}
|
|
|
|
|
|
// 计算当前显示图像对话框尺寸
|
|
|
CRect clientRect;
|
|
|
GetClientRect(&clientRect);
|
|
|
|
|
|
// 获得 pictrue 控件窗口的句柄
|
|
|
CWnd *pWnd = NULL;
|
|
|
pWnd = GetDlgItem(IDC_IMG_SHOW_PIC_CTRL);
|
|
|
|
|
|
// 后面程序无需再判定
|
|
|
if (pWnd == NULL)
|
|
|
{
|
|
|
return FALSE;
|
|
|
}
|
|
|
|
|
|
// 让图像控件填满对话框
|
|
|
pWnd->MoveWindow(&clientRect);
|
|
|
|
|
|
// 设置图像控件尺寸
|
|
|
m_PicCtrlWidth = clientRect.Width(); // 图像控件宽
|
|
|
m_PicCtrlHeight = clientRect.Height(); // 图像控件高
|
|
|
|
|
|
// 获取图像控件HDC
|
|
|
CDC *pDC = NULL; // 函数退出时需要释放 ReleaseDC(pDC);
|
|
|
pDC = pWnd->GetDC();
|
|
|
|
|
|
// 后面程序无需再判定
|
|
|
if (pDC == NULL)
|
|
|
{
|
|
|
return FALSE;
|
|
|
}
|
|
|
|
|
|
HDC hdc = NULL;
|
|
|
hdc = pDC->GetSafeHdc();
|
|
|
|
|
|
// 当前图像尺寸
|
|
|
int imgWidth = src->width;
|
|
|
int imgHeight = src->height;
|
|
|
|
|
|
// 显示图像
|
|
|
IplImage* fitSizeImg = NULL;
|
|
|
|
|
|
// 显示图像尺寸
|
|
|
int fitSizeImgWidth = 0;
|
|
|
int fitSizeImgHeight = 0;
|
|
|
|
|
|
// 图像尺寸小于窗口尺寸
|
|
|
if ((imgWidth <= m_PicCtrlWidth) && (imgHeight <= m_PicCtrlHeight))
|
|
|
{
|
|
|
// 拉伸图像
|
|
|
double Ratio = 1.0;
|
|
|
double Ratio_Width = static_cast<double>(m_PicCtrlWidth) / static_cast<double>(imgWidth);
|
|
|
double Ratio_Height = static_cast<double>(m_PicCtrlHeight) / static_cast<double>(imgHeight);
|
|
|
|
|
|
Ratio = (Ratio_Width < Ratio_Height) ? Ratio_Width : Ratio_Height; // Ratio 大于 1
|
|
|
|
|
|
// 拉伸比例控制
|
|
|
Ratio *= StrecthRatio;
|
|
|
|
|
|
// 显示图像尺寸
|
|
|
fitSizeImgWidth = static_cast<int>(imgWidth * Ratio + 0.5);
|
|
|
fitSizeImgHeight = static_cast<int>(imgHeight * Ratio + 0.5);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
// 压缩图像
|
|
|
double Ratio = 1.0;
|
|
|
double Ratio_Img = static_cast<double>(imgWidth) / static_cast<double>(imgHeight);
|
|
|
double Ratio_ClientRect = static_cast<double>(m_PicCtrlWidth) / static_cast<double>(m_PicCtrlHeight);
|
|
|
|
|
|
// 计算比例系数
|
|
|
if ( Ratio_Img > Ratio_ClientRect )
|
|
|
{
|
|
|
Ratio = static_cast<double>(m_PicCtrlWidth) / static_cast<double>(imgWidth); // Ratio 小于 1
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
Ratio = static_cast<double>(m_PicCtrlHeight) / static_cast<double>(imgHeight); // Ratio 小于 1
|
|
|
}
|
|
|
|
|
|
// 拉伸比例控制
|
|
|
Ratio *= StrecthRatio;
|
|
|
|
|
|
// 显示图像尺寸
|
|
|
fitSizeImgWidth = static_cast<int>(imgWidth * Ratio + 0.5);
|
|
|
fitSizeImgHeight = static_cast<int>(imgHeight * Ratio + 0.5);
|
|
|
}
|
|
|
|
|
|
// 最低尺寸判断,小于一个像素时直接返回
|
|
|
if(min(fitSizeImgWidth, fitSizeImgHeight) <= 1)
|
|
|
{
|
|
|
// 释放
|
|
|
ReleaseDC(pDC);
|
|
|
return FALSE;
|
|
|
}
|
|
|
|
|
|
// 创建fitSizeImg
|
|
|
fitSizeImg = cvCreateImage(cvSize(fitSizeImgWidth, fitSizeImgHeight), src->depth, src->nChannels);
|
|
|
|
|
|
if (fitSizeImg == NULL)
|
|
|
{
|
|
|
return FALSE;
|
|
|
}
|
|
|
|
|
|
// 改变图像尺寸
|
|
|
cvResize(src, fitSizeImg);
|
|
|
|
|
|
// 为使显示界面不闪烁 增加中间变量 边界充满黑色
|
|
|
IplImage* fillblackImg = NULL;
|
|
|
fillblackImg = cvCreateImage(cvSize(clientRect.Width(), clientRect.Height()), src->depth, src->nChannels);
|
|
|
|
|
|
if (fillblackImg != NULL)
|
|
|
{
|
|
|
cvZero(fillblackImg); // 清零
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
// 释放缩放后图像
|
|
|
cvReleaseImage(&fitSizeImg);
|
|
|
fitSizeImg = NULL;
|
|
|
|
|
|
// 释放pdc
|
|
|
ReleaseDC(pDC);
|
|
|
|
|
|
return FALSE;
|
|
|
}
|
|
|
|
|
|
// 叠加 fitSizeImg 图像 到 fillblackImg
|
|
|
|
|
|
// 左上 起始点
|
|
|
cv::Point LeftUpBefore;
|
|
|
LeftUpBefore.x = static_cast<int>((m_PicCtrlWidth - fitSizeImgWidth)/2);
|
|
|
LeftUpBefore.y = static_cast<int>((m_PicCtrlHeight - fitSizeImgHeight)/2);
|
|
|
|
|
|
// 加上偏移量之后
|
|
|
cv::Point LeftUpAfter = LeftUpBefore;
|
|
|
LeftUpBefore.x += shift.x;
|
|
|
LeftUpBefore.y += shift.y;
|
|
|
|
|
|
// 修改全局变量 设计的不好
|
|
|
if (LeftUpAfter.x < 0)
|
|
|
{
|
|
|
LeftUpAfter.x = 0;
|
|
|
}
|
|
|
|
|
|
if (LeftUpAfter.x > m_PicCtrlWidth - fitSizeImgWidth)
|
|
|
{
|
|
|
LeftUpAfter.x = m_PicCtrlWidth - fitSizeImgWidth;
|
|
|
}
|
|
|
|
|
|
if (LeftUpAfter.y < 0)
|
|
|
{
|
|
|
LeftUpAfter.y = 0;
|
|
|
}
|
|
|
|
|
|
if (LeftUpAfter.y > m_PicCtrlHeight - fitSizeImgHeight)
|
|
|
{
|
|
|
LeftUpAfter.y = m_PicCtrlHeight - fitSizeImgHeight;
|
|
|
}
|
|
|
|
|
|
// 实际偏移量
|
|
|
shift.x = LeftUpAfter.x - LeftUpBefore.x;
|
|
|
shift.y = LeftUpAfter.y - LeftUpBefore.y;
|
|
|
|
|
|
|
|
|
|
|
|
cvSetImageROI(fillblackImg, cvRect(static_cast<int>(LeftUpAfter.x), static_cast<int>(LeftUpAfter.y), fitSizeImgWidth, fitSizeImgHeight));
|
|
|
cvAdd(fillblackImg, fitSizeImg, fillblackImg);
|
|
|
cvResetImageROI( fillblackImg );
|
|
|
|
|
|
// 设置 ShowRegionOnScreen : 图像显示部分在dialog中的坐标
|
|
|
m_ShowRegionOnScreen.left = LeftUpAfter.x;
|
|
|
m_ShowRegionOnScreen.right = LeftUpAfter.x + fitSizeImgWidth;
|
|
|
m_ShowRegionOnScreen.top = LeftUpAfter.y;
|
|
|
m_ShowRegionOnScreen.bottom = LeftUpAfter.y + fitSizeImgHeight;
|
|
|
|
|
|
|
|
|
// 在图像中写字、添加信息示例
|
|
|
if (m_LatestQBData.image.bValid == true)
|
|
|
{
|
|
|
cv::Mat fillblackImgMat(fillblackImg, false);
|
|
|
cv::Scalar color(0, 255, 0);
|
|
|
if (fillblackImgMat.type() == CV_8UC1)
|
|
|
{
|
|
|
color = cv::Scalar(255);
|
|
|
}
|
|
|
|
|
|
// 图像显示比例
|
|
|
CString scale = 0;
|
|
|
scale.Format("%.1f", double(fitSizeImgWidth) / imgWidth * 100);
|
|
|
scale = scale + "%";
|
|
|
cv::putText(fillblackImgMat, scale.GetBuffer(0), cv::Point(10, fillblackImgMat.rows - 20), 2, 0.5, color);
|
|
|
}
|
|
|
|
|
|
// 释放 fitSizeImg
|
|
|
cvReleaseImage(&fitSizeImg);
|
|
|
fitSizeImg = NULL;
|
|
|
|
|
|
// 绘图
|
|
|
CvvImage img;
|
|
|
img.CopyOf(fillblackImg);
|
|
|
img.Show(hdc, 0, 0, fillblackImg->width, fillblackImg->height);
|
|
|
|
|
|
// 释放fillblackImg
|
|
|
cvReleaseImage(&fillblackImg);
|
|
|
fillblackImg = NULL;
|
|
|
|
|
|
// 释放
|
|
|
ReleaseDC(pDC);
|
|
|
|
|
|
return TRUE;
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.msg;
|
|
|
return FALSE;
|
|
|
}
|
|
|
catch(...)
|
|
|
{
|
|
|
return FALSE;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
// 1.5 功能:设置目标点像素坐标,如果设置合理,在在显示窗口中标绘目标
|
|
|
BOOL CImgShowDlg::SetTargetPixelCoordinate(const CPoint &point)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
// 设置目标点
|
|
|
m_LButtonDblClkPixelCoordinate = point; // 赋值给私有成员变量
|
|
|
|
|
|
if ((point.x >= m_ShowRegion.left) && (point.x <= m_ShowRegion.right) &&
|
|
|
(point.y >= m_ShowRegion.top) && (point.y <= m_ShowRegion.bottom) )
|
|
|
{
|
|
|
// 标绘目标:当目标点未显示到屏幕时,不标绘
|
|
|
DrawSquareOnScreen(GetScreenCoordinateBasedOnPixelCoordinate(m_LButtonDblClkPixelCoordinate));
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
// 先全景显示 再标绘
|
|
|
OnZoomFitImg();
|
|
|
|
|
|
// 标绘目标:当目标点未显示到屏幕时,不标绘
|
|
|
DrawSquareOnScreen(GetScreenCoordinateBasedOnPixelCoordinate(m_LButtonDblClkPixelCoordinate));
|
|
|
}
|
|
|
|
|
|
return TRUE;
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.msg;
|
|
|
return FALSE;
|
|
|
}
|
|
|
catch(...)
|
|
|
{
|
|
|
return FALSE;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 功能:标绘目标,其中输入为经纬度坐标
|
|
|
void CImgShowDlg::SetTgtLocLeadLonLat(double lon, double lat)
|
|
|
{
|
|
|
if (m_bFirstSignal == TRUE || m_bSecondSignal == TRUE)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (m_SrcFrame != NULL && m_SrcFrame->width > 0 && m_SrcFrame->height > 0)
|
|
|
{
|
|
|
if (m_boundbingBox.EastLon - m_boundbingBox.WestLon > 0
|
|
|
&& m_boundbingBox.WestLon >= -180
|
|
|
&& m_boundbingBox.WestLon <= 180
|
|
|
&& m_boundbingBox.EastLon >= -180
|
|
|
&& m_boundbingBox.EastLon <= 180
|
|
|
&& m_boundbingBox.NorthLat - m_boundbingBox.SouthLat > 0
|
|
|
&& m_boundbingBox.SouthLat >= -90
|
|
|
&& m_boundbingBox.SouthLat <= 90
|
|
|
&& m_boundbingBox.NorthLat >= -90
|
|
|
&& m_boundbingBox.NorthLat <= 90)
|
|
|
{
|
|
|
if (lon >= m_boundbingBox.WestLon
|
|
|
&& lon <= m_boundbingBox.EastLon
|
|
|
&& lat >= m_boundbingBox.SouthLat
|
|
|
&& lat <= m_boundbingBox.NorthLat)
|
|
|
{
|
|
|
double LonResolution = (m_boundbingBox.EastLon - m_boundbingBox.WestLon) / m_SrcFrame->width;
|
|
|
double LatResolution = (m_boundbingBox.NorthLat - m_boundbingBox.SouthLat) / m_SrcFrame->height;
|
|
|
|
|
|
CPoint pixelCord;
|
|
|
pixelCord.x = static_cast<LONG>((lon - m_boundbingBox.WestLon) / LonResolution);
|
|
|
pixelCord.y = static_cast<LONG>((m_boundbingBox.NorthLat - lat) / LatResolution);
|
|
|
|
|
|
SetTargetPixelCoordinate(pixelCord);
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
::MessageBoxA(NULL, _T("目标可能不在当前图像中!"),_T("操作提示"), MB_OK);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 绘制四个角点连成的区域
|
|
|
BOOL CImgShowDlg::SetQuadrangleCorners(const POINT* pts)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
if (pts != NULL)
|
|
|
{
|
|
|
m_corners[0] = pts[0];
|
|
|
m_corners[1] = pts[1];
|
|
|
m_corners[2] = pts[2];
|
|
|
m_corners[3] = pts[3];
|
|
|
|
|
|
POINT CornersOnScreen[4];
|
|
|
for (int i = 0; i < 4; i++)
|
|
|
{
|
|
|
CornersOnScreen[i] = GetScreenCoordinateBasedOnPixelCoordinate(m_corners[i]);
|
|
|
}
|
|
|
|
|
|
if (CornersOnScreen[0].x >= 0 && CornersOnScreen[0].y >= 0 &&
|
|
|
CornersOnScreen[1].x >= 0 && CornersOnScreen[1].y >= 0 &&
|
|
|
CornersOnScreen[2].x >= 0 && CornersOnScreen[2].y >= 0 &&
|
|
|
CornersOnScreen[3].x >= 0 && CornersOnScreen[3].y >= 0)
|
|
|
{
|
|
|
DrawQuadrangleOnScreen(CornersOnScreen);
|
|
|
}
|
|
|
|
|
|
return TRUE;
|
|
|
}
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.msg;
|
|
|
return FALSE;
|
|
|
}
|
|
|
catch(...)
|
|
|
{
|
|
|
return FALSE;
|
|
|
}
|
|
|
|
|
|
return FALSE;
|
|
|
}
|
|
|
|
|
|
|
|
|
// 1.6 功能:绘制指北针
|
|
|
// void CImgShowDlg::DrawNorthDirection(const POINT ¢er, double angle)
|
|
|
// {
|
|
|
// try
|
|
|
// {
|
|
|
// int r = 20; // 中心点到底角的长度
|
|
|
// int R = 30; // 中心点到顶点的长度
|
|
|
//
|
|
|
// double LocalAngle = 50.0; // 控制指北针尖锐程度
|
|
|
// LocalAngle = LocalAngle/180.0 * 3.1415926535;
|
|
|
//
|
|
|
// CDC* pDC = NULL;
|
|
|
// pDC = this->GetDC();
|
|
|
//
|
|
|
// // 判断,若pDC为空,直接返回,后面程序也无需再判定pDC
|
|
|
// if (pDC == NULL)
|
|
|
// {
|
|
|
// return;
|
|
|
// }
|
|
|
//
|
|
|
// // 创建并选择画笔
|
|
|
// CPen aPen;
|
|
|
// aPen.CreatePen(PS_SOLID, 2, RGB(0,255,0));
|
|
|
//
|
|
|
// CPen * pOldPen = NULL;
|
|
|
// pOldPen = pDC->SelectObject(&aPen);
|
|
|
//
|
|
|
// // 设置背景透明 用于写字
|
|
|
// pDC->SetBkMode(TRANSPARENT);
|
|
|
// pDC->SetTextColor(RGB(0,255,0));
|
|
|
//
|
|
|
// // 绘制图形需要的五个点
|
|
|
// POINT point[5];
|
|
|
//
|
|
|
// // 零度时各点相对于中心点的位置
|
|
|
// point[0].x = - static_cast<LONG>(r * cos(LocalAngle));
|
|
|
// point[0].y = static_cast<LONG>(r * sin(LocalAngle));
|
|
|
//
|
|
|
// point[1].x = 0L;
|
|
|
// point[1].y = - static_cast<LONG>(R);
|
|
|
//
|
|
|
// point[2].x = static_cast<LONG>(r * cos(LocalAngle));
|
|
|
// point[2].y = static_cast<LONG>(r * sin(LocalAngle));
|
|
|
//
|
|
|
// point[3].x = 0L;
|
|
|
// point[3].y = 0L;
|
|
|
//
|
|
|
// point[4].x = - 4L;
|
|
|
// point[4].y = - static_cast<LONG>(R + 16);
|
|
|
//
|
|
|
// // 各点旋转一定角度,并平移至以center为中心的坐标
|
|
|
// for(int i = 0; i < 5; i++)
|
|
|
// {
|
|
|
// point[i] = RotateShiftPoint(point[i],angle,center);
|
|
|
// }
|
|
|
//
|
|
|
// // 绘图
|
|
|
// pDC->MoveTo(point[0]);
|
|
|
// pDC->LineTo(point[1]);
|
|
|
// pDC->LineTo(point[2]);
|
|
|
// pDC->LineTo(point[3]);
|
|
|
// pDC->LineTo(point[0]);
|
|
|
//
|
|
|
// // 画圆圈
|
|
|
// CBrush* pBrush = CBrush::FromHandle((HBRUSH)GetStockObject(NULL_BRUSH));
|
|
|
// CBrush* pOldBrush = pDC->SelectObject(pBrush);
|
|
|
// R = R + 2;
|
|
|
// pDC->Ellipse(point[3].x - R, point[3].y - R, point[3].x + R, point[3].y + R);
|
|
|
// pDC->SelectObject(pOldBrush);
|
|
|
//
|
|
|
// // 写字:N
|
|
|
// // 转换为【0,360】
|
|
|
// angle = (angle/360.0 - static_cast<int>(angle/360.0)) * 360.0;
|
|
|
// if (angle < 0)
|
|
|
// {
|
|
|
// angle += 360;
|
|
|
// }
|
|
|
//
|
|
|
// // 判断并修正,经验值
|
|
|
// if (angle <= 45)
|
|
|
// {
|
|
|
// point[4].y -= 3;
|
|
|
// }
|
|
|
//
|
|
|
// if ((angle > 45) && (angle <= 135))
|
|
|
// {
|
|
|
// point[4].x -= 8;
|
|
|
// point[4].y -= 3;
|
|
|
// }
|
|
|
//
|
|
|
// if ((angle > 135) && (angle <= 225))
|
|
|
// {
|
|
|
// point[4].x -= 8;
|
|
|
// point[4].y -= 10;
|
|
|
// }
|
|
|
//
|
|
|
// if ((angle > 225) && (angle <= 315))
|
|
|
// {
|
|
|
// point[4].y -= 10;
|
|
|
// }
|
|
|
//
|
|
|
// if (angle > 315)
|
|
|
// {
|
|
|
// point[4].y -= 6;
|
|
|
// }
|
|
|
//
|
|
|
// // 写N
|
|
|
// pDC->TextOutA(static_cast<int>(point[4].x), static_cast<int>(point[4].y), "N");
|
|
|
//
|
|
|
// // 选回旧画笔
|
|
|
// pDC->SelectObject(pOldPen);
|
|
|
//
|
|
|
// // 释放pDC
|
|
|
// ReleaseDC(pDC);
|
|
|
// pDC = NULL;
|
|
|
// }
|
|
|
// catch(cv::Exception &e)
|
|
|
// {
|
|
|
// e.msg;
|
|
|
// return;
|
|
|
// }
|
|
|
// catch(...)
|
|
|
// {
|
|
|
// return;
|
|
|
// }
|
|
|
// }
|
|
|
//
|
|
|
// //1.7 功能:设置指北针中心
|
|
|
// void CImgShowDlg::SetNorthDirectionCenter(const POINT ¢er)
|
|
|
// {
|
|
|
// CRect rect;
|
|
|
// GetClientRect(&rect);
|
|
|
//
|
|
|
// if ((center.x > 0) && (center.x < rect.Width()) &&
|
|
|
// (center.y > 0) && (center.y < rect.Height()))
|
|
|
// {
|
|
|
// m_NorthDirectionCenter = center;
|
|
|
// }
|
|
|
// }
|
|
|
|
|
|
|
|
|
// 1.8 功能:基于私有成员变量LatestQBData 显示图像和指北针
|
|
|
// 说明:当dst有效时,优先显示dst,否则显示src
|
|
|
void CImgShowDlg::ShowLatestQBData()
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
// geoImg
|
|
|
if ((m_LatestQBData.image.bValid == true) && // 图像数据有效
|
|
|
(m_LatestQBData.image.geoImg.buff != nullptr) && // 图像有数据
|
|
|
(m_LatestQBData.image.geoImg.ImgWidth > 0) && (m_LatestQBData.image.geoImg.ImgHeight > 0) && // 图像尺寸有效
|
|
|
(m_LatestQBData.image.geoImg.bitcount > 0)) // 数据位数有效
|
|
|
{
|
|
|
// 创建临时变量:图像头
|
|
|
BITMAPINFO imgheader;
|
|
|
imgheader.bmiHeader.biWidth = static_cast<int>(m_LatestQBData.image.geoImg.ImgWidth);
|
|
|
imgheader.bmiHeader.biHeight = static_cast<int>(m_LatestQBData.image.geoImg.ImgHeight);
|
|
|
imgheader.bmiHeader.biBitCount = static_cast<WORD>(m_LatestQBData.image.geoImg.bitcount);
|
|
|
|
|
|
// 显示图像
|
|
|
ShowOneImage(&imgheader, m_LatestQBData.image.geoImg.buff, FALSE, NULL, FALSE, m_ImgRatioOnScreen, m_ImgShowShift);
|
|
|
|
|
|
if (min(m_ShowRegionOnScreen.Width(), m_ShowRegionOnScreen.Height()) <= 10)
|
|
|
{
|
|
|
m_ImgRatioOnScreen = m_ImgRatioOnScreen / 0.9F;
|
|
|
}
|
|
|
}
|
|
|
// dstImg
|
|
|
else if ((m_LatestQBData.image.bValid == true) && // 图像数据有效
|
|
|
(m_LatestQBData.image.dstImg.buff != nullptr) && // 图像有数据
|
|
|
(m_LatestQBData.image.dstImg.ImgWidth > 0) && (m_LatestQBData.image.dstImg.ImgHeight > 0) && // 图像尺寸有效
|
|
|
(m_LatestQBData.image.dstImg.bitcount > 0)) // 数据位数有效
|
|
|
{
|
|
|
// 创建临时变量:图像头
|
|
|
BITMAPINFO imgheader;
|
|
|
imgheader.bmiHeader.biWidth = static_cast<int>(m_LatestQBData.image.dstImg.ImgWidth);
|
|
|
imgheader.bmiHeader.biHeight = static_cast<int>(m_LatestQBData.image.dstImg.ImgHeight);
|
|
|
imgheader.bmiHeader.biBitCount = static_cast<WORD>(m_LatestQBData.image.dstImg.bitcount);
|
|
|
|
|
|
// 显示图像
|
|
|
ShowOneImage(&imgheader, m_LatestQBData.image.dstImg.buff, FALSE, NULL, FALSE, m_ImgRatioOnScreen, m_ImgShowShift);
|
|
|
|
|
|
if (min(m_ShowRegionOnScreen.Width(), m_ShowRegionOnScreen.Height()) <= 10)
|
|
|
{
|
|
|
m_ImgRatioOnScreen = m_ImgRatioOnScreen / 0.9F;
|
|
|
}
|
|
|
}
|
|
|
// srcImg
|
|
|
else if ((m_LatestQBData.image.bValid == true) && // 图像数据有效
|
|
|
(m_LatestQBData.image.srcImg.buff != nullptr) && // 图像有数据
|
|
|
(m_LatestQBData.image.srcImg.ImgWidth > 0) && (m_LatestQBData.image.srcImg.ImgHeight > 0) && // 图像尺寸有效
|
|
|
(m_LatestQBData.image.srcImg.bitcount > 0)) // 数据位数有效
|
|
|
{
|
|
|
// 创建临时变量:图像头
|
|
|
BITMAPINFO imgheader;
|
|
|
imgheader.bmiHeader.biWidth = static_cast<LONG>(m_LatestQBData.image.srcImg.ImgWidth);
|
|
|
imgheader.bmiHeader.biHeight = static_cast<LONG>(m_LatestQBData.image.srcImg.ImgHeight);
|
|
|
imgheader.bmiHeader.biBitCount = static_cast<WORD>(m_LatestQBData.image.srcImg.bitcount);
|
|
|
|
|
|
// 显示图像
|
|
|
ShowOneImage(&imgheader, m_LatestQBData.image.srcImg.buff, FALSE, NULL, FALSE, m_ImgRatioOnScreen, m_ImgShowShift);
|
|
|
|
|
|
if (min(m_ShowRegionOnScreen.Width(), m_ShowRegionOnScreen.Height()) <= 10)
|
|
|
{
|
|
|
m_ImgRatioOnScreen = m_ImgRatioOnScreen / 0.9F;
|
|
|
}
|
|
|
}
|
|
|
else // 图像数据无效
|
|
|
{
|
|
|
|
|
|
// 如果当前帧图像数据无效,则释放上一帧保存的图像
|
|
|
cvReleaseImage(&m_SrcFrame);
|
|
|
m_SrcFrame = NULL;
|
|
|
|
|
|
// 重绘窗口
|
|
|
CRect clientRect;
|
|
|
GetClientRect(&clientRect);
|
|
|
InvalidateRect(&clientRect);
|
|
|
UpdateWindow();
|
|
|
|
|
|
// 显示指北针
|
|
|
if (m_LatestQBData.framePart.bValid == TRUE) // 复接数据有效
|
|
|
{
|
|
|
// 设置在OnPaint中不绘制指北针
|
|
|
m_bPlotDirectionOnPaint = FALSE;
|
|
|
|
|
|
// 清除上次绘制的指北针
|
|
|
CRect rect;
|
|
|
rect.left = m_NorthDirectionCenter.x - 100;
|
|
|
rect.right = m_NorthDirectionCenter.x + 100;
|
|
|
rect.top = m_NorthDirectionCenter.y - 100;
|
|
|
rect.bottom = m_NorthDirectionCenter.y + 100;
|
|
|
|
|
|
InvalidateRect(&rect);
|
|
|
UpdateWindow();
|
|
|
|
|
|
// 恢复设置 OnPaint中重绘
|
|
|
m_bPlotDirectionOnPaint = TRUE;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.msg;
|
|
|
return;
|
|
|
}
|
|
|
catch(...)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
// 1.9 功能:获取双击目标点坐标 m_LButtonDblClkPixelCoordinate
|
|
|
CPoint CImgShowDlg::GetTargetCoordinate()
|
|
|
{
|
|
|
return m_LButtonDblClkPixelCoordinate;
|
|
|
}
|
|
|
|
|
|
|
|
|
// 1.10 功能:在对话框左上角显示信息
|
|
|
void CImgShowDlg::ShowMessageOnDialog(CString msg)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
// 获取窗口句柄
|
|
|
CWnd *pWnd = GetDlgItem(IDC_IMG_SHOW_PIC_CTRL);
|
|
|
|
|
|
CRect Rect;
|
|
|
pWnd->GetClientRect(&Rect);
|
|
|
|
|
|
// 获得控件的 DC
|
|
|
CDC *pDC=pWnd->GetDC();
|
|
|
|
|
|
// 设置背景透明
|
|
|
pDC->SetBkMode(TRANSPARENT);
|
|
|
|
|
|
// 设置字体颜色
|
|
|
pDC->SetTextColor(RGB(255,0,0));
|
|
|
|
|
|
// 输出信息
|
|
|
pDC->TextOutA(Rect.Width() - 130, Rect.Height() - 50, msg);
|
|
|
|
|
|
ReleaseDC(pDC);
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.msg;
|
|
|
return;
|
|
|
}
|
|
|
catch(...)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 3.1 功能:基于当前图像显示状态 和 像素坐标(图像某点的像素坐标),求该像素坐标对应的客户区坐标
|
|
|
CPoint CImgShowDlg::GetScreenCoordinateBasedOnPixelCoordinate(const POINT &PixelCoordinate)
|
|
|
{
|
|
|
// 返回值
|
|
|
CPoint screenCoordinate = CPoint(-100, -100);
|
|
|
|
|
|
try
|
|
|
{
|
|
|
// 如果该像素坐标显示在当前窗口中
|
|
|
if ((PixelCoordinate.x >= m_ShowRegion.left) && (PixelCoordinate.x <= m_ShowRegion.right) &&
|
|
|
(PixelCoordinate.y >= m_ShowRegion.top) && (PixelCoordinate.y <= m_ShowRegion.bottom) )
|
|
|
{
|
|
|
double ratio = 1.0;
|
|
|
|
|
|
// 计算屏幕坐标
|
|
|
if(m_ShowRegionOnScreen.Width() > 0)
|
|
|
{
|
|
|
ratio = m_ShowRegion.Width() * 1.0 / m_ShowRegionOnScreen.Width();
|
|
|
|
|
|
if (ratio > 0.0)
|
|
|
{
|
|
|
screenCoordinate.x = static_cast<LONG>((PixelCoordinate.x - m_ShowRegion.left) / ratio) + m_ShowRegionOnScreen.left;
|
|
|
screenCoordinate.y = static_cast<LONG>((PixelCoordinate.y - m_ShowRegion.top) / ratio) + m_ShowRegionOnScreen.top;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return screenCoordinate;
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.msg;
|
|
|
return screenCoordinate;
|
|
|
}
|
|
|
catch(...)
|
|
|
{
|
|
|
return screenCoordinate;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
// 3.2 功能:给定屏幕坐标,在屏幕中绘制标框, (可能)同时清除上次绘制的标框
|
|
|
void CImgShowDlg::DrawSquareOnScreen(const POINT &screenCoordinate, BOOL bErase)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
// 如果该点在图像显示区域中,则清除上次绘制的标框,同时标绘该点
|
|
|
int X = static_cast<int>(screenCoordinate.x); // X坐标
|
|
|
int Y = static_cast<int>(screenCoordinate.y); // Y坐标
|
|
|
|
|
|
if (X > m_ShowRegionOnScreen.left && X < m_ShowRegionOnScreen.right &&
|
|
|
Y > m_ShowRegionOnScreen.top && Y < m_ShowRegionOnScreen.bottom ) // 鼠标在图像上
|
|
|
{
|
|
|
// 绘制标框
|
|
|
if (bErase == TRUE)
|
|
|
{
|
|
|
// 去掉上次标绘的框
|
|
|
InvalidateRect(&m_LatestPlotRect, FALSE);
|
|
|
UpdateWindow();
|
|
|
}
|
|
|
|
|
|
CDC* pDC = this->GetDC();
|
|
|
CPen newPen; // 创建新画笔
|
|
|
newPen.CreatePen(PS_SOLID, 2, RGB(0, 255, 0));
|
|
|
|
|
|
CPen* pOldPen = NULL;
|
|
|
if (pDC != NULL)
|
|
|
{
|
|
|
pDC->SelectObject(&newPen);
|
|
|
|
|
|
// 绘图
|
|
|
pDC->MoveTo(X - 50, Y);
|
|
|
pDC->LineTo(X - 20, Y);
|
|
|
|
|
|
pDC->MoveTo(X + 20, Y);
|
|
|
pDC->LineTo(X + 50, Y);
|
|
|
|
|
|
pDC->MoveTo(X, Y - 50);
|
|
|
pDC->LineTo(X, Y - 20);
|
|
|
|
|
|
pDC->MoveTo(X, Y + 20);
|
|
|
pDC->LineTo(X, Y + 50);
|
|
|
|
|
|
pDC->MoveTo(X + 30, Y - 15);
|
|
|
pDC->LineTo(X + 30, Y - 30);
|
|
|
pDC->LineTo(X + 15, Y - 30);
|
|
|
|
|
|
pDC->MoveTo(X - 30, Y - 15);
|
|
|
pDC->LineTo(X - 30, Y - 30);
|
|
|
pDC->LineTo(X - 15, Y - 30);
|
|
|
|
|
|
pDC->MoveTo(X - 30, Y + 15);
|
|
|
pDC->LineTo(X - 30, Y + 30);
|
|
|
pDC->LineTo(X - 15, Y + 30);
|
|
|
|
|
|
pDC->MoveTo(X + 30, Y + 15);
|
|
|
pDC->LineTo(X + 30, Y + 30);
|
|
|
pDC->LineTo(X + 15, Y + 30);
|
|
|
|
|
|
// 中心点
|
|
|
pDC->MoveTo(X - 1, Y);
|
|
|
pDC->LineTo(X + 1, Y);
|
|
|
pDC->MoveTo(X , Y - 1);
|
|
|
pDC->LineTo(X , Y + 1);
|
|
|
|
|
|
// 回收旧画笔
|
|
|
pDC->SelectObject(pOldPen);
|
|
|
|
|
|
// 释放设备上下文指针
|
|
|
ReleaseDC(pDC);
|
|
|
pDC = NULL;
|
|
|
|
|
|
// 更新latestRect
|
|
|
m_LatestPlotRect.left = X - 51;
|
|
|
m_LatestPlotRect.right = X + 50;
|
|
|
m_LatestPlotRect.top = Y - 51;
|
|
|
m_LatestPlotRect.bottom = Y + 50;
|
|
|
}
|
|
|
|
|
|
// 设置为目标标绘状态
|
|
|
m_bPlotRect = TRUE;
|
|
|
}
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.msg;
|
|
|
return;
|
|
|
}
|
|
|
catch(...)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 3.2 功能:给定屏幕4个坐标,在屏幕中绘制四边形, (可能)同时清除上次绘制
|
|
|
// 输入:
|
|
|
// 1: screenCoordinate: 屏幕坐标
|
|
|
// 返回值:无
|
|
|
void CImgShowDlg::DrawQuadrangleOnScreen(const POINT screenCoordinate[4], BOOL bErase)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
// 如果该点在图像显示区域中,则清除上次绘制的标框,同时标绘该点
|
|
|
|
|
|
// 绘制标框
|
|
|
if (bErase == TRUE)
|
|
|
{
|
|
|
// 去掉上次标绘的框
|
|
|
InvalidateRect(&m_LatestPlotRect, FALSE);
|
|
|
UpdateWindow();
|
|
|
}
|
|
|
|
|
|
CDC* pDC = this->GetDC();
|
|
|
CPen newPen; // 创建新画笔
|
|
|
newPen.CreatePen(PS_SOLID, 2, RGB(0, 255, 0));
|
|
|
|
|
|
CPen* pOldPen = NULL;
|
|
|
if (pDC != NULL)
|
|
|
{
|
|
|
pDC->SelectObject(&newPen);
|
|
|
|
|
|
// 绘图
|
|
|
pDC->MoveTo(screenCoordinate[0].x, screenCoordinate[0].y);
|
|
|
pDC->LineTo(screenCoordinate[1].x, screenCoordinate[1].y);
|
|
|
pDC->LineTo(screenCoordinate[2].x, screenCoordinate[2].y);
|
|
|
pDC->LineTo(screenCoordinate[3].x, screenCoordinate[3].y);
|
|
|
pDC->LineTo(screenCoordinate[0].x, screenCoordinate[0].y);
|
|
|
|
|
|
// 回收旧画笔
|
|
|
pDC->SelectObject(pOldPen);
|
|
|
|
|
|
// 释放设备上下文指针
|
|
|
ReleaseDC(pDC);
|
|
|
pDC = NULL;
|
|
|
}
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.msg;
|
|
|
return;
|
|
|
}
|
|
|
catch(...)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
void CImgShowDlg::DoZoomInImg()
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
/************************************************************************/
|
|
|
/* 设计思路:
|
|
|
|
|
|
分两种情况:
|
|
|
情况1:当前图像的全部内容已经全部显示出来
|
|
|
情况2:当前只显示出部分图像
|
|
|
|
|
|
针对情况1:也存在两种情况:
|
|
|
(1.1) 全景显示: 此时 StrecthRatio = 1.0f
|
|
|
(1.2) 图像已经经过缩小显示,此时,StrecthRatio <= 0.901(考虑到存储精度),这时,放大10%显示即可,即StrecthRatio /= 0.9f;
|
|
|
|
|
|
针对情况2:只显示出部分图像,此时 StrecthRatio = 1.0f
|
|
|
/************************************************************************/
|
|
|
|
|
|
if ((m_ShowRegion.Width() == m_SrcFrame->width - 1) && (m_ShowRegion.Height() == m_SrcFrame->height - 1)) // 情况1
|
|
|
{
|
|
|
// 拉伸比例计算
|
|
|
if (m_ImgRatioOnScreen <= 0.901F) // (1.2) 目前图像是缩小显示
|
|
|
{
|
|
|
m_ImgRatioOnScreen /= 0.9F;
|
|
|
}
|
|
|
else // (1.1) 目前图像是充满显示,正好
|
|
|
{
|
|
|
m_ImgRatioOnScreen = 1.0F; // 继续放大时要求继续填满显示才符合逻辑,故设为:ImgRatioOnScreen = 1.0F
|
|
|
|
|
|
if (max(m_ShowRegion.Width(), m_ShowRegion.Height()) >= 100)
|
|
|
{
|
|
|
m_ShowRegion = GetNewRegionWhenZoom(true);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
else // 图像尚未完整显示 情况2
|
|
|
{
|
|
|
m_ImgRatioOnScreen = 1.0F; // 此时,无需拉伸比例控制
|
|
|
|
|
|
if (max(m_ShowRegion.Width(), m_ShowRegion.Height()) >= 100)
|
|
|
{
|
|
|
m_ShowRegion = GetNewRegionWhenZoom(true);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 显示图像
|
|
|
ShowOneImage(m_SrcFrame, TRUE, m_ShowRegion, m_ImgRatioOnScreen, m_ImgShowShift);
|
|
|
|
|
|
int a = 5;
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.msg;
|
|
|
return;
|
|
|
}
|
|
|
catch(...)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
CRect CImgShowDlg::GetNewRegionWhenZoom(bool in)
|
|
|
{
|
|
|
CRect newShowRegion = m_ShowRegion;
|
|
|
|
|
|
try
|
|
|
{
|
|
|
double ratio = 0.1;
|
|
|
if (in == true)
|
|
|
{
|
|
|
ratio = -ratio;
|
|
|
}
|
|
|
|
|
|
// 在当前显示区域的基础上,以中心点为基准点放大
|
|
|
int ShowRegionWidth = m_ShowRegion.Width() + 1;
|
|
|
int ShowRegionHeight = m_ShowRegion.Height() + 1;
|
|
|
|
|
|
newShowRegion.left = m_ShowRegion.left - static_cast<LONG>(ratio / 2 * ShowRegionWidth);
|
|
|
newShowRegion.right = m_ShowRegion.right + static_cast<LONG>(ratio / 2 * ShowRegionWidth);
|
|
|
newShowRegion.top = m_ShowRegion.top - static_cast<LONG>(ratio / 2 * ShowRegionHeight);
|
|
|
newShowRegion.bottom = m_ShowRegion.bottom + static_cast<LONG>(ratio / 2 * ShowRegionHeight);
|
|
|
|
|
|
// 在此修正,确保返回值有效
|
|
|
if (newShowRegion.left < 0)
|
|
|
{
|
|
|
newShowRegion.left = 0;
|
|
|
}
|
|
|
|
|
|
int _Width = m_SrcFrame->width;
|
|
|
int _Height = m_SrcFrame->height;
|
|
|
|
|
|
if (newShowRegion.right > _Width - 1)
|
|
|
{
|
|
|
newShowRegion.right = _Width - 1;
|
|
|
}
|
|
|
|
|
|
if (newShowRegion.top < 0)
|
|
|
{
|
|
|
newShowRegion.top = 0;
|
|
|
}
|
|
|
|
|
|
if (newShowRegion.bottom > _Height - 1)
|
|
|
{
|
|
|
newShowRegion.bottom = _Height - 1;
|
|
|
}
|
|
|
|
|
|
// 若无效,返回原始值
|
|
|
if (newShowRegion.right - newShowRegion.left <= 0 ||
|
|
|
newShowRegion.bottom - newShowRegion.top <= 0)
|
|
|
{
|
|
|
return m_ShowRegion;
|
|
|
}
|
|
|
|
|
|
// 调整 newShowRegion 目的:填充图像控件
|
|
|
double newShowRegion_WH_Ration = 1.0; // 当前 newShowRegion 的“宽高” 比例
|
|
|
double PicCtrl_WH_Ration = 1.0; // 当前图像控件的“宽高”比例
|
|
|
|
|
|
double newShowRegion_HW_Ration = 1.0; // 当前 newShowRegion 的“高宽”比例
|
|
|
double PicCtrl_HW_Ration = 1.0; // 当前图像控件的“高宽”比例
|
|
|
|
|
|
// 分母不为0判断
|
|
|
if ((newShowRegion.Height() > 0) && (m_PicCtrlHeight > 0))
|
|
|
{
|
|
|
newShowRegion_WH_Ration = static_cast<double>(newShowRegion.Width()) / static_cast<double>(newShowRegion.Height());
|
|
|
PicCtrl_WH_Ration = static_cast<double>(m_PicCtrlWidth) / static_cast<double>(m_PicCtrlHeight);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
return m_ShowRegion;
|
|
|
}
|
|
|
|
|
|
// 分母不为0判断
|
|
|
if ((newShowRegion_WH_Ration > 0.0) && (PicCtrl_WH_Ration > 0.0))
|
|
|
{
|
|
|
newShowRegion_HW_Ration = 1.0 / newShowRegion_WH_Ration;
|
|
|
PicCtrl_HW_Ration = 1.0 / PicCtrl_WH_Ration;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
return m_ShowRegion;
|
|
|
}
|
|
|
|
|
|
if (newShowRegion_WH_Ration > PicCtrl_WH_Ration) // 宽度已经填满时
|
|
|
{
|
|
|
// 图像上下填充
|
|
|
int newShowRegion_ideal_Height = 0; // 在现有图像显示宽度的基础上,图像显示区域的理想高度
|
|
|
newShowRegion_ideal_Height = static_cast<int>(newShowRegion.Width() * PicCtrl_HW_Ration);
|
|
|
|
|
|
// 上下补齐
|
|
|
newShowRegion.top -= static_cast<LONG>((newShowRegion_ideal_Height - newShowRegion.Height() + 1)/ 2); // + 1 是考虑到 0.5 误差影响
|
|
|
newShowRegion.bottom += static_cast<LONG>((newShowRegion_ideal_Height - newShowRegion.Height() + 1)/ 2); // + 1 是考虑到 0.5 误差影响
|
|
|
|
|
|
// 补齐后有可能越界 需进行修正
|
|
|
if (newShowRegion.top < 0) // 可能上边界越出图像边界
|
|
|
{
|
|
|
newShowRegion.bottom -= newShowRegion.top;
|
|
|
newShowRegion.top = 0L;
|
|
|
|
|
|
if (newShowRegion.bottom > static_cast<LONG>(_Height - 1))
|
|
|
{
|
|
|
newShowRegion.bottom = static_cast<LONG>(_Height - 1);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (newShowRegion.bottom > static_cast<LONG>(_Height - 1)) // 可能下边界越出图像边界
|
|
|
{
|
|
|
newShowRegion.top -= static_cast<LONG>((newShowRegion.bottom - _Height + 1));
|
|
|
newShowRegion.bottom = static_cast<LONG>(_Height - 1);
|
|
|
|
|
|
if (newShowRegion.top < 0L)
|
|
|
{
|
|
|
newShowRegion.top = 0L;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
else // 高度已经填满
|
|
|
{
|
|
|
// 图像左右填充
|
|
|
int newShowRegion_ideal_Width = 0; // 在现有图像显示高度的基础上,图像显示区域的理想宽度
|
|
|
newShowRegion_ideal_Width = static_cast<int>(newShowRegion.Height() * PicCtrl_WH_Ration);
|
|
|
|
|
|
// 左右补齐
|
|
|
newShowRegion.left -= static_cast<LONG>((newShowRegion_ideal_Width - newShowRegion.Width() + 1)/ 2); // + 1 是考虑到 0.5 误差影响
|
|
|
newShowRegion.right += static_cast<LONG>((newShowRegion_ideal_Width - newShowRegion.Width() + 1)/ 2); // + 1 是考虑到 0.5 误差影响
|
|
|
|
|
|
// 补齐后有可能越界 需进行修正
|
|
|
|
|
|
if (newShowRegion.left < 0L) // 可能左边界越出图像边界
|
|
|
{
|
|
|
newShowRegion.right -= newShowRegion.left;
|
|
|
newShowRegion.left = 0L;
|
|
|
|
|
|
if (newShowRegion.right > static_cast<LONG>(_Width - 1))
|
|
|
{
|
|
|
newShowRegion.right = static_cast<LONG>(_Width - 1);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (newShowRegion.right > static_cast<LONG>(_Width - 1)) // 可能右边界越出图像边界
|
|
|
{
|
|
|
newShowRegion.left -= static_cast<LONG>((newShowRegion.right - _Width + 1));
|
|
|
newShowRegion.right = static_cast<LONG>(_Width - 1);
|
|
|
|
|
|
if (newShowRegion.left < 0L)
|
|
|
{
|
|
|
newShowRegion.left = 0L;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 在此修正,确保返回值有效
|
|
|
if (newShowRegion.left < 0)
|
|
|
{
|
|
|
newShowRegion.left = 0;
|
|
|
}
|
|
|
|
|
|
if (newShowRegion.right > _Width - 1)
|
|
|
{
|
|
|
newShowRegion.right = _Width - 1;
|
|
|
}
|
|
|
|
|
|
if (newShowRegion.top < 0)
|
|
|
{
|
|
|
newShowRegion.top = 0;
|
|
|
}
|
|
|
|
|
|
if (newShowRegion.bottom > _Height - 1)
|
|
|
{
|
|
|
newShowRegion.bottom = _Height - 1;
|
|
|
}
|
|
|
|
|
|
return newShowRegion;
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.msg;
|
|
|
return newShowRegion;
|
|
|
}
|
|
|
catch(...)
|
|
|
{
|
|
|
return newShowRegion;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 3.6 功能: 执行图像缩小操作
|
|
|
void CImgShowDlg::DoZoomOutImg()
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
// 计算图像显示区域,更新:ShowRegion
|
|
|
|
|
|
/************************************************************************/
|
|
|
/* 设计思路:
|
|
|
|
|
|
分两种情况:
|
|
|
情况1:当前图像的全部内容已经全部显示出来,继续拉伸比例缩小显示即可
|
|
|
情况2:当前只显示出部分图像,计算新的显示区域
|
|
|
/************************************************************************/
|
|
|
|
|
|
// 是否已经显示全部图像内容
|
|
|
if ((m_ShowRegion.Width() == m_SrcFrame->width - 1) && (m_ShowRegion.Height() == m_SrcFrame->height - 1))
|
|
|
{
|
|
|
if (max(m_ShowRegionOnScreen.Width(), m_ShowRegionOnScreen.Height()) > 10)
|
|
|
{
|
|
|
m_ImgRatioOnScreen *= 0.9F;
|
|
|
}
|
|
|
}
|
|
|
else // 图像尚未完整显示
|
|
|
{
|
|
|
// 自适应计算 ShowRegion
|
|
|
m_ShowRegion = GetNewRegionWhenZoom(false);
|
|
|
|
|
|
m_ImgRatioOnScreen = 1.0F; // 此时,无需拉伸比例控制
|
|
|
}
|
|
|
|
|
|
// 显示图像
|
|
|
ShowOneImage(m_SrcFrame, TRUE, m_ShowRegion, m_ImgRatioOnScreen, m_ImgShowShift);
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.msg;
|
|
|
return;
|
|
|
}
|
|
|
catch(...)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 3.7 功能: 当漫游图像时,自适应计算新的图像显示区
|
|
|
CRect CImgShowDlg::GetNewRegionWhenRoamImg(int deltaX, int deltaY)
|
|
|
{
|
|
|
// 返回值,初始化为当前显示区域
|
|
|
CRect newShowRegion = m_ShowRegion; // 新的图像显示区域
|
|
|
|
|
|
newShowRegion.left = m_ShowRegion.left - deltaX;
|
|
|
newShowRegion.right = m_ShowRegion.right - deltaX;
|
|
|
newShowRegion.top = m_ShowRegion.top - deltaY;
|
|
|
newShowRegion.bottom = m_ShowRegion.bottom - deltaY;
|
|
|
|
|
|
int m_Width = m_SrcFrame->width;
|
|
|
int m_Height = m_SrcFrame->height;
|
|
|
|
|
|
if (newShowRegion.left < 0L)
|
|
|
{
|
|
|
newShowRegion.right -= newShowRegion.left;
|
|
|
newShowRegion.left = 0L;
|
|
|
|
|
|
if (newShowRegion.right > static_cast<LONG>(m_Width - 1))
|
|
|
{
|
|
|
newShowRegion.right = static_cast<LONG>(m_Width - 1);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (newShowRegion.right > static_cast<LONG>(m_Width - 1))
|
|
|
{
|
|
|
newShowRegion.left -= static_cast<LONG>((newShowRegion.right - m_Width + 1));
|
|
|
newShowRegion.right = static_cast<LONG>(m_Width - 1);
|
|
|
|
|
|
if (newShowRegion.left < 0L)
|
|
|
{
|
|
|
newShowRegion.left = 0L;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (newShowRegion.top < 0)
|
|
|
{
|
|
|
newShowRegion.bottom -= newShowRegion.top;
|
|
|
newShowRegion.top = 0L;
|
|
|
|
|
|
if (newShowRegion.bottom > static_cast<LONG>(m_Height - 1))
|
|
|
{
|
|
|
newShowRegion.bottom = static_cast<LONG>(m_Height - 1);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (newShowRegion.bottom > static_cast<LONG>(m_Height - 1))
|
|
|
{
|
|
|
newShowRegion.top -= static_cast<LONG>((newShowRegion.bottom - m_Height + 1));
|
|
|
newShowRegion.bottom = static_cast<LONG>(m_Height - 1);
|
|
|
|
|
|
if (newShowRegion.top < 0L)
|
|
|
{
|
|
|
newShowRegion.top = 0L;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 在此修正,确保返回值有效
|
|
|
if (newShowRegion.left < 0)
|
|
|
{
|
|
|
newShowRegion.left = 0;
|
|
|
}
|
|
|
|
|
|
if (newShowRegion.right > m_Width - 1)
|
|
|
{
|
|
|
newShowRegion.right = m_Width - 1;
|
|
|
}
|
|
|
|
|
|
if (newShowRegion.top < 0)
|
|
|
{
|
|
|
newShowRegion.top = 0;
|
|
|
}
|
|
|
|
|
|
if (newShowRegion.bottom > m_Height - 1)
|
|
|
{
|
|
|
newShowRegion.bottom = m_Height - 1;
|
|
|
}
|
|
|
|
|
|
return newShowRegion;
|
|
|
}
|
|
|
|
|
|
|
|
|
// 3.8 功能: 执行图像全景(全屏)操作
|
|
|
void CImgShowDlg::DoZoomFitImg()
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
// 保证有图像
|
|
|
if (m_SrcFrame != NULL)
|
|
|
{
|
|
|
// 设置为整个图像显示
|
|
|
m_ShowRegion.left = 0L;
|
|
|
m_ShowRegion.right = static_cast<LONG>(m_SrcFrame->width - 1);
|
|
|
m_ShowRegion.top = 0L;
|
|
|
m_ShowRegion.bottom = static_cast<LONG>(m_SrcFrame->height - 1);
|
|
|
|
|
|
// 拉伸比例归1
|
|
|
m_ImgRatioOnScreen = 1.0F; // 复位
|
|
|
|
|
|
// 平移量归零
|
|
|
m_ImgShowShift.x = 0L;
|
|
|
m_ImgShowShift.y = 0L;
|
|
|
|
|
|
// 全景显示图像
|
|
|
ShowWholeImage(m_SrcFrame, m_ImgRatioOnScreen, m_ImgShowShift);
|
|
|
}
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.msg;
|
|
|
return;
|
|
|
}
|
|
|
catch(...)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// CImgShowDlg 消息处理程序
|
|
|
|
|
|
|
|
|
BOOL CImgShowDlg::OnEraseBkgnd(CDC* pDC)
|
|
|
{
|
|
|
// 背景色为黑色
|
|
|
CRect Rect;
|
|
|
GetClientRect(&Rect);
|
|
|
pDC->FillSolidRect(Rect, RGB(0, 0, 0)); //设置窗口背景颜色为黑色
|
|
|
return TRUE;
|
|
|
}
|
|
|
|
|
|
|
|
|
void CImgShowDlg::OnPaint()
|
|
|
{
|
|
|
CPaintDC dc(this); // device context for painting
|
|
|
|
|
|
try
|
|
|
{
|
|
|
if (m_SrcFrame != NULL)
|
|
|
{
|
|
|
// 重绘图像
|
|
|
ShowOneImage(m_SrcFrame, TRUE, m_ShowRegion, m_ImgRatioOnScreen, m_ImgShowShift);
|
|
|
|
|
|
if (min(m_ShowRegionOnScreen.Width(), m_ShowRegionOnScreen.Height()) <= 10)
|
|
|
{
|
|
|
m_ImgRatioOnScreen = m_ImgRatioOnScreen / 0.9F;
|
|
|
}
|
|
|
|
|
|
if (m_bPlotRectOnPaint == TRUE)
|
|
|
{
|
|
|
// 标绘目标点 标绘窗口
|
|
|
DrawSquareOnScreen(GetScreenCoordinateBasedOnPixelCoordinate(m_LButtonDblClkPixelCoordinate), FALSE);
|
|
|
}
|
|
|
|
|
|
// 视场标绘
|
|
|
// SetQuadrangleCorners(m_corners);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if (m_sThemeText != "")
|
|
|
{
|
|
|
// 写字:图像窗口
|
|
|
// 获取窗口句柄
|
|
|
CWnd *pWnd = NULL;
|
|
|
pWnd = GetDlgItem(IDC_IMG_SHOW_PIC_CTRL);
|
|
|
|
|
|
if (pWnd == NULL)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// 获得控件的 DC
|
|
|
CDC *pDC = NULL;
|
|
|
pDC = pWnd->GetDC();
|
|
|
if (pDC == NULL)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
CFont font;
|
|
|
font.CreatePointFont(180,"Times New Roman");
|
|
|
|
|
|
CFont *pOldFont = pDC->SelectObject(&font);
|
|
|
|
|
|
// 设置背景透明
|
|
|
pDC->SetBkMode(TRANSPARENT);
|
|
|
|
|
|
// 设置字体颜色
|
|
|
pDC->SetTextColor(RGB(0,255,255));
|
|
|
|
|
|
// 确定输出位置
|
|
|
CRect Rect;
|
|
|
GetClientRect(&Rect);
|
|
|
int x = Rect.left + 5;
|
|
|
int y = Rect.bottom - 28;
|
|
|
|
|
|
// 输出信息
|
|
|
pDC->TextOutA(x, y, m_sThemeText);
|
|
|
|
|
|
pDC->SelectObject(pOldFont);
|
|
|
|
|
|
ReleaseDC(pDC);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.msg;
|
|
|
return;
|
|
|
}
|
|
|
catch(...)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 5.10 右键响应函数
|
|
|
// 功能:弹出右键菜单,进行功能选择
|
|
|
void CImgShowDlg::OnRButtonDown(UINT nFlags, CPoint point)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
if (m_bCloseRughtBtnMenu == false)
|
|
|
{
|
|
|
// 加载菜单项
|
|
|
CMenu menu;
|
|
|
menu.LoadMenu(IDR_MENU_IMG_PROCESS);
|
|
|
|
|
|
// 保留右键坐标 由于定位导引 或 右键图像放大
|
|
|
m_RButtonPt = point;
|
|
|
|
|
|
// 输入坐标为客户区坐标,也就是相对本对话框(左上角为(0,0))的坐标转换到屏幕坐标
|
|
|
ClientToScreen(&point);
|
|
|
|
|
|
// 九宫格快速浏览图像
|
|
|
if (m_pFastLookUpDlg != NULL && m_pFastLookUpDlg->IsWindowVisible() == TRUE)
|
|
|
{
|
|
|
menu.GetSubMenu(0)->CheckMenuItem(ID_FAST_LOOKUP_IMGS, MF_BYCOMMAND | MF_CHECKED);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
menu.GetSubMenu(0)->CheckMenuItem(ID_FAST_LOOKUP_IMGS, MF_BYCOMMAND | MF_UNCHECKED);
|
|
|
}
|
|
|
|
|
|
// menu.GetSubMenu(0)->EnableMenuItem(ID_FAST_LOOKUP_IMGS, MF_GRAYED); // MF_ENABLED
|
|
|
|
|
|
// 标绘 目标 矩形
|
|
|
if (m_bDrawSquareOnImg == TRUE)
|
|
|
{
|
|
|
menu.GetSubMenu(0)->CheckMenuItem(ID_DRAW_SQUARE_ON_IMG, MF_BYCOMMAND | MF_CHECKED);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
menu.GetSubMenu(0)->CheckMenuItem(ID_DRAW_SQUARE_ON_IMG, MF_BYCOMMAND | MF_UNCHECKED);
|
|
|
}
|
|
|
|
|
|
// 目标扣取
|
|
|
if (m_bGetTgtImgOn == true)
|
|
|
{
|
|
|
menu.GetSubMenu(0)->CheckMenuItem(ID_GET_TARGET_IMG, MF_BYCOMMAND | MF_CHECKED);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
menu.GetSubMenu(0)->CheckMenuItem(ID_GET_TARGET_IMG, MF_BYCOMMAND | MF_UNCHECKED);
|
|
|
}
|
|
|
|
|
|
if (m_bClipImgOn == TRUE)
|
|
|
{
|
|
|
menu.GetSubMenu(0)->CheckMenuItem(ID_CLIP_IMG, MF_BYCOMMAND | MF_CHECKED);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
menu.GetSubMenu(0)->CheckMenuItem(ID_CLIP_IMG, MF_BYCOMMAND | MF_UNCHECKED);
|
|
|
}
|
|
|
|
|
|
// 弹出菜单
|
|
|
menu.GetSubMenu(0)->TrackPopupMenu( TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_RIGHTBUTTON,
|
|
|
static_cast<int>(point.x), static_cast<int>(point.y), this); // 只在本窗口内作出相应
|
|
|
}
|
|
|
|
|
|
CDialog::OnRButtonDown(nFlags, point);
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.msg;
|
|
|
return;
|
|
|
}
|
|
|
catch(...)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 功能:设置图像在屏幕中的显示比例
|
|
|
void CImgShowDlg::SetImgShowRationOnScreen(float ratio)
|
|
|
{
|
|
|
if(ratio >= 1.0F || ratio <= 0.0F)
|
|
|
{
|
|
|
ratio = 1.0F;
|
|
|
}
|
|
|
|
|
|
// 修改全局变量 ImgRatioOnScreen
|
|
|
m_ImgRatioOnScreen = ratio;
|
|
|
}
|
|
|
|
|
|
void CImgShowDlg::OnZoomInImg()
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
// 如果有外部信号输入,操作与视频模式下相同
|
|
|
if (m_bFirstSignal == TRUE || m_bSecondSignal == TRUE)
|
|
|
{
|
|
|
SetImgShowRationOnScreen(m_ImgRatioOnScreen / 0.9F);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// 放大显示图像
|
|
|
DoZoomInImg();
|
|
|
|
|
|
// 更新标绘窗口
|
|
|
DrawSquareOnScreen(GetScreenCoordinateBasedOnPixelCoordinate(m_LButtonDblClkPixelCoordinate));
|
|
|
|
|
|
// 设置无效,不保留上次值
|
|
|
m_RButtonPt.x = -100;
|
|
|
m_RButtonPt.y = -100;
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.msg;
|
|
|
return;
|
|
|
}
|
|
|
catch(...)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
void CImgShowDlg::OnZoomOutImg()
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
// 如果有外部信号输入 操作与视频模式下相同
|
|
|
if (m_bFirstSignal == TRUE || m_bSecondSignal == TRUE)
|
|
|
{
|
|
|
SetImgShowRationOnScreen(m_ImgRatioOnScreen * 0.9F);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// 缩小显示图像
|
|
|
DoZoomOutImg();
|
|
|
|
|
|
// 更新标绘窗口
|
|
|
DrawSquareOnScreen(GetScreenCoordinateBasedOnPixelCoordinate(m_LButtonDblClkPixelCoordinate));
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.msg;
|
|
|
return;
|
|
|
}
|
|
|
catch(...)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
void CImgShowDlg::OnZoomFitImg()
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
// 如果有外部信号输入 操作与视频模式下相同
|
|
|
if (m_bFirstSignal == TRUE || m_bSecondSignal == TRUE)
|
|
|
{
|
|
|
// 视频显示模式复位
|
|
|
m_ImgRatioOnScreen = 1.0F;
|
|
|
m_ImgShowShift.x = 0L;
|
|
|
m_ImgShowShift.y = 0L;
|
|
|
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// 直接全景显示图像
|
|
|
DoZoomFitImg();
|
|
|
|
|
|
// 更新标绘窗口
|
|
|
DrawSquareOnScreen(GetScreenCoordinateBasedOnPixelCoordinate(m_LButtonDblClkPixelCoordinate));
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.msg;
|
|
|
return;
|
|
|
}
|
|
|
catch(...)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
void CImgShowDlg::OnConcelTargetPlot()
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
// 在onPaint中不重绘
|
|
|
m_bPlotRectOnPaint = FALSE;
|
|
|
|
|
|
// 去掉上次标绘的框
|
|
|
InvalidateRect(&m_LatestPlotRect, FALSE);
|
|
|
UpdateWindow(); // 发送消息 立即响应
|
|
|
|
|
|
// 设置为 小于0 的无效值
|
|
|
m_LButtonDblClkPixelCoordinate.x = -1;
|
|
|
m_LButtonDblClkPixelCoordinate.y = -1;
|
|
|
|
|
|
// 结束绘制
|
|
|
m_bPlotRect = FALSE;
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.msg;
|
|
|
return;
|
|
|
}
|
|
|
catch(...)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
// 功能:保存当前帧图像及信息
|
|
|
BOOL CImgShowDlg::SaveCurrentDecodedFrame()
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
// 计算存储路径
|
|
|
static int imgSaveOrder = 1;
|
|
|
|
|
|
// 图像数据有效
|
|
|
// 说明:程序设计中,SrcFrame代表当前图像
|
|
|
if (m_SrcFrame != NULL)
|
|
|
{
|
|
|
// 计算图像和复接数据存储路径
|
|
|
SYSTEMTIME CurrentTime;
|
|
|
GetLocalTime(&CurrentTime);
|
|
|
|
|
|
CString ImgSavePath;
|
|
|
ImgSavePath.Format( "%04d%02d%02d_%02d%02d%02d%04d",
|
|
|
CurrentTime.wYear,
|
|
|
CurrentTime.wMonth,
|
|
|
CurrentTime.wDay,
|
|
|
CurrentTime.wHour,
|
|
|
CurrentTime.wMinute,
|
|
|
CurrentTime.wSecond,
|
|
|
CurrentTime.wMilliseconds);
|
|
|
// 添加序号
|
|
|
CString sImgSaveOlder;
|
|
|
sImgSaveOlder.Format("%04d", imgSaveOrder);
|
|
|
|
|
|
ImgSavePath = ImgSavePath + "_" + sImgSaveOlder;
|
|
|
|
|
|
CString FJSavePath;
|
|
|
FJSavePath = ImgSavePath; // 共享同一时间
|
|
|
|
|
|
CString FImgSavePath;
|
|
|
FImgSavePath = ImgSavePath; // 共享同一时间
|
|
|
|
|
|
// 校验保存路径
|
|
|
if (m_sSaveCurrentImgFolder == "" || false == SearchDirectory(m_sSaveCurrentImgFolder))
|
|
|
{
|
|
|
m_sSaveCurrentImgFolder = "";
|
|
|
}
|
|
|
|
|
|
if (m_sSaveCurrentImgFolder == "")
|
|
|
{
|
|
|
ImgSavePath = m_sImgSaveFolder + "\\" + ImgSavePath + ".bmp"; // 完整图像存储路径
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
ImgSavePath = m_sSaveCurrentImgFolder + "\\" + ImgSavePath + ".bmp"; // 完整图像存储路径
|
|
|
}
|
|
|
|
|
|
|
|
|
// 确保有文件夹,如果中途误删,会再次创建
|
|
|
if (SearchDirectory(m_sRootFolder) == FALSE) // 没找到根文件夹
|
|
|
{
|
|
|
CreateDirectory(m_sRootFolder, NULL);
|
|
|
}
|
|
|
if (SearchDirectory(m_sImgSaveFolder) == FALSE) // 没找到【图像】文件夹
|
|
|
{
|
|
|
CreateDirectory(m_sImgSaveFolder, NULL);
|
|
|
}
|
|
|
|
|
|
// 转化
|
|
|
cv::Mat img(m_SrcFrame, false);
|
|
|
|
|
|
// 保存图像
|
|
|
if (true == cv::imwrite(ImgSavePath.GetBuffer(0), img))
|
|
|
{
|
|
|
// 保存路径回调
|
|
|
if (m_lpSendFilePath != NULL)
|
|
|
{
|
|
|
m_lpSendFilePath(ImgSavePath, 0);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
imgSaveOrder++;
|
|
|
|
|
|
m_sSaveCurrentImgFolder = ""; // 复位
|
|
|
|
|
|
return TRUE;
|
|
|
}
|
|
|
|
|
|
return FALSE;
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.msg;
|
|
|
m_sSaveCurrentImgFolder = ""; // 复位
|
|
|
return FALSE;
|
|
|
}
|
|
|
catch(...)
|
|
|
{
|
|
|
m_sSaveCurrentImgFolder = ""; // 复位
|
|
|
return FALSE;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 保存当前帧
|
|
|
void CImgShowDlg::OnSaveCurrentFrame()
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
SaveCurrentDecodedFrame();
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.msg;
|
|
|
return;
|
|
|
}
|
|
|
catch(...)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 功能:是否需要记忆前面多帧(18帧)图像信息
|
|
|
// 输入:
|
|
|
// 1. bMem TRUE:记忆 FALSE:不记忆
|
|
|
// 输出:无
|
|
|
void CImgShowDlg::MemPreMultiFrame(BOOL bMem)
|
|
|
{
|
|
|
m_bMemPreMultiFrame = bMem;
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 左键按下消息响应
|
|
|
void CImgShowDlg::OnLButtonDown(UINT nFlags, CPoint point)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
CDialog::OnLButtonDown(nFlags, point);
|
|
|
|
|
|
if (m_SrcFrame == NULL) // 如果没有图像,不响应
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// Alt = 1 Ctrl = 5 Shift = 9
|
|
|
if (nFlags == MK_CONTROL) // 当按住ctrl键时,不响应 因为与选择目标时冲突
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// 更新鼠标坐标
|
|
|
m_LeftButtonDown = point;
|
|
|
|
|
|
// 鼠标是否在图像上
|
|
|
if(m_LeftButtonDown.x > m_ShowRegionOnScreen.left && m_LeftButtonDown.x < m_ShowRegionOnScreen.right &&
|
|
|
m_LeftButtonDown.y > m_ShowRegionOnScreen.top && m_LeftButtonDown.y < m_ShowRegionOnScreen.bottom)
|
|
|
{
|
|
|
m_bStaisfyRoamImg = TRUE;
|
|
|
|
|
|
// 计算一点的像素坐标
|
|
|
int ShowRegionWidth = m_ShowRegionOnScreen.Width() + 1;
|
|
|
int ShowRegionHeight = m_ShowRegionOnScreen.Height() + 1;
|
|
|
double ratioW = double(m_ShowRegion.Width() + 1) / ShowRegionWidth;
|
|
|
double ratioH = double(m_ShowRegion.Height() + 1) / ShowRegionHeight;
|
|
|
m_LButtonDownPixelCoordinate.x = static_cast<int>((point.x - m_ShowRegionOnScreen.left) * ratioW + 0.5 + m_ShowRegion.left);
|
|
|
m_LButtonDownPixelCoordinate.y = static_cast<int>((point.y - m_ShowRegionOnScreen.top) * ratioH + 0.5 + m_ShowRegion.top);
|
|
|
|
|
|
// 图像裁剪优先级高于目标扣取
|
|
|
if (m_bClipImgOn == true)
|
|
|
{
|
|
|
if (m_haveValidFirstPt == FALSE)
|
|
|
{
|
|
|
m_clipImgFirstPt = m_LButtonDownPixelCoordinate;
|
|
|
m_clipImgFirstPtScreen = point;
|
|
|
m_haveValidFirstPt = TRUE;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
m_clipImgSecondPt = m_LButtonDownPixelCoordinate;
|
|
|
m_haveValidFirstPt = FALSE;
|
|
|
|
|
|
// 弹出裁剪提示
|
|
|
int Left = min(m_clipImgFirstPt.x, m_clipImgSecondPt.x);
|
|
|
int Right = max(m_clipImgFirstPt.x, m_clipImgSecondPt.x);
|
|
|
int Top = min(m_clipImgFirstPt.y, m_clipImgSecondPt.y);
|
|
|
int Bottom = max(m_clipImgFirstPt.y, m_clipImgSecondPt.y);
|
|
|
|
|
|
if (Right > Left && Bottom > Top)
|
|
|
{
|
|
|
cv::Mat img(m_SrcFrame, false);
|
|
|
|
|
|
cv::Mat clipedImg;
|
|
|
img(cv::Range(Top, Bottom), cv::Range(Left, Right)).copyTo(clipedImg);
|
|
|
|
|
|
int ret = ::MessageBoxA(NULL, _T("确定裁剪图像?"),_T("操作提示"), MB_YESNO | MB_SYSTEMMODAL);
|
|
|
|
|
|
if (ret == IDNO)
|
|
|
{
|
|
|
Invalidate();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
m_bClipImgOn = false;
|
|
|
|
|
|
// 创建临时情报结构体
|
|
|
QBStru qbLocal;
|
|
|
qbLocal.image.bValid = true;
|
|
|
qbLocal.framePart.bValid = false;
|
|
|
|
|
|
qbLocal.image.srcImg.ImgWidth = clipedImg.cols;
|
|
|
qbLocal.image.srcImg.ImgHeight = clipedImg.rows;
|
|
|
qbLocal.image.srcImg.bitcount = clipedImg.channels() * 8;
|
|
|
|
|
|
// 步长:每行像素所占字节数
|
|
|
int lineByte = (clipedImg.cols * clipedImg.channels());
|
|
|
|
|
|
// 位图数据缓冲区的大小,即图像大小
|
|
|
int imgBufSize = clipedImg.rows * lineByte;
|
|
|
|
|
|
if (imgBufSize > 0)
|
|
|
{
|
|
|
qbLocal.image.srcImg.buff = new BYTE[imgBufSize];
|
|
|
if (qbLocal.image.srcImg.buff != nullptr)
|
|
|
{
|
|
|
// 复制实际字节数
|
|
|
memcpy(qbLocal.image.srcImg.buff, clipedImg.data, static_cast<size_t>(imgBufSize)); // 图像数据复制
|
|
|
|
|
|
if (m_boundbingBox.EastLon - m_boundbingBox.WestLon > 0
|
|
|
&& m_boundbingBox.WestLon >= -180
|
|
|
&& m_boundbingBox.WestLon <= 180
|
|
|
&& m_boundbingBox.EastLon >= -180
|
|
|
&& m_boundbingBox.EastLon <= 180
|
|
|
&& m_boundbingBox.NorthLat - m_boundbingBox.SouthLat > 0
|
|
|
&& m_boundbingBox.SouthLat >= -90
|
|
|
&& m_boundbingBox.SouthLat <= 90
|
|
|
&& m_boundbingBox.NorthLat >= -90
|
|
|
&& m_boundbingBox.NorthLat <= 90)
|
|
|
{
|
|
|
m_ImgRatioOnScreen = 0.9f;
|
|
|
|
|
|
// 设置经纬度盒子
|
|
|
GeoBoundingBox LLBox;
|
|
|
double lonResolution = (m_boundbingBox.EastLon - m_boundbingBox.WestLon) / img.cols;
|
|
|
double latResolution = (m_boundbingBox.NorthLat - m_boundbingBox.SouthLat) / img.rows;
|
|
|
|
|
|
LLBox.WestLon = m_boundbingBox.WestLon + Left * lonResolution;
|
|
|
LLBox.EastLon = m_boundbingBox.WestLon + Right * lonResolution;
|
|
|
|
|
|
LLBox.NorthLat = m_boundbingBox.NorthLat - Top * latResolution;
|
|
|
LLBox.SouthLat = m_boundbingBox.NorthLat - Bottom * latResolution;
|
|
|
|
|
|
qbLocal.image.srcImg.BoundingBox = LLBox;
|
|
|
|
|
|
DisposeQBData(&qbLocal);
|
|
|
SetBoundingBox(LLBox);
|
|
|
|
|
|
SAFE_DELETE_ARRAY(m_midImg.buff);
|
|
|
m_midImg.buff = NULL;
|
|
|
m_iLatest = 0;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if (qbLocal.framePart.bValid == true)
|
|
|
{
|
|
|
int ret = ::MessageBoxA(NULL, _T("提示:图像将丧失定位能力,是否继续?"),_T("操作提示"), MB_OKCANCEL);
|
|
|
|
|
|
if (ret == IDOK)
|
|
|
{
|
|
|
m_ImgRatioOnScreen = 0.9f;
|
|
|
DisposeQBData(&qbLocal);
|
|
|
|
|
|
SAFE_DELETE_ARRAY(m_midImg.buff);
|
|
|
m_midImg.buff = NULL;
|
|
|
m_iLatest = 0;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
Invalidate();
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
m_ImgRatioOnScreen = 0.9f;
|
|
|
DisposeQBData(&qbLocal);
|
|
|
|
|
|
SAFE_DELETE_ARRAY(m_midImg.buff);
|
|
|
m_midImg.buff = NULL;
|
|
|
m_iLatest = 0;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
delete [] qbLocal.image.srcImg.buff;
|
|
|
qbLocal.image.srcImg.buff = NULL;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
// 目标扣取
|
|
|
if (m_bGetTgtImgOn == true)
|
|
|
{
|
|
|
if (m_haveValidFirstPt == FALSE)
|
|
|
{
|
|
|
m_clipImgFirstPt = m_LButtonDownPixelCoordinate;
|
|
|
m_clipImgFirstPtScreen = point;
|
|
|
m_haveValidFirstPt = TRUE;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
m_clipImgSecondPt = m_LButtonDownPixelCoordinate;
|
|
|
m_haveValidFirstPt = FALSE;
|
|
|
|
|
|
// 弹出裁剪提示
|
|
|
int Left = min(m_clipImgFirstPt.x, m_clipImgSecondPt.x);
|
|
|
int Right = max(m_clipImgFirstPt.x, m_clipImgSecondPt.x);
|
|
|
int Top = min(m_clipImgFirstPt.y, m_clipImgSecondPt.y);
|
|
|
int Bottom = max(m_clipImgFirstPt.y, m_clipImgSecondPt.y);
|
|
|
|
|
|
if (Right > Left && Bottom > Top)
|
|
|
{
|
|
|
cv::Mat img(m_SrcFrame, false);
|
|
|
|
|
|
cv::Mat clipedImg;
|
|
|
img(cv::Range(Top, Bottom), cv::Range(Left, Right)).copyTo(clipedImg);
|
|
|
|
|
|
int ret = ::MessageBoxA(NULL, _T("确定抓取目标图像?"),_T("操作提示"), MB_YESNO | MB_SYSTEMMODAL);
|
|
|
|
|
|
if (ret == IDNO)
|
|
|
{
|
|
|
Invalidate();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
m_bGetTgtImgOn = false;
|
|
|
|
|
|
// 计算图像和复接数据存储路径
|
|
|
SYSTEMTIME CurrentTime;
|
|
|
GetLocalTime(&CurrentTime);
|
|
|
|
|
|
CString ImgSavePath;
|
|
|
ImgSavePath.Format( "%04d%02d%02d_%02d%02d%02d%04d.jpg",
|
|
|
CurrentTime.wYear,
|
|
|
CurrentTime.wMonth,
|
|
|
CurrentTime.wDay,
|
|
|
CurrentTime.wHour,
|
|
|
CurrentTime.wMinute,
|
|
|
CurrentTime.wSecond,
|
|
|
CurrentTime.wMilliseconds);
|
|
|
|
|
|
// 确保有文件夹,如果中途误删,会再次创建
|
|
|
CString tgtFolder = GetSoftwareCurrentDirectory() + "\\targets";
|
|
|
if (SearchDirectory(tgtFolder) == FALSE) // 没找到根文件夹
|
|
|
{
|
|
|
CreateDirectory(tgtFolder, NULL);
|
|
|
}
|
|
|
|
|
|
CString savePath = tgtFolder + "\\" + ImgSavePath;
|
|
|
cv::imwrite(savePath.GetBuffer(0) ,clipedImg);
|
|
|
|
|
|
if (m_lpSendFilePath != nullptr)
|
|
|
{
|
|
|
m_lpSendFilePath(savePath, 7);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
m_bStaisfyRoamImg = FALSE;
|
|
|
}
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.msg;
|
|
|
return;
|
|
|
}
|
|
|
catch(...)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 功能:向图像中添加 经纬高 位置信息
|
|
|
// 输入:
|
|
|
// 1: qb: 情报结构体
|
|
|
// 2: pt: 像素坐标
|
|
|
// 3. Lon: 经度
|
|
|
// 4. Lat: 纬度
|
|
|
// 5. H: 高度
|
|
|
// 返回值:无
|
|
|
void CImgShowDlg::TagLocationOnImgStru(ImgStru &imgData, cv::Point pt, double Lon, double Lat, double H)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
|
|
|
if (imgData.ImgWidth <= 0 || imgData.ImgHeight <= 0
|
|
|
|| (imgData.bitcount != 8 && imgData.bitcount != 24)
|
|
|
|| imgData.buff == NULL)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (pt.x < 0 || pt.y < 0)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (Lon < -180 || Lon > 180 || Lat < -90 || Lat > 90)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (imgData.ImgWidth > 0
|
|
|
&& imgData.ImgHeight > 0
|
|
|
&& (imgData.bitcount == 8 || imgData.bitcount == 24)
|
|
|
&& imgData.buff != NULL)
|
|
|
{
|
|
|
cv::Mat img;
|
|
|
unsigned int imgBufSize = 0;
|
|
|
if (imgData.bitcount == 8 && imgData.ImgHeight * imgData.ImgWidth > 0)
|
|
|
{
|
|
|
img = cv::Mat(imgData.ImgHeight, imgData.ImgWidth, CV_8UC1);
|
|
|
imgBufSize = static_cast<unsigned int>(imgData.ImgHeight * imgData.ImgWidth);
|
|
|
}
|
|
|
else
|
|
|
if (imgData.bitcount == 24 && imgData.ImgHeight * imgData.ImgWidth * 3 > 0)
|
|
|
{
|
|
|
img = cv::Mat(imgData.ImgHeight, imgData.ImgWidth, CV_8UC3);
|
|
|
imgBufSize = static_cast<unsigned int>(imgData.ImgHeight * imgData.ImgWidth * 3);
|
|
|
}
|
|
|
|
|
|
memcpy(img.data, imgData.buff, imgBufSize); // 图像数据复制
|
|
|
|
|
|
CString sLon;
|
|
|
CString sLat;
|
|
|
CString sH;
|
|
|
|
|
|
sLon.Format("%.6f", Lon);
|
|
|
sLat.Format("%.6f", Lat);
|
|
|
sH.Format("%.1f", H);
|
|
|
|
|
|
sLon = "Lon:" + sLon;
|
|
|
sLat = "Lat:" + sLat;
|
|
|
sH = "H:" + sH;
|
|
|
|
|
|
|
|
|
cv::Scalar color(0, 255, 255);
|
|
|
|
|
|
cv::circle(img, pt, 2, color, 2);
|
|
|
if (pt.x > (img.cols - 100))
|
|
|
{
|
|
|
cv::putText(img, sLon.GetBuffer(0), cv::Point(pt.x + 5 - 100, pt.y + 4 + 15), 1, 1, color);
|
|
|
cv::putText(img, sLat.GetBuffer(0), cv::Point(pt.x + 5 - 100, pt.y + 4 + 15 + 15), 1, 1, color);
|
|
|
cv::putText(img, sH.GetBuffer(0), cv::Point(pt.x + 5 - 100, pt.y + 4 + 30 + 15), 1, 1, color);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
cv::putText(img, sLon.GetBuffer(0), cv::Point(pt.x + 5, pt.y + 4), 1, 1, color);
|
|
|
cv::putText(img, sLat.GetBuffer(0), cv::Point(pt.x + 5, pt.y + 4 + 15), 1, 1, color);
|
|
|
cv::putText(img, sH.GetBuffer(0), cv::Point(pt.x + 5, pt.y + 4 + 30), 1, 1, color);
|
|
|
}
|
|
|
|
|
|
memcpy(imgData.buff, img.data, imgBufSize);
|
|
|
}
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.msg;
|
|
|
return;
|
|
|
}
|
|
|
catch(...)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 向图像中写信息
|
|
|
void CImgShowDlg::TagLocationOnQBData(QBStru &qb, cv::Point pt, double Lon, double Lat, double H)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
if (qb.image.bValid == true)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (pt.x < 0 || pt.y < 0)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (Lon < -180 || Lon > 180 || Lat < -90 || Lat > 90)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// srcImg
|
|
|
TagLocationOnImgStru(qb.image.srcImg, pt, Lon, Lat, H);
|
|
|
|
|
|
// dstImg
|
|
|
TagLocationOnImgStru(qb.image.dstImg, pt, Lon, Lat, H);
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.msg;
|
|
|
return;
|
|
|
}
|
|
|
catch(...)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
// 功能:向图像中添加 经纬高 位置信息
|
|
|
// 输入:
|
|
|
// 1: img: 情报结构体
|
|
|
// 2: pt: 像素坐标
|
|
|
// 3. Lon: 经度
|
|
|
// 4. Lat: 纬度
|
|
|
// 5. H: 高度
|
|
|
// 返回值:无
|
|
|
void CImgShowDlg::TagLocationOnMatImg(cv::Mat &img, cv::Point pt, double Lon, double Lat, double H)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
if (img.empty() == true || img.cols <= 0 || img.rows <= 0)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (pt.x < 0 || pt.y < 0)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (Lon < -180 || Lon > 180 || Lat < -90 || Lat > 90)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
CString sLon;
|
|
|
CString sLat;
|
|
|
CString sH;
|
|
|
|
|
|
sLon.Format("%.6f", Lon);
|
|
|
sLat.Format("%.6f", Lat);
|
|
|
sH.Format("%.1f", H);
|
|
|
|
|
|
sLon = "Lon:" + sLon;
|
|
|
sLat = "Lat:" + sLat;
|
|
|
sH = "H:" + sH;
|
|
|
|
|
|
cv::Scalar color(0, 255, 255);
|
|
|
|
|
|
cv::circle(img, pt, 3, color, 2);
|
|
|
|
|
|
if (pt.x > (img.cols - 100))
|
|
|
{
|
|
|
cv::putText(img, sLon.GetBuffer(0), cv::Point(pt.x + 5 - 100, pt.y + 4 + 15), 1, 1, color);
|
|
|
cv::putText(img, sLat.GetBuffer(0), cv::Point(pt.x + 5 - 100, pt.y + 4 + 15 + 15), 1, 1, color);
|
|
|
cv::putText(img, sH.GetBuffer(0), cv::Point(pt.x + 5 - 100, pt.y + 4 + 30 + 15), 1, 1, color);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
cv::putText(img, sLon.GetBuffer(0), cv::Point(pt.x + 5, pt.y + 4), 1, 1, color);
|
|
|
cv::putText(img, sLat.GetBuffer(0), cv::Point(pt.x + 5, pt.y + 4 + 15), 1, 1, color);
|
|
|
cv::putText(img, sH.GetBuffer(0), cv::Point(pt.x + 5, pt.y + 4 + 30), 1, 1, color);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.msg;
|
|
|
return;
|
|
|
}
|
|
|
catch(...)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 功能:向图像中添加 文字 信息
|
|
|
// 输入:
|
|
|
// 1: imgData: 图像结构体
|
|
|
// 2: pt: 像素坐标
|
|
|
// 3. text: 文字信息
|
|
|
// 返回值:无
|
|
|
void CImgShowDlg::TagTextOnImgStru(ImgStru &imgData, cv::Point pt, CString text)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
if (imgData.ImgWidth <= 0 || imgData.ImgHeight <= 0
|
|
|
|| (imgData.bitcount != 8 && imgData.bitcount != 24)
|
|
|
|| imgData.buff == NULL)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (text == "")
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (pt.x < 0 || pt.y < 0)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (imgData.ImgWidth > 0
|
|
|
&& imgData.ImgHeight > 0
|
|
|
&& (imgData.bitcount == 8 || imgData.bitcount == 24)
|
|
|
&& imgData.buff != NULL)
|
|
|
{
|
|
|
cv::Mat img;
|
|
|
unsigned int imgBufSize = 0;
|
|
|
if (imgData.bitcount == 8)
|
|
|
{
|
|
|
img = cv::Mat(imgData.ImgHeight, imgData.ImgWidth, CV_8UC1);
|
|
|
imgBufSize = static_cast<unsigned int>(imgData.ImgHeight * imgData.ImgWidth);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
img = cv::Mat(imgData.ImgHeight, imgData.ImgWidth, CV_8UC3);
|
|
|
imgBufSize = static_cast<unsigned int>(imgData.ImgHeight * imgData.ImgWidth * 3);
|
|
|
}
|
|
|
|
|
|
memcpy(img.data, imgData.buff, imgBufSize); // 图像数据复制
|
|
|
|
|
|
cv::Scalar color(0, 255, 255);
|
|
|
cv::putText(img, text.GetBuffer(0), cv::Point(pt.x + 5, pt.y - 5), 1, 1, color);
|
|
|
|
|
|
memcpy(imgData.buff, img.data, imgBufSize);
|
|
|
}
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.msg;
|
|
|
return;
|
|
|
}
|
|
|
catch(...)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 功能:向图像中添加 文字 信息
|
|
|
// 输入:
|
|
|
// 1: qb: 情报结构体
|
|
|
// 2: pt: 像素坐标
|
|
|
// 3. text: 文字信息
|
|
|
// 返回值:无
|
|
|
void CImgShowDlg::TagTextOnQBData(QBStru &qb, cv::Point pt, CString text)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
if (qb.image.bValid == 0 || text == "")
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (pt.x < 0 || pt.y < 0)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// srcImg
|
|
|
TagTextOnImgStru(qb.image.srcImg, pt, text);
|
|
|
|
|
|
// dstImg
|
|
|
TagTextOnImgStru(qb.image.dstImg, pt, text);
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.msg;
|
|
|
return;
|
|
|
}
|
|
|
catch(...)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 功能:向图像中添加 文字 信息
|
|
|
// 输入:
|
|
|
// 1: img: 情报结构体
|
|
|
// 2: pt: 像素坐标
|
|
|
// 3. text: 文字信息
|
|
|
// 返回值:无
|
|
|
void CImgShowDlg::TagTextOnMatImg(cv::Mat &img, cv::Point pt, CString text)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
if (img.empty() == true || text == "" || img.cols <= 0 || img.rows <= 0)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (pt.x < 0 || pt.y < 0)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
cv::Scalar color(0, 255, 255);
|
|
|
cv::putText(img, text.GetBuffer(0), cv::Point(pt.x + 5, pt.y - 5), 1, 1, color);
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.msg;
|
|
|
return;
|
|
|
}
|
|
|
catch(...)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void CImgShowDlg::TagInfoReviseShotOnMatImg(cv::Mat &img, cv::Point pt1, cv::Point pt2, double *LLA1, double *LLA2)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
if (img.empty() == true || img.cols <= 0 || img.rows <= 0)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (pt1.x < 0 || pt1.x > img.cols - 1
|
|
|
|| pt1.y < 0 || pt1.y > img.rows - 1)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (pt2.x < 0 || pt2.x > img.cols - 1
|
|
|
|| pt2.y < 0 || pt2.y > img.rows - 1)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (LLA1[0] < -180 || LLA1[0] > 180 || LLA1[1] < -90 || LLA1[1] > 90)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (LLA2[0] < -180 || LLA2[0] > 180 || LLA2[1] < -90 || LLA2[1] > 90)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// 计算距离和方位
|
|
|
|
|
|
// 计算角度
|
|
|
double distance = 0.0; // 距离
|
|
|
double azAngle = 0.0; // 方位
|
|
|
|
|
|
// 计算两点间的距离和方位(顺时针:0 - 360)
|
|
|
CalculateTwoPtsDistanceAzimuth(distance, azAngle, LLA1[0], LLA1[1], LLA2[0], LLA2[1], 3);
|
|
|
|
|
|
// 计算 pt1 和 pt2 在图像中的夹角
|
|
|
const int R = 30;
|
|
|
|
|
|
double theta = 0;
|
|
|
|
|
|
if (pt1.x == pt2.x && pt1.y > pt2.y)
|
|
|
{
|
|
|
theta = 0;
|
|
|
}
|
|
|
else if (pt1.x < pt2.x && pt1.y > pt2.y)
|
|
|
{
|
|
|
theta = atan2(double(pt2.x - pt1.x), double(pt1.y - pt2.y)) * 180 / 3.1415926;
|
|
|
}
|
|
|
else if (pt1.x < pt2.x && pt1.y == pt2.y)
|
|
|
{
|
|
|
theta = 90;
|
|
|
}
|
|
|
else if (pt1.x < pt2.x && pt1.y < pt2.y)
|
|
|
{
|
|
|
theta = atan2(double(pt2.y - pt1.y), double(pt2.x - pt1.x)) * 180 / 3.1415926 + 90;
|
|
|
}
|
|
|
else if (pt1.x == pt2.x && pt1.y < pt2.y)
|
|
|
{
|
|
|
theta = 180;
|
|
|
}
|
|
|
else if (pt1.x > pt2.x && pt1.y < pt2.y)
|
|
|
{
|
|
|
theta = atan2(double(pt1.x - pt2.x), double(pt2.y - pt1.y)) * 180 / 3.1415926 + 180;
|
|
|
}
|
|
|
else if (pt1.x > pt2.x && pt1.y == pt2.y)
|
|
|
{
|
|
|
theta = 270;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
theta = atan2(double(pt1.y - pt2.y), double(pt1.x - pt2.x)) * 180 / 3.1415926 + 270;
|
|
|
}
|
|
|
|
|
|
// 计算
|
|
|
|
|
|
cv::Scalar color = cv::Scalar(0,0, 255);
|
|
|
|
|
|
cv::Point pt3;
|
|
|
cv::Point pt4;
|
|
|
|
|
|
pt3.x = pt2.x - static_cast<int>(R * cos((90 - theta - 30) * 3.1415926 / 180));
|
|
|
pt3.y = pt2.y + static_cast<int>(R * sin((90 - theta - 30) * 3.1415926 / 180));
|
|
|
|
|
|
pt4.x = pt2.x - static_cast<int>(R * cos((90 - theta + 30) * 3.1415926 / 180));
|
|
|
pt4.y = pt2.y + static_cast<int>(R * sin((90 - theta + 30) * 3.1415926 / 180));
|
|
|
|
|
|
cv::line(img, pt1, pt2, color, 1, 16);
|
|
|
cv::line(img, pt2, pt3, color, 1, 16);
|
|
|
cv::line(img, pt2, pt4, color, 1, 16);
|
|
|
|
|
|
CString sDistance;
|
|
|
CString sAngle;
|
|
|
|
|
|
if (distance > 1000)
|
|
|
{
|
|
|
sDistance.Format("%.3fkm", distance / 1000);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
sDistance.Format("%.1fm", distance);
|
|
|
}
|
|
|
|
|
|
sAngle.Format("%.1fd", azAngle);
|
|
|
|
|
|
color = cv::Scalar(255, 0, 0);
|
|
|
cv::putText(img, sDistance.GetBuffer(0), cv::Point(pt2.x + 5, pt2.y + 4), 1, 1, color);
|
|
|
cv::putText(img, sAngle.GetBuffer(0), cv::Point(pt2.x + 5, pt2.y + 4 + 15), 1, 1, color);
|
|
|
|
|
|
// 写字:“目标”
|
|
|
color = cv::Scalar(0,0, 255);
|
|
|
cv::putText(img, "T", cv::Point(pt1.x, pt1.y), 1, 2, color, 2);
|
|
|
|
|
|
|
|
|
// 火炮校射信息回调输出
|
|
|
if (m_lpSendArtilleryReviseInfo != NULL)
|
|
|
{
|
|
|
m_lpSendArtilleryReviseInfo(float(distance), float(azAngle));
|
|
|
}
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.msg;
|
|
|
return;
|
|
|
}
|
|
|
catch(...)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
void CImgShowDlg::TagInfoReviseShotOnImgStru(ImgStru &imgData, cv::Point pt1, cv::Point pt2, double *LLA1, double *LLA2)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
if (imgData.ImgWidth <= 0 || imgData.ImgHeight <= 0
|
|
|
|| (imgData.bitcount != 8 && imgData.bitcount != 24)
|
|
|
|| imgData.buff == NULL)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (pt1.x < 0 || pt1.x > imgData.ImgWidth - 1
|
|
|
|| pt1.y < 0 || pt1.y > imgData.ImgHeight - 1)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (pt2.x < 0 || pt2.x > imgData.ImgWidth - 1
|
|
|
|| pt2.y < 0 || pt2.y > imgData.ImgHeight - 1)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (LLA1[0] < -180 || LLA1[0] > 180 || LLA1[1] < -90 || LLA1[1] > 90)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (LLA2[0] < -180 || LLA2[0] > 180 || LLA2[1] < -90 || LLA2[1] > 90)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (imgData.ImgWidth > 0
|
|
|
&& imgData.ImgHeight > 0
|
|
|
&& (imgData.bitcount == 8 || imgData.bitcount == 24)
|
|
|
&& imgData.buff != NULL)
|
|
|
{
|
|
|
cv::Mat img;
|
|
|
unsigned int imgBufSize = 0;
|
|
|
if (imgData.bitcount == 8)
|
|
|
{
|
|
|
img = cv::Mat(imgData.ImgHeight, imgData.ImgWidth, CV_8UC1);
|
|
|
imgBufSize = static_cast<unsigned int>(imgData.ImgHeight * imgData.ImgWidth);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
img = cv::Mat(imgData.ImgHeight, imgData.ImgWidth, CV_8UC3);
|
|
|
imgBufSize = static_cast<unsigned int>(imgData.ImgHeight * imgData.ImgWidth * 3);
|
|
|
}
|
|
|
|
|
|
memcpy(img.data, imgData.buff, imgBufSize); // 图像数据复制
|
|
|
|
|
|
TagInfoReviseShotOnMatImg(img, pt1, pt2, LLA1, LLA2);
|
|
|
|
|
|
memcpy(imgData.buff, img.data, imgBufSize);
|
|
|
}
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.msg;
|
|
|
return;
|
|
|
}
|
|
|
catch(...)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
void CImgShowDlg::TagInfoReviseShotOnQBData(QBStru &qb, cv::Point pt1, cv::Point pt2, double *LLA1, double *LLA2)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
if (qb.image.bValid == 0)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// srcImg
|
|
|
TagInfoReviseShotOnImgStru(qb.image.srcImg, pt1, pt2, LLA1, LLA2);
|
|
|
|
|
|
// dstImg
|
|
|
TagInfoReviseShotOnImgStru(qb.image.dstImg, pt1, pt2, LLA1, LLA2);
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.msg;
|
|
|
return;
|
|
|
}
|
|
|
catch(...)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 左键双击消息响应
|
|
|
void CImgShowDlg::OnLButtonDblClk(UINT nFlags, CPoint point)
|
|
|
{
|
|
|
if (m_bFirstSignal == TRUE || m_bSecondSignal == TRUE)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
try
|
|
|
{
|
|
|
CDialog::OnLButtonDblClk(nFlags, point);
|
|
|
|
|
|
// 要求按住Ctrl键
|
|
|
if ((m_SrcFrame != NULL)/* && (nFlags == MK_CONTROL + 1)*/) // SrcFrame 按住ctrl时,nFlags = 9
|
|
|
{
|
|
|
// 计算 CPoint point 对应的像素坐标 CPoint LButtonDblClkPixelCoordinate;
|
|
|
if ((point.x > m_ShowRegionOnScreen.left) && (point.x < m_ShowRegionOnScreen.right) &&
|
|
|
(point.y > m_ShowRegionOnScreen.top) && (point.y < m_ShowRegionOnScreen.bottom)) // 鼠标在图像上
|
|
|
{
|
|
|
// 计算一点的像素坐标
|
|
|
int ShowRegionWidth = m_ShowRegionOnScreen.Width() + 1;
|
|
|
int ShowRegionHeight = m_ShowRegionOnScreen.Height() + 1;
|
|
|
double ratioW = double(m_ShowRegion.Width() + 1) / ShowRegionWidth;
|
|
|
double ratioH = double(m_ShowRegion.Height() + 1) / ShowRegionHeight;
|
|
|
m_LButtonDblClkPixelCoordinate.x = static_cast<int>((point.x - m_ShowRegionOnScreen.left) * ratioW + 0.5 + m_ShowRegion.left);
|
|
|
m_LButtonDblClkPixelCoordinate.y = static_cast<int>((point.y - m_ShowRegionOnScreen.top) * ratioH + 0.5 + m_ShowRegion.top);
|
|
|
|
|
|
// 地图匹配定位时,在图像中标绘目标
|
|
|
if (m_lpSendTgrLocLeadLonLat != NULL && m_bDrawSquareOnImg == TRUE)
|
|
|
{
|
|
|
cv::Mat DrawTargetImg(m_SrcFrame, false);
|
|
|
|
|
|
cv::Scalar color;
|
|
|
cv::Mat Mask = Mat::zeros(DrawTargetImg.size(), CV_8U);
|
|
|
|
|
|
if (DrawTargetImg.type() == 0)
|
|
|
{
|
|
|
color = cv::Scalar(255);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
color = cv::Scalar(0, 0, 255);
|
|
|
}
|
|
|
|
|
|
// 清理上次矩形标绘
|
|
|
cv::Point leftUp = m_TargetCenter + cv::Point(-25, -25);
|
|
|
cv::Point rightUp = m_TargetCenter + cv::Point(+25, -25);
|
|
|
cv::Point rightDown = m_TargetCenter + cv::Point(+25, +25);
|
|
|
cv::Point leftDown = m_TargetCenter + cv::Point(-25, +25);
|
|
|
|
|
|
try
|
|
|
{
|
|
|
cv::line(Mask, leftUp, rightUp, cv::Scalar(255), 1, 16);
|
|
|
cv::line(Mask, leftUp, leftDown, cv::Scalar(255), 1, 16);
|
|
|
cv::line(Mask, leftDown, rightDown, cv::Scalar(255), 1, 16);
|
|
|
cv::line(Mask, rightUp, rightDown, cv::Scalar(255), 1, 16);
|
|
|
|
|
|
cv::inpaint(DrawTargetImg, Mask, DrawTargetImg, 3, CV_INPAINT_TELEA);
|
|
|
}
|
|
|
catch (cv::Exception &e)
|
|
|
{
|
|
|
// 继续执行 即使修补失败,也能输出单点定位结果
|
|
|
e;
|
|
|
}
|
|
|
|
|
|
|
|
|
// 确定矩形四个点
|
|
|
cv::Point center = cv::Point(m_LButtonDblClkPixelCoordinate.x, m_LButtonDblClkPixelCoordinate.y);
|
|
|
|
|
|
leftUp = center + cv::Point(-25, -25);
|
|
|
rightUp = center + cv::Point(+25, -25);
|
|
|
rightDown = center + cv::Point(+25, +25);
|
|
|
leftDown = center + cv::Point(-25, +25);
|
|
|
|
|
|
cv::line(DrawTargetImg, leftUp, rightUp, color, 1, 16);
|
|
|
cv::line(DrawTargetImg, leftUp, leftDown, color, 1, 16);
|
|
|
cv::line(DrawTargetImg, leftDown, rightDown, color, 1, 16);
|
|
|
cv::line(DrawTargetImg, rightUp, rightDown, color, 1, 16);
|
|
|
|
|
|
// 上一次无效时,本次重绘
|
|
|
if (m_TargetCenter.x = -100 && m_TargetCenter.y == -100)
|
|
|
{
|
|
|
OnPaint();
|
|
|
}
|
|
|
|
|
|
// 更新记忆
|
|
|
m_TargetCenter = center;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
m_bDrawSquareOnImg = FALSE;
|
|
|
m_TargetCenter = cv::Point(-100, -100);
|
|
|
}
|
|
|
|
|
|
// 绘制标框
|
|
|
// 设计技巧:利用m_bPlotRectOnPaint,避免在OnPaint中重绘一次
|
|
|
m_bPlotRectOnPaint = FALSE;
|
|
|
|
|
|
DrawSquareOnScreen(point, TRUE);
|
|
|
|
|
|
m_bPlotRectOnPaint = TRUE;
|
|
|
|
|
|
|
|
|
// 函数回调 对外输出目标坐标
|
|
|
if (m_lpSendCoordinate != NULL) // 函数指针有效性判断
|
|
|
{
|
|
|
m_lpSendCoordinate(m_LButtonDblClkPixelCoordinate);
|
|
|
}
|
|
|
|
|
|
// 对外输出像素信息:王家星 20150721 原因:解决多次双击时的像素信息输出问题
|
|
|
|
|
|
//新增功能:计算当前图像 像素坐标 经纬度坐标 RGB值 回调输出
|
|
|
// 计算 CPoint point 对应的像素坐标 CPoint LButtonDblClkPixelCoordinate;
|
|
|
if ((point.x > m_ShowRegionOnScreen.left) && (point.x < m_ShowRegionOnScreen.right) &&
|
|
|
(point.y > m_ShowRegionOnScreen.top) && (point.y < m_ShowRegionOnScreen.bottom)) // 鼠标在图像上
|
|
|
{
|
|
|
// 图像尺寸与显示区域尺寸之间的比例
|
|
|
double ratio = 1.0;
|
|
|
|
|
|
// 分母0值判断
|
|
|
if (m_ShowRegionOnScreen.Width() > 0)
|
|
|
{
|
|
|
ratio = (m_ShowRegion.Width() * 1.0) / m_ShowRegionOnScreen.Width();
|
|
|
}
|
|
|
|
|
|
// 像素坐标
|
|
|
m_imgPixel_XY_Coordinate.x = static_cast<LONG>((point.x - m_ShowRegionOnScreen.left) * ratio) + m_ShowRegion.left;
|
|
|
m_imgPixel_XY_Coordinate.y = static_cast<LONG>((point.y - m_ShowRegionOnScreen.top) * ratio) + m_ShowRegion.top;
|
|
|
|
|
|
// 经纬度坐标
|
|
|
double Lon = 0.0;
|
|
|
double Lat = 0.0;
|
|
|
double H = 0;
|
|
|
if (true == DoCalAnyPtCoordinate(Lon, Lat, H, &m_LatestQBData.framePart, m_imgPixel_XY_Coordinate.x, m_imgPixel_XY_Coordinate.y))
|
|
|
{
|
|
|
m_imgPixel_LBH_Coordinate.x = Lon + m_deltaLon;
|
|
|
m_imgPixel_LBH_Coordinate.y = Lat + m_deltaLat;
|
|
|
|
|
|
CString DEMpath = GetSoftwareCurrentDirectory() + "\\ElevationData";
|
|
|
float fDem = 0;
|
|
|
GetElevation(fDem, m_imgPixel_LBH_Coordinate.x, m_imgPixel_LBH_Coordinate.y, DEMpath.GetBuffer(0));
|
|
|
m_imgPixel_LBH_Coordinate.z = fDem;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if (m_boundbingBox.EastLon - m_boundbingBox.WestLon > 0
|
|
|
&& m_boundbingBox.WestLon >= -180
|
|
|
&& m_boundbingBox.WestLon <= 180
|
|
|
&& m_boundbingBox.EastLon >= -180
|
|
|
&& m_boundbingBox.EastLon <= 180
|
|
|
&& m_boundbingBox.NorthLat - m_boundbingBox.SouthLat > 0
|
|
|
&& m_boundbingBox.SouthLat >= -90
|
|
|
&& m_boundbingBox.SouthLat <= 90
|
|
|
&& m_boundbingBox.NorthLat >= -90
|
|
|
&& m_boundbingBox.NorthLat <= 90)
|
|
|
{
|
|
|
double LonResolution = (m_boundbingBox.EastLon - m_boundbingBox.WestLon) / m_SrcFrame->width;
|
|
|
double LatResolution = (m_boundbingBox.NorthLat - m_boundbingBox.SouthLat) / m_SrcFrame->height;
|
|
|
|
|
|
m_imgPixel_LBH_Coordinate.x = (m_boundbingBox.WestLon + m_imgPixel_XY_Coordinate.x * LonResolution);
|
|
|
m_imgPixel_LBH_Coordinate.y = (m_boundbingBox.NorthLat - m_imgPixel_XY_Coordinate.y * LatResolution);
|
|
|
|
|
|
// 修正
|
|
|
m_imgPixel_LBH_Coordinate.x += (m_deltaLon);
|
|
|
m_imgPixel_LBH_Coordinate.y += (m_deltaLat);
|
|
|
|
|
|
CString DEMpath = GetSoftwareCurrentDirectory() + "\\ElevationData";
|
|
|
|
|
|
float fDem = 0;
|
|
|
GetElevation(fDem, m_imgPixel_LBH_Coordinate.x, m_imgPixel_LBH_Coordinate.y, DEMpath.GetBuffer(0));
|
|
|
m_imgPixel_LBH_Coordinate.z = fDem;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
m_imgPixel_LBH_Coordinate.x = -200.0;
|
|
|
m_imgPixel_LBH_Coordinate.y = -200.0;
|
|
|
m_imgPixel_LBH_Coordinate.z = -200.0;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
// 设置为 小于0 的无效值
|
|
|
m_imgPixel_XY_Coordinate.x = -1;
|
|
|
m_imgPixel_XY_Coordinate.y = -1;
|
|
|
m_imgPixel_LBH_Coordinate.x = -200.0;
|
|
|
m_imgPixel_LBH_Coordinate.y = -200.0;
|
|
|
m_imgPixel_LBH_Coordinate.z = -200.0;
|
|
|
}
|
|
|
|
|
|
// 定位标记
|
|
|
if (m_iImgEditType == 0)
|
|
|
{
|
|
|
m_bHaveOnPt = false; // 清零
|
|
|
|
|
|
m_bEnhanceEdit = true; // 增强
|
|
|
}
|
|
|
else if (m_iImgEditType == 1) // 定位标记
|
|
|
{
|
|
|
m_bEnhanceEdit = false; // 编辑
|
|
|
|
|
|
// 未作任何处理
|
|
|
if (m_LatestQBData.image.dstImg.buff == NULL/* && m_midImg.buff == NULL*/)
|
|
|
{
|
|
|
CloneImgStru(m_LatestQBData.image.srcImg, m_LatestQBData.image.dstImg);
|
|
|
CloneImgStru(m_LatestQBData.image.srcImg, m_midImg);
|
|
|
|
|
|
TagLocationOnImgStru(m_LatestQBData.image.dstImg, cv::Point(m_imgPixel_XY_Coordinate.x, m_imgPixel_XY_Coordinate.y),
|
|
|
m_imgPixel_LBH_Coordinate.x,
|
|
|
m_imgPixel_LBH_Coordinate.y,
|
|
|
m_imgPixel_LBH_Coordinate.z);
|
|
|
|
|
|
// 标记 m_SrcFrame
|
|
|
cv::Mat srcFrameMat(m_SrcFrame, false);
|
|
|
|
|
|
if (srcFrameMat.type() == CV_8UC1
|
|
|
&& srcFrameMat.data != NULL
|
|
|
&& m_LatestQBData.image.dstImg.buff != NULL
|
|
|
&& srcFrameMat.cols > 0 && srcFrameMat.rows > 0
|
|
|
&& srcFrameMat.cols * srcFrameMat.rows < 1e8)
|
|
|
{
|
|
|
memcpy(srcFrameMat.data, m_LatestQBData.image.dstImg.buff, srcFrameMat.cols * srcFrameMat.rows); // 图像数据复制
|
|
|
}
|
|
|
else
|
|
|
if (srcFrameMat.type() == CV_8UC3
|
|
|
&& srcFrameMat.data != NULL
|
|
|
&& m_LatestQBData.image.dstImg.buff != NULL
|
|
|
&& srcFrameMat.cols > 0 && srcFrameMat.rows > 0
|
|
|
&& srcFrameMat.cols * srcFrameMat.rows < 1e8)
|
|
|
{
|
|
|
memcpy(srcFrameMat.data, m_LatestQBData.image.dstImg.buff, srcFrameMat.cols * srcFrameMat.rows * 3); // 图像数据复制
|
|
|
}
|
|
|
|
|
|
Invalidate();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
CloneImgStru(m_LatestQBData.image.dstImg, m_midImg);
|
|
|
|
|
|
TagLocationOnImgStru(m_LatestQBData.image.dstImg, cv::Point(m_imgPixel_XY_Coordinate.x, m_imgPixel_XY_Coordinate.y),
|
|
|
m_imgPixel_LBH_Coordinate.x,
|
|
|
m_imgPixel_LBH_Coordinate.y,
|
|
|
m_imgPixel_LBH_Coordinate.z);
|
|
|
|
|
|
// 标记 m_SrcFrame
|
|
|
cv::Mat srcFrameMat(m_SrcFrame, false);
|
|
|
|
|
|
if (srcFrameMat.type() == CV_8UC1
|
|
|
&& srcFrameMat.data != NULL
|
|
|
&& m_LatestQBData.image.dstImg.buff != NULL
|
|
|
&& srcFrameMat.cols > 0 && srcFrameMat.rows > 0
|
|
|
&& srcFrameMat.cols * srcFrameMat.rows < 1e8)
|
|
|
{
|
|
|
memcpy(srcFrameMat.data, m_LatestQBData.image.dstImg.buff, srcFrameMat.cols * srcFrameMat.rows); // 图像数据复制
|
|
|
}
|
|
|
else
|
|
|
if (srcFrameMat.type() == CV_8UC3
|
|
|
&& srcFrameMat.data != NULL
|
|
|
&& m_LatestQBData.image.dstImg.buff != NULL
|
|
|
&& srcFrameMat.cols > 0 && srcFrameMat.rows > 0
|
|
|
&& srcFrameMat.cols * srcFrameMat.rows < 1e8)
|
|
|
{
|
|
|
memcpy(srcFrameMat.data, m_LatestQBData.image.dstImg.buff, srcFrameMat.cols * srcFrameMat.rows * 3); // 图像数据复制
|
|
|
}
|
|
|
|
|
|
Invalidate();
|
|
|
}
|
|
|
}
|
|
|
else if (m_iImgEditType == 2) // 文字标记
|
|
|
{
|
|
|
m_bEnhanceEdit = false; // 编辑
|
|
|
|
|
|
CAddTextDlg addTextDlg;
|
|
|
if (addTextDlg.DoModal() == IDOK)
|
|
|
{
|
|
|
CString inputText = addTextDlg.GetText();
|
|
|
|
|
|
// 未作任何处理
|
|
|
if (m_LatestQBData.image.dstImg.buff == NULL/* && m_midImg.buff == NULL*/)
|
|
|
{
|
|
|
CloneImgStru(m_LatestQBData.image.srcImg, m_LatestQBData.image.dstImg);
|
|
|
CloneImgStru(m_LatestQBData.image.srcImg, m_midImg);
|
|
|
|
|
|
TagTextOnImgStru(m_LatestQBData.image.dstImg, cv::Point(m_imgPixel_XY_Coordinate.x, m_imgPixel_XY_Coordinate.y), inputText);
|
|
|
|
|
|
// 标记 m_SrcFrame
|
|
|
cv::Mat srcFrameMat(m_SrcFrame, false);
|
|
|
|
|
|
if (srcFrameMat.type() == CV_8UC1
|
|
|
&& srcFrameMat.data != NULL
|
|
|
&& m_LatestQBData.image.dstImg.buff != NULL
|
|
|
&& srcFrameMat.cols > 0 && srcFrameMat.rows > 0
|
|
|
&& srcFrameMat.cols * srcFrameMat.rows < 1e8)
|
|
|
{
|
|
|
memcpy(srcFrameMat.data, m_LatestQBData.image.dstImg.buff, srcFrameMat.cols * srcFrameMat.rows); // 图像数据复制
|
|
|
}
|
|
|
else
|
|
|
if (srcFrameMat.type() == CV_8UC3
|
|
|
&& srcFrameMat.data != NULL
|
|
|
&& m_LatestQBData.image.dstImg.buff != NULL
|
|
|
&& srcFrameMat.cols > 0 && srcFrameMat.rows > 0
|
|
|
&& srcFrameMat.cols * srcFrameMat.rows < 1e8)
|
|
|
{
|
|
|
memcpy(srcFrameMat.data, m_LatestQBData.image.dstImg.buff, srcFrameMat.cols * srcFrameMat.rows * 3); // 图像数据复制
|
|
|
}
|
|
|
|
|
|
Invalidate();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
CloneImgStru(m_LatestQBData.image.dstImg, m_midImg);
|
|
|
|
|
|
TagTextOnImgStru(m_LatestQBData.image.dstImg, cv::Point(m_imgPixel_XY_Coordinate.x, m_imgPixel_XY_Coordinate.y), inputText);
|
|
|
|
|
|
// 标记 m_SrcFrame
|
|
|
cv::Mat srcFrameMat(m_SrcFrame, false);
|
|
|
|
|
|
if (srcFrameMat.type() == CV_8UC1
|
|
|
&& srcFrameMat.data != NULL
|
|
|
&& m_LatestQBData.image.dstImg.buff != NULL
|
|
|
&& srcFrameMat.cols > 0 && srcFrameMat.rows > 0
|
|
|
&& srcFrameMat.cols * srcFrameMat.rows < 1e8)
|
|
|
{
|
|
|
memcpy(srcFrameMat.data, m_LatestQBData.image.dstImg.buff, srcFrameMat.cols * srcFrameMat.rows); // 图像数据复制
|
|
|
}
|
|
|
else
|
|
|
if (srcFrameMat.type() == CV_8UC3
|
|
|
&& srcFrameMat.data != NULL
|
|
|
&& m_LatestQBData.image.dstImg.buff != NULL
|
|
|
&& srcFrameMat.cols > 0 && srcFrameMat.rows > 0
|
|
|
&& srcFrameMat.cols * srcFrameMat.rows < 1e8)
|
|
|
{
|
|
|
memcpy(srcFrameMat.data, m_LatestQBData.image.dstImg.buff, srcFrameMat.cols * srcFrameMat.rows * 3); // 图像数据复制
|
|
|
}
|
|
|
|
|
|
Invalidate();
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
else if (m_iImgEditType == 3) // 火炮校射标记
|
|
|
{
|
|
|
m_bEnhanceEdit = false; // 编辑
|
|
|
|
|
|
if (m_bHaveOnPt == false)
|
|
|
{
|
|
|
m_bHaveOnPt = true;
|
|
|
|
|
|
m_beginPixPt.x = m_LButtonDblClkPixelCoordinate.x;
|
|
|
m_beginPixPt.y = m_LButtonDblClkPixelCoordinate.y;
|
|
|
|
|
|
m_beginLLA[0] = m_imgPixel_LBH_Coordinate.x;
|
|
|
m_beginLLA[1] = m_imgPixel_LBH_Coordinate.y;
|
|
|
m_beginLLA[2] = m_imgPixel_LBH_Coordinate.z;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
m_bHaveOnPt = false;
|
|
|
m_endPixPt.x = m_LButtonDblClkPixelCoordinate.x;
|
|
|
m_endPixPt.y = m_LButtonDblClkPixelCoordinate.y;
|
|
|
|
|
|
m_endLLA[0] = m_imgPixel_LBH_Coordinate.x;
|
|
|
m_endLLA[1] = m_imgPixel_LBH_Coordinate.y;
|
|
|
m_endLLA[2] = m_imgPixel_LBH_Coordinate.z;
|
|
|
|
|
|
// 未作任何处理
|
|
|
if (m_LatestQBData.image.dstImg.buff == NULL/* && m_midImg.buff == NULL*/)
|
|
|
{
|
|
|
CloneImgStru(m_LatestQBData.image.srcImg, m_LatestQBData.image.dstImg);
|
|
|
CloneImgStru(m_LatestQBData.image.srcImg, m_midImg);
|
|
|
|
|
|
TagInfoReviseShotOnImgStru(m_LatestQBData.image.dstImg, m_beginPixPt, m_endPixPt, m_beginLLA, m_endLLA);
|
|
|
|
|
|
// 标记 m_SrcFrame
|
|
|
cv::Mat srcFrameMat(m_SrcFrame, false);
|
|
|
|
|
|
if (srcFrameMat.type() == CV_8UC1
|
|
|
&& srcFrameMat.data != NULL
|
|
|
&& m_LatestQBData.image.dstImg.buff != NULL
|
|
|
&& srcFrameMat.cols > 0 && srcFrameMat.rows > 0
|
|
|
&& srcFrameMat.cols * srcFrameMat.rows < 1e8)
|
|
|
{
|
|
|
memcpy(srcFrameMat.data, m_LatestQBData.image.dstImg.buff, srcFrameMat.cols * srcFrameMat.rows); // 图像数据复制
|
|
|
}
|
|
|
else
|
|
|
if (srcFrameMat.type() == CV_8UC3
|
|
|
&& srcFrameMat.data != NULL
|
|
|
&& m_LatestQBData.image.dstImg.buff != NULL
|
|
|
&& srcFrameMat.cols > 0 && srcFrameMat.rows > 0
|
|
|
&& srcFrameMat.cols * srcFrameMat.rows < 1e8)
|
|
|
{
|
|
|
memcpy(srcFrameMat.data, m_LatestQBData.image.dstImg.buff, srcFrameMat.cols * srcFrameMat.rows * 3); // 图像数据复制
|
|
|
}
|
|
|
|
|
|
Invalidate();
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
CloneImgStru(m_LatestQBData.image.dstImg, m_midImg);
|
|
|
TagInfoReviseShotOnImgStru(m_LatestQBData.image.dstImg, m_beginPixPt, m_endPixPt, m_beginLLA, m_endLLA);
|
|
|
|
|
|
// 标记 m_SrcFrame
|
|
|
cv::Mat srcFrameMat(m_SrcFrame, false);
|
|
|
|
|
|
if (srcFrameMat.type() == CV_8UC1
|
|
|
&& srcFrameMat.data != NULL
|
|
|
&& m_LatestQBData.image.dstImg.buff != NULL
|
|
|
&& srcFrameMat.cols > 0 && srcFrameMat.rows > 0
|
|
|
&& srcFrameMat.cols * srcFrameMat.rows < 1e8)
|
|
|
{
|
|
|
memcpy(srcFrameMat.data, m_LatestQBData.image.dstImg.buff, srcFrameMat.cols * srcFrameMat.rows); // 图像数据复制
|
|
|
}
|
|
|
else
|
|
|
if (srcFrameMat.type() == CV_8UC3
|
|
|
&& srcFrameMat.data != NULL
|
|
|
&& m_LatestQBData.image.dstImg.buff != NULL
|
|
|
&& srcFrameMat.cols > 0 && srcFrameMat.rows > 0
|
|
|
&& srcFrameMat.cols * srcFrameMat.rows < 1e8)
|
|
|
{
|
|
|
memcpy(srcFrameMat.data, m_LatestQBData.image.dstImg.buff, srcFrameMat.cols * srcFrameMat.rows * 3); // 图像数据复制
|
|
|
}
|
|
|
|
|
|
Invalidate();
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
m_bEnhanceEdit = true; // 增强
|
|
|
}
|
|
|
|
|
|
|
|
|
// 回调输出信息即可
|
|
|
if (m_lpSendPixInfoProc != NULL)
|
|
|
{
|
|
|
CPoint pt;
|
|
|
pt.x = m_imgPixel_XY_Coordinate.x;
|
|
|
pt.y = m_imgPixel_XY_Coordinate.y;
|
|
|
m_lpSendPixInfoProc(pt, m_imgPixel_LBH_Coordinate.x, m_imgPixel_LBH_Coordinate.y, m_imgPixel_LBH_Coordinate.z);
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
// 设置为 小于0 的无效值
|
|
|
m_LButtonDblClkPixelCoordinate.x = -1;
|
|
|
m_LButtonDblClkPixelCoordinate.y = -1;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.msg;
|
|
|
return;
|
|
|
}
|
|
|
catch(...)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 功能:获取当前图像中心的经纬度坐标
|
|
|
bool CImgShowDlg::GetCurrentImgCenterLonLat(double &lon, double &lat)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
if (m_SrcFrame == NULL)
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
// 经纬度坐标
|
|
|
double Lon = 0.0;
|
|
|
double Lat = 0.0;
|
|
|
double H = 0;
|
|
|
if (true == DoCalImgCenterCoordinate(Lon, Lat, H, &m_LatestQBData.framePart))
|
|
|
{
|
|
|
lon = Lon + m_deltaLon;
|
|
|
lat = Lat + m_deltaLat;
|
|
|
return true;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if (m_boundbingBox.EastLon - m_boundbingBox.WestLon > 0
|
|
|
&& m_boundbingBox.WestLon >= -180
|
|
|
&& m_boundbingBox.WestLon <= 180
|
|
|
&& m_boundbingBox.EastLon >= -180
|
|
|
&& m_boundbingBox.EastLon <= 180
|
|
|
&& m_boundbingBox.NorthLat - m_boundbingBox.SouthLat > 0
|
|
|
&& m_boundbingBox.SouthLat >= -90
|
|
|
&& m_boundbingBox.SouthLat <= 90
|
|
|
&& m_boundbingBox.NorthLat >= -90
|
|
|
&& m_boundbingBox.NorthLat <= 90)
|
|
|
{
|
|
|
lon = (m_boundbingBox.EastLon - m_boundbingBox.WestLon) / 2 + m_boundbingBox.WestLon;
|
|
|
lat = (m_boundbingBox.NorthLat - m_boundbingBox.SouthLat) / 2 + m_boundbingBox.SouthLat;
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return false;
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.msg;
|
|
|
return false;
|
|
|
}
|
|
|
catch(...)
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 鼠标移动消息响应
|
|
|
void CImgShowDlg::OnMouseMove(UINT nFlags, CPoint point)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
CDialog::OnMouseMove(nFlags, point);
|
|
|
|
|
|
if (nFlags == MK_LBUTTON) // 首要条件:左键按下
|
|
|
{
|
|
|
// 如果有外部信号输入 操作与视频模式相同
|
|
|
if (m_bFirstSignal == TRUE || m_bSecondSignal == TRUE)
|
|
|
{
|
|
|
if(m_bSatisfyMove == TRUE)
|
|
|
{
|
|
|
// 更新偏移量
|
|
|
m_ImgShowShift.x += (point.x - m_LeftButtonDown.x);
|
|
|
m_ImgShowShift.y += (point.y - m_LeftButtonDown.y);
|
|
|
|
|
|
// 更新鼠标左键按下点
|
|
|
m_LeftButtonDown = point;
|
|
|
}
|
|
|
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// 满足图像漫游条件
|
|
|
if(m_bStaisfyRoamImg == TRUE)
|
|
|
{
|
|
|
// 图像未全部显示
|
|
|
if (m_ShowRegion.Width() < m_SrcFrame->width - 1 || m_ShowRegion.Height() < m_SrcFrame->height - 1)
|
|
|
{
|
|
|
// 策略1:更新显示区域
|
|
|
int ShowRegionWidth = m_ShowRegionOnScreen.Width() + 1;
|
|
|
int ShowRegionHeight = m_ShowRegionOnScreen.Height() + 1;
|
|
|
double ratioW = double(m_ShowRegion.Width() + 1) / ShowRegionWidth;
|
|
|
double ratioH = double(m_ShowRegion.Height() + 1) / ShowRegionHeight;
|
|
|
|
|
|
// 像素坐标偏移量
|
|
|
int delatX = int((point.x - m_LeftButtonDown.x) * ratioW);
|
|
|
int delatY = int((point.y - m_LeftButtonDown.y) * ratioH);
|
|
|
|
|
|
m_LeftButtonDown = point;
|
|
|
|
|
|
// 计算显示区域
|
|
|
CRect new_ShowRegion = GetNewRegionWhenRoamImg(delatX, delatY);
|
|
|
|
|
|
|
|
|
// 如果有显示区域变动
|
|
|
if( new_ShowRegion.left - m_ShowRegion.left != 0 ||
|
|
|
new_ShowRegion.right - m_ShowRegion.right != 0 ||
|
|
|
new_ShowRegion.top - m_ShowRegion.top != 0 ||
|
|
|
new_ShowRegion.bottom - m_ShowRegion.bottom != 0)
|
|
|
{
|
|
|
// 更新显示区域
|
|
|
m_ShowRegion = new_ShowRegion;
|
|
|
|
|
|
// 图像显示拉伸比例控制
|
|
|
m_ImgRatioOnScreen = 1.0F;
|
|
|
|
|
|
// 显示图像
|
|
|
ShowOneImage(m_SrcFrame, TRUE, m_ShowRegion, m_ImgRatioOnScreen, m_ImgShowShift);
|
|
|
|
|
|
// 更新标绘窗口
|
|
|
DrawSquareOnScreen(GetScreenCoordinateBasedOnPixelCoordinate(m_LButtonDblClkPixelCoordinate),FALSE);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
// 策略2:图像已经全部显示
|
|
|
|
|
|
// 更新偏移量
|
|
|
m_ImgShowShift.x += (point.x - m_LeftButtonDown.x);
|
|
|
m_ImgShowShift.y += (point.y - m_LeftButtonDown.y);
|
|
|
|
|
|
// 更新鼠标左键按下点
|
|
|
m_LeftButtonDown = point;
|
|
|
|
|
|
// 显示图像
|
|
|
ShowWholeImage(m_SrcFrame, m_ImgRatioOnScreen, m_ImgShowShift);
|
|
|
|
|
|
// 更新标绘窗口
|
|
|
DrawSquareOnScreen(GetScreenCoordinateBasedOnPixelCoordinate(m_LButtonDblClkPixelCoordinate), FALSE);
|
|
|
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 已经有一个点了
|
|
|
if ((m_bGetTgtImgOn == true || m_bClipImgOn == true)&& m_haveValidFirstPt == TRUE)
|
|
|
{
|
|
|
// 计算 CPoint point 对应的像素坐标 CPoint LButtonDblClkPixelCoordinate;
|
|
|
if ((point.x > m_ShowRegionOnScreen.left) && (point.x < m_ShowRegionOnScreen.right) &&
|
|
|
(point.y > m_ShowRegionOnScreen.top) && (point.y < m_ShowRegionOnScreen.bottom)) // 鼠标在图像上
|
|
|
{
|
|
|
m_clipImgSecondPtScreen = point;
|
|
|
|
|
|
// 重新计算第一个点的屏幕坐标
|
|
|
m_clipImgFirstPtScreen = GetScreenCoordinateBasedOnPixelCoordinate(m_clipImgFirstPt);
|
|
|
|
|
|
CDC* pDC = this->GetDC();
|
|
|
CPen newPen1; // 创建新画笔
|
|
|
newPen1.CreatePen(PS_SOLID, 2, RGB(0, 255, 255));
|
|
|
|
|
|
// 显示区域的地理边界
|
|
|
CRect rect;
|
|
|
GetClientRect(&rect);
|
|
|
InvalidateRect(&rect, FALSE);
|
|
|
UpdateWindow();
|
|
|
|
|
|
CPen *pOldPen = pDC->SelectObject(&newPen1);
|
|
|
|
|
|
CPoint pts[4];
|
|
|
pts[0] = m_clipImgFirstPtScreen;
|
|
|
pts[1].x = m_clipImgSecondPtScreen.x;
|
|
|
pts[1].y = m_clipImgFirstPtScreen.y;
|
|
|
pts[2] = m_clipImgSecondPtScreen;
|
|
|
pts[3].x = m_clipImgFirstPtScreen.x;
|
|
|
pts[3].y = m_clipImgSecondPtScreen.y;
|
|
|
|
|
|
pDC->MoveTo(pts[0]);
|
|
|
pDC->LineTo(pts[1]);
|
|
|
pDC->LineTo(pts[2]);
|
|
|
pDC->LineTo(pts[3]);
|
|
|
pDC->LineTo(pts[0]);
|
|
|
|
|
|
// 释放设备上下文指针
|
|
|
ReleaseDC(pDC);
|
|
|
pDC = NULL;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//新增功能:计算当前图像 像素坐标 经纬度坐标 RGB值 回调输出
|
|
|
if (m_bFirstSignal == FALSE && m_bSecondSignal == FALSE && m_SrcFrame != NULL && m_bPlotRect == FALSE)
|
|
|
{
|
|
|
// 计算 CPoint point 对应的像素坐标 CPoint LButtonDblClkPixelCoordinate;
|
|
|
if ((point.x > m_ShowRegionOnScreen.left) && (point.x < m_ShowRegionOnScreen.right) &&
|
|
|
(point.y > m_ShowRegionOnScreen.top) && (point.y < m_ShowRegionOnScreen.bottom)) // 鼠标在图像上
|
|
|
{
|
|
|
int ShowRegionWidth = m_ShowRegionOnScreen.Width() + 1;
|
|
|
int ShowRegionHeight = m_ShowRegionOnScreen.Height() + 1;
|
|
|
double ratioW = double(m_ShowRegion.Width() + 1) / ShowRegionWidth;
|
|
|
double ratioH = double(m_ShowRegion.Height() + 1) / ShowRegionHeight;
|
|
|
m_imgPixel_XY_Coordinate.x = static_cast<int>((point.x - m_ShowRegionOnScreen.left) * ratioW + 0.5 + m_ShowRegion.left);
|
|
|
m_imgPixel_XY_Coordinate.y = static_cast<int>((point.y - m_ShowRegionOnScreen.top) * ratioH + 0.5 + m_ShowRegion.top);
|
|
|
|
|
|
// 经纬度坐标
|
|
|
double Lon = 0.0;
|
|
|
double Lat = 0.0;
|
|
|
double H = 0;
|
|
|
if (true == DoCalAnyPtCoordinate(Lon, Lat, H, &m_LatestQBData.framePart, m_imgPixel_XY_Coordinate.x, m_imgPixel_XY_Coordinate.y))
|
|
|
{
|
|
|
m_imgPixel_LBH_Coordinate.x = Lon + m_deltaLon;
|
|
|
m_imgPixel_LBH_Coordinate.y = Lat + m_deltaLat;
|
|
|
|
|
|
CString DEMpath = GetSoftwareCurrentDirectory() + "\\ElevationData";
|
|
|
|
|
|
float fDem = 0;
|
|
|
GetElevation(fDem, m_imgPixel_LBH_Coordinate.x, m_imgPixel_LBH_Coordinate.y, DEMpath.GetBuffer(0));
|
|
|
m_imgPixel_LBH_Coordinate.z = fDem;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if (m_boundbingBox.EastLon - m_boundbingBox.WestLon > 0
|
|
|
&& m_boundbingBox.WestLon >= -180
|
|
|
&& m_boundbingBox.WestLon <= 180
|
|
|
&& m_boundbingBox.EastLon >= -180
|
|
|
&& m_boundbingBox.EastLon <= 180
|
|
|
&& m_boundbingBox.NorthLat - m_boundbingBox.SouthLat > 0
|
|
|
&& m_boundbingBox.SouthLat >= -90
|
|
|
&& m_boundbingBox.SouthLat <= 90
|
|
|
&& m_boundbingBox.NorthLat >= -90
|
|
|
&& m_boundbingBox.NorthLat <= 90)
|
|
|
{
|
|
|
double LonResolution = (m_boundbingBox.EastLon - m_boundbingBox.WestLon) / m_SrcFrame->width;
|
|
|
double LatResolution = (m_boundbingBox.NorthLat - m_boundbingBox.SouthLat) / m_SrcFrame->height;
|
|
|
|
|
|
m_imgPixel_LBH_Coordinate.x = (m_boundbingBox.WestLon + m_imgPixel_XY_Coordinate.x * LonResolution);
|
|
|
m_imgPixel_LBH_Coordinate.y = (m_boundbingBox.NorthLat - m_imgPixel_XY_Coordinate.y * LatResolution);
|
|
|
|
|
|
// 修正
|
|
|
m_imgPixel_LBH_Coordinate.x += (m_deltaLon);
|
|
|
m_imgPixel_LBH_Coordinate.y += (m_deltaLat);
|
|
|
|
|
|
CString DEMpath = GetSoftwareCurrentDirectory() + "\\ElevationData";
|
|
|
|
|
|
float fDem = 0;
|
|
|
GetElevation(fDem, m_imgPixel_LBH_Coordinate.x, m_imgPixel_LBH_Coordinate.y, DEMpath.GetBuffer(0));
|
|
|
m_imgPixel_LBH_Coordinate.z = fDem;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
m_imgPixel_LBH_Coordinate.x = -200.0;
|
|
|
m_imgPixel_LBH_Coordinate.y = -200.0;
|
|
|
m_imgPixel_LBH_Coordinate.z = -200.0;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
// 设置为 小于0 的无效值
|
|
|
m_imgPixel_XY_Coordinate.x = -1;
|
|
|
m_imgPixel_XY_Coordinate.y = -1;
|
|
|
m_imgPixel_LBH_Coordinate.x = -200.f;
|
|
|
m_imgPixel_LBH_Coordinate.y = -200.f;
|
|
|
m_imgPixel_LBH_Coordinate.z = -200.f;
|
|
|
}
|
|
|
|
|
|
// 回调输出信息即可
|
|
|
if (m_lpSendPixInfoProc != NULL)
|
|
|
{
|
|
|
CPoint pt;
|
|
|
pt.x = m_imgPixel_XY_Coordinate.x;
|
|
|
pt.y = m_imgPixel_XY_Coordinate.y;
|
|
|
|
|
|
m_lpSendPixInfoProc(pt, m_imgPixel_LBH_Coordinate.x, m_imgPixel_LBH_Coordinate.y, m_imgPixel_LBH_Coordinate.z);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.msg;
|
|
|
return;
|
|
|
}
|
|
|
catch(...)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 滚轮消息响应
|
|
|
BOOL CImgShowDlg::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
// 放大
|
|
|
if (zDelta > 0)
|
|
|
{
|
|
|
if (m_SrcFrame != NULL)
|
|
|
{
|
|
|
// 放大并显示图像
|
|
|
DoZoomInImg();
|
|
|
|
|
|
// 更新标绘窗口
|
|
|
DrawSquareOnScreen(GetScreenCoordinateBasedOnPixelCoordinate(m_LButtonDblClkPixelCoordinate), FALSE);
|
|
|
}
|
|
|
}else // 缩小
|
|
|
{
|
|
|
if (m_SrcFrame != NULL)
|
|
|
{
|
|
|
// 放大并显示图像
|
|
|
DoZoomOutImg();
|
|
|
|
|
|
// 更新标绘窗口
|
|
|
DrawSquareOnScreen(GetScreenCoordinateBasedOnPixelCoordinate(m_LButtonDblClkPixelCoordinate), FALSE);
|
|
|
}
|
|
|
}
|
|
|
return TRUE;
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.msg;
|
|
|
return FALSE;
|
|
|
}
|
|
|
catch(...)
|
|
|
{
|
|
|
return FALSE;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
BOOL CImgShowDlg::OnInitDialog()
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
CDialog::OnInitDialog();
|
|
|
|
|
|
// 数据存储目录
|
|
|
m_sRootFolder = GetSoftwareCurrentDirectory() + "\\QB_RESULT";
|
|
|
m_sImgSaveFolder = m_sRootFolder + "\\EDITED_IMAGE";
|
|
|
|
|
|
// 创建文件夹
|
|
|
CreateDirectory(m_sRootFolder, NULL);
|
|
|
CreateDirectory(m_sImgSaveFolder, NULL);
|
|
|
|
|
|
m_hMutex_ProcessData = CreateMutexA(NULL, FALSE, NULL);
|
|
|
|
|
|
m_pFastLookUpDlg = new CFastLookUpDlg();
|
|
|
|
|
|
if (m_pFastLookUpDlg != NULL)
|
|
|
{
|
|
|
m_pFastLookUpDlg->Create(IDD_DLG_FAST_LOOKUP_IMGS, this);
|
|
|
m_pFastLookUpDlg->SetParentPt(this);
|
|
|
}
|
|
|
|
|
|
return TRUE;
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.msg;
|
|
|
return FALSE;
|
|
|
}
|
|
|
catch(...)
|
|
|
{
|
|
|
return FALSE;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
// 设置一路信号是否正在输入
|
|
|
void CImgShowDlg::SetFirstSignal(BOOL bflag)
|
|
|
{
|
|
|
m_bFirstSignal = bflag;
|
|
|
}
|
|
|
|
|
|
BOOL CImgShowDlg::GetFirstSignal()
|
|
|
{
|
|
|
return m_bFirstSignal;
|
|
|
}
|
|
|
|
|
|
// 设置2路信号是否正在输入
|
|
|
void CImgShowDlg::SetSecondSignal(BOOL bflag)
|
|
|
{
|
|
|
m_bSecondSignal = bflag;
|
|
|
}
|
|
|
|
|
|
BOOL CImgShowDlg::GetSecondSignal()
|
|
|
{
|
|
|
return m_bSecondSignal;
|
|
|
}
|
|
|
|
|
|
// 释放m_LatestQBData
|
|
|
void CImgShowDlg::ReleaseLatestQBData()
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
ReleaseQBData(&m_LatestQBData);
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.msg;
|
|
|
return;
|
|
|
}
|
|
|
catch(...)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
// 设置m_LatestQBData
|
|
|
void CImgShowDlg::SetLatestQBData(const QBStru &qbData)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
ReleaseQBData(&m_LatestQBData);
|
|
|
CloneQBData(qbData, m_LatestQBData);
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.msg;
|
|
|
return;
|
|
|
}
|
|
|
catch(...)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 设置经纬度盒子
|
|
|
void CImgShowDlg::SetBoundingBox(GeoBoundingBox box)
|
|
|
{
|
|
|
m_boundbingBox = box;
|
|
|
}
|
|
|
|
|
|
// 设置iLatest
|
|
|
void CImgShowDlg::SetiLatest(int i)
|
|
|
{
|
|
|
m_iLatest = i;
|
|
|
}
|
|
|
|
|
|
int CImgShowDlg::GetiLatest()
|
|
|
{
|
|
|
return m_iLatest;
|
|
|
}
|
|
|
|
|
|
// 设置iPreLatest
|
|
|
void CImgShowDlg::SetiPreLatest(int i)
|
|
|
{
|
|
|
m_iPreLatest = i;
|
|
|
}
|
|
|
|
|
|
int CImgShowDlg::GetiPreLatest()
|
|
|
{
|
|
|
return m_iPreLatest;
|
|
|
}
|
|
|
|
|
|
//功能:解压后的情报数据处理函数(包括三项:更新本地情报、显示、入队列和对外传递数据)
|
|
|
void CImgShowDlg::DisposeQBData(const QBStru* qbData)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
// 空值判断
|
|
|
if (qbData == nullptr)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
|
|
|
// 输入数据有效性判断 如果复接数据和图像数据均无效,直接返回
|
|
|
if ((qbData->framePart.bValid == false) && (qbData->image.bValid == false))
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// 功能1:更新数据 m_LatestQBData
|
|
|
CloneQBData(*qbData, m_LatestQBData);
|
|
|
|
|
|
// 设置为 小于0 的无效值
|
|
|
m_LButtonDblClkPixelCoordinate.x = -1;
|
|
|
m_LButtonDblClkPixelCoordinate.y = -1;
|
|
|
|
|
|
// 功能2:显示(显示图像)和 指北针 dstImg 或 srcImg,不显示geoImg(暂时觉得没必要)
|
|
|
ShowLatestQBData();
|
|
|
|
|
|
// 功能3:入队列: 按需入队
|
|
|
if (m_bMemPreMultiFrame == TRUE)
|
|
|
{
|
|
|
PushLatestQBData2Deque();
|
|
|
|
|
|
// 功能4:送入 快速查询模块
|
|
|
if (m_pFastLookUpDlg != NULL)
|
|
|
{
|
|
|
m_pFastLookUpDlg->SetImgData(m_LatestQBData.image.srcImg);
|
|
|
if (m_pFastLookUpDlg->IsWindowVisible() == TRUE)
|
|
|
{
|
|
|
m_pFastLookUpDlg->ShowImgData();
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 更新数目,注意不是+1
|
|
|
WaitForSingleObject(m_hMutex_ProcessData, INFINITE);
|
|
|
m_currentImgOrder = static_cast<int>(m_QBDataDeque.size());
|
|
|
ReleaseMutex(m_hMutex_ProcessData);
|
|
|
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.msg;
|
|
|
return;
|
|
|
}
|
|
|
catch(...)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
// 功能:m_LatestQBData 入队列
|
|
|
// 输入:
|
|
|
// 输出:
|
|
|
// 说明:只有当m_LatestQBData图像数据有效时,方可入队
|
|
|
// 功能:LatestQBData 入队列,
|
|
|
void CImgShowDlg::PushLatestQBData2Deque()
|
|
|
{
|
|
|
WaitForSingleObject(m_hMutex_ProcessData, INFINITE);
|
|
|
try
|
|
|
{
|
|
|
if (m_LatestQBData.image.bValid == true) // 图像数据有效
|
|
|
{
|
|
|
if ( m_QBDataDeque.size() < 18U)
|
|
|
{
|
|
|
QBStru local; // 局部变量
|
|
|
CloneQBData(m_LatestQBData,local); // 深度复制
|
|
|
|
|
|
|
|
|
m_QBDataDeque.push_back(local); // 入队,浅复制
|
|
|
|
|
|
|
|
|
// 设置局部变量buffer指向空,否则,local超出作用域会析构其指向的内存单元,
|
|
|
// 从而使local中已入队的结构体成为野指针;
|
|
|
local.image.srcImg.buff = NULL;
|
|
|
local.image.dstImg.buff = NULL;
|
|
|
local.image.geoImg.buff = NULL;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
while(m_QBDataDeque.size() >= 18U) // 设计原因:中途可能设置小于当前数目的容量
|
|
|
{
|
|
|
// 弹出
|
|
|
std::deque<QBStru>::iterator iter; // 定义迭代器
|
|
|
iter = m_QBDataDeque.begin();
|
|
|
|
|
|
// 释放指针指向的内存
|
|
|
SAFE_DELETE_ARRAY(iter->image.srcImg.buff);
|
|
|
SAFE_DELETE_ARRAY(iter->image.dstImg.buff);
|
|
|
SAFE_DELETE_ARRAY(iter->image.geoImg.buff);
|
|
|
|
|
|
// 弹出
|
|
|
m_QBDataDeque.pop_front();
|
|
|
}
|
|
|
|
|
|
// 当前帧入队
|
|
|
QBStru local; // 局部变量
|
|
|
CloneQBData(m_LatestQBData, local); // 深度复制
|
|
|
|
|
|
m_QBDataDeque.push_back(local); // 入队,浅复制
|
|
|
|
|
|
// 设置局部变量buffer指向空,否则,local超出作用域会析构其指向的内存单元,
|
|
|
// 从而使local中已入队的结构体成为野指针;
|
|
|
local.image.srcImg.buff = NULL;
|
|
|
local.image.dstImg.buff = NULL;
|
|
|
local.image.geoImg.buff = NULL;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.msg;
|
|
|
}
|
|
|
catch(...)
|
|
|
{
|
|
|
}
|
|
|
ReleaseMutex(m_hMutex_ProcessData);
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 1.29 功能:清理内存及记忆
|
|
|
// 输入:无
|
|
|
//
|
|
|
// 输出:无
|
|
|
void CImgShowDlg::ClearMemory()
|
|
|
{
|
|
|
if (m_bFirstSignal == TRUE || m_bSecondSignal == TRUE)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
try
|
|
|
{
|
|
|
// 如果有图像 需要释放该图像
|
|
|
if (m_SrcFrame != NULL)
|
|
|
{
|
|
|
cvReleaseImage(&m_SrcFrame);
|
|
|
m_SrcFrame = NULL;
|
|
|
}
|
|
|
|
|
|
// 当前情报数据结构体:LatestQBData
|
|
|
ReleaseQBData(&m_LatestQBData);
|
|
|
|
|
|
WaitForSingleObject(m_hMutex_ProcessData, INFINITE);
|
|
|
// 情报队列销毁
|
|
|
if(m_QBDataDeque.size() > 0)
|
|
|
{
|
|
|
for (size_t i = 0; i < m_QBDataDeque.size(); ++i)
|
|
|
{
|
|
|
SAFE_DELETE_ARRAY(m_QBDataDeque[i].image.srcImg.buff);
|
|
|
SAFE_DELETE_ARRAY(m_QBDataDeque[i].image.dstImg.buff);
|
|
|
SAFE_DELETE_ARRAY(m_QBDataDeque[i].image.geoImg.buff);
|
|
|
}
|
|
|
|
|
|
m_QBDataDeque.clear();
|
|
|
}
|
|
|
ReleaseMutex(m_hMutex_ProcessData);
|
|
|
|
|
|
|
|
|
// midImg 释放
|
|
|
SAFE_DELETE_ARRAY(m_midImg.buff);
|
|
|
|
|
|
// 复位
|
|
|
m_ShowRegion = CRect(0,0,0,0);
|
|
|
|
|
|
m_ShowRegionOnScreen.left = 0;
|
|
|
m_ShowRegionOnScreen.right = 0;
|
|
|
m_ShowRegionOnScreen.top = 0;
|
|
|
m_ShowRegionOnScreen.bottom = 0;
|
|
|
|
|
|
m_LButtonDownPixelCoordinate = CPoint(0,0);
|
|
|
m_bStaisfyRoamImg = FALSE;
|
|
|
m_LatestPlotRect = CRect(0,0,0,0);
|
|
|
m_LButtonDblClkPixelCoordinate = CPoint(-1, -1);
|
|
|
|
|
|
m_LeftButtonDown.x = 0;
|
|
|
m_LeftButtonDown.y = 0;
|
|
|
|
|
|
m_RButtonPt.x = 0;
|
|
|
m_RButtonPt.y = 0;
|
|
|
|
|
|
m_SrcFrame = NULL;
|
|
|
m_ImgRatioOnScreen = 1.0F;
|
|
|
|
|
|
m_ImgShowShift.x = 0L;
|
|
|
m_ImgShowShift.y = 0L;
|
|
|
|
|
|
m_bFirstSignal = FALSE;
|
|
|
m_bSecondSignal = FALSE;
|
|
|
m_bSatisfyMove = FALSE;
|
|
|
|
|
|
m_iLatest = 0;
|
|
|
m_iPreLatest = 0;
|
|
|
|
|
|
m_LatestQuadrangle = CRect(0,0,0,0);
|
|
|
|
|
|
// 像素信息
|
|
|
m_imgPixel_XY_Coordinate.x = -1;
|
|
|
m_imgPixel_XY_Coordinate.y = -1;
|
|
|
m_imgPixel_LBH_Coordinate.x = -200.0;
|
|
|
m_imgPixel_LBH_Coordinate.y = -200.0;
|
|
|
m_imgPixel_LBH_Coordinate.z = -200.0;
|
|
|
|
|
|
m_currentImgOrder = 0;
|
|
|
|
|
|
m_TargetCenter = cv::Point(-100, -100);
|
|
|
m_bDrawSquareOnImg = TRUE;
|
|
|
|
|
|
m_deltaLon = 0;
|
|
|
m_deltaLat = 0;
|
|
|
|
|
|
// 使窗口无效
|
|
|
Invalidate();
|
|
|
|
|
|
// 释放快速浏览对话框内存图像
|
|
|
if (m_pFastLookUpDlg != NULL)
|
|
|
{
|
|
|
m_pFastLookUpDlg->ClearMemory();
|
|
|
}
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.msg;
|
|
|
return;
|
|
|
}
|
|
|
catch(...)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
// 3.12 功能:保存图像为tiff,并回调保存路径
|
|
|
// 说明:当保存为tiff图像时,忽略校准量,牵扯面太广,且不可靠
|
|
|
// 如果实在想高精度保存一幅图像为tiff,可通过GCP几何校正实现
|
|
|
void CImgShowDlg::SaveToGeoTiff()
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
// 计算保存路径
|
|
|
CString savePath;
|
|
|
CString sRootFolder;
|
|
|
CString sImgSaveFolder;
|
|
|
|
|
|
// 数据存储目录
|
|
|
sRootFolder = GetSoftwareCurrentDirectory() + "\\QB_RESULT";
|
|
|
sImgSaveFolder = sRootFolder + "\\EDITED_IMAGE";
|
|
|
|
|
|
// 创建文件夹
|
|
|
CreateDirectory(sRootFolder, NULL);
|
|
|
CreateDirectory(sImgSaveFolder, NULL);
|
|
|
|
|
|
// 计算存储路径
|
|
|
SYSTEMTIME CurrentTime;
|
|
|
GetLocalTime(&CurrentTime);
|
|
|
savePath.Format( "%04d%02d%02d_%02d%02d%02d%04d",
|
|
|
CurrentTime.wYear,
|
|
|
CurrentTime.wMonth,
|
|
|
CurrentTime.wDay,
|
|
|
CurrentTime.wHour,
|
|
|
CurrentTime.wMinute,
|
|
|
CurrentTime.wSecond,
|
|
|
CurrentTime.wMilliseconds);
|
|
|
savePath = "Geo_" + savePath;
|
|
|
|
|
|
savePath = savePath + _T(".tif");
|
|
|
savePath = sImgSaveFolder + "\\" + savePath;
|
|
|
|
|
|
bool bret = false;
|
|
|
|
|
|
// 保存为tiff
|
|
|
if (true == SaveToGeoTIFF(&m_LatestQBData, savePath.GetBuffer(0)))
|
|
|
{
|
|
|
bret = true;
|
|
|
}
|
|
|
else if (true == SaveToGeoTIFF(&m_LatestQBData.image.dstImg, savePath.GetBuffer(0)))
|
|
|
{
|
|
|
bret = true;
|
|
|
}
|
|
|
else if (true == SaveToGeoTIFF(&m_LatestQBData.image.srcImg, savePath.GetBuffer(0)))
|
|
|
{
|
|
|
bret = true;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
bret = false;
|
|
|
}
|
|
|
|
|
|
if (bret == true)
|
|
|
{
|
|
|
// 保存路径回调
|
|
|
if (m_lpSendFilePath != NULL)
|
|
|
{
|
|
|
m_lpSendFilePath(savePath, 6);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 清理 geoImg
|
|
|
SAFE_DELETE_ARRAY(m_LatestQBData.image.geoImg.buff);
|
|
|
m_LatestQBData.image.geoImg.buff = NULL;
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.what();
|
|
|
return;
|
|
|
}
|
|
|
catch (...)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 右键 清理内存记忆
|
|
|
void CImgShowDlg::OnClearMemory()
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
ClearMemory();
|
|
|
|
|
|
// 复位目标标绘
|
|
|
m_bPlotRect = FALSE;
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.what();
|
|
|
return;
|
|
|
}
|
|
|
catch (...)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 单帧校正采集
|
|
|
void CImgShowDlg::OnSaveImgToTiff()
|
|
|
{
|
|
|
SaveToGeoTiff();
|
|
|
}
|
|
|
|
|
|
// 功能:图像去雾
|
|
|
void CImgShowDlg::AdjustImgDehaze(BOOL bAdjust, int A_MAX, double degree)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
if (bAdjust == TRUE)
|
|
|
{
|
|
|
if(m_bEnhanceEdit == true) // 增强
|
|
|
{
|
|
|
if (GetiLatest() == 0) // 如果刚什么也没做
|
|
|
{
|
|
|
if (m_LatestQBData.image.dstImg.buff == NULL && m_midImg.buff == NULL)
|
|
|
{
|
|
|
CloneImgStru(m_LatestQBData.image.srcImg, m_midImg);
|
|
|
DoDehazeCtrl(&m_midImg, &m_LatestQBData.image.dstImg, A_MAX, degree);
|
|
|
ShowLatestQBData(); // 显示图像
|
|
|
SetTargetPixelCoordinate(GetTargetCoordinate());
|
|
|
|
|
|
SetiPreLatest(GetiLatest());
|
|
|
SetiLatest(1);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
CloneImgStru(m_LatestQBData.image.dstImg, m_midImg);
|
|
|
DoDehazeCtrl(&m_midImg, &m_LatestQBData.image.dstImg, A_MAX, degree);
|
|
|
ShowLatestQBData(); // 显示图像
|
|
|
SetTargetPixelCoordinate(GetTargetCoordinate());
|
|
|
|
|
|
SetiPreLatest(GetiLatest());
|
|
|
SetiLatest(1);
|
|
|
}
|
|
|
}
|
|
|
else if (GetiLatest() == 1) // 如果刚才就是去雾
|
|
|
{
|
|
|
DoDehazeCtrl(&m_midImg, &m_LatestQBData.image.dstImg, A_MAX,degree);
|
|
|
ShowLatestQBData(); // 显示图像
|
|
|
SetTargetPixelCoordinate(GetTargetCoordinate());
|
|
|
|
|
|
SetiPreLatest(GetiLatest());
|
|
|
}
|
|
|
else // 其它
|
|
|
{
|
|
|
CloneImgStru(m_LatestQBData.image.dstImg, m_midImg);
|
|
|
|
|
|
DoDehazeCtrl(&m_midImg, &m_LatestQBData.image.dstImg, A_MAX,degree);
|
|
|
ShowLatestQBData(); // 显示图像
|
|
|
SetTargetPixelCoordinate(GetTargetCoordinate());
|
|
|
|
|
|
SetiPreLatest(GetiLatest());
|
|
|
SetiLatest(1);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.what();
|
|
|
return;
|
|
|
}
|
|
|
catch (...)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 功能:图像亮度调节
|
|
|
void CImgShowDlg::AdjustImgIntensity(BOOL bAdjust, int degree)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
// 执行亮度调节
|
|
|
if(bAdjust == TRUE)
|
|
|
{
|
|
|
if (degree == 10)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (m_bEnhanceEdit == true) // 增强
|
|
|
{
|
|
|
if (GetiLatest() == 0)
|
|
|
{
|
|
|
if (m_LatestQBData.image.dstImg.buff == NULL && m_midImg.buff == NULL)
|
|
|
{
|
|
|
CloneImgStru(m_LatestQBData.image.srcImg, m_midImg);
|
|
|
DoIntensityCtrl(&m_midImg, &m_LatestQBData.image.dstImg, degree);
|
|
|
ShowLatestQBData(); // 显示图像
|
|
|
SetTargetPixelCoordinate(GetTargetCoordinate());
|
|
|
|
|
|
SetiPreLatest(GetiLatest());
|
|
|
SetiLatest(2);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
CloneImgStru(m_LatestQBData.image.dstImg, m_midImg);
|
|
|
DoIntensityCtrl(&m_midImg, &m_LatestQBData.image.dstImg, degree);
|
|
|
ShowLatestQBData(); // 显示图像
|
|
|
SetTargetPixelCoordinate(GetTargetCoordinate());
|
|
|
|
|
|
SetiPreLatest(GetiLatest());
|
|
|
SetiLatest(2);
|
|
|
}
|
|
|
}
|
|
|
else if(GetiLatest() == 2)
|
|
|
{
|
|
|
DoIntensityCtrl(&m_midImg, &m_LatestQBData.image.dstImg, degree);
|
|
|
ShowLatestQBData(); // 显示图像
|
|
|
SetTargetPixelCoordinate(GetTargetCoordinate());
|
|
|
|
|
|
SetiPreLatest(GetiLatest());
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
CloneImgStru(m_LatestQBData.image.dstImg, m_midImg);
|
|
|
|
|
|
DoIntensityCtrl(&m_midImg, &m_LatestQBData.image.dstImg, degree);
|
|
|
ShowLatestQBData(); // 显示图像
|
|
|
SetTargetPixelCoordinate(GetTargetCoordinate());
|
|
|
|
|
|
SetiPreLatest(GetiLatest());
|
|
|
SetiLatest(2);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.what();
|
|
|
return;
|
|
|
}
|
|
|
catch (...)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 功能:图像对比度调节
|
|
|
void CImgShowDlg::AdjustImgContrast(BOOL bAdjust, int degree)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
if(bAdjust == TRUE)
|
|
|
{
|
|
|
if (degree == 10)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (m_bEnhanceEdit == true) // 增强
|
|
|
{
|
|
|
if (GetiLatest() == 0)
|
|
|
{
|
|
|
if (m_LatestQBData.image.dstImg.buff == NULL && m_midImg.buff == NULL)
|
|
|
{
|
|
|
CloneImgStru(m_LatestQBData.image.srcImg, m_midImg);
|
|
|
DoContrastCtrl(&m_midImg, &m_LatestQBData.image.dstImg, degree);
|
|
|
|
|
|
ShowLatestQBData(); // 显示图像
|
|
|
SetTargetPixelCoordinate(GetTargetCoordinate());
|
|
|
|
|
|
SetiPreLatest(GetiLatest());
|
|
|
SetiLatest(3);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
CloneImgStru(m_LatestQBData.image.dstImg, m_midImg);
|
|
|
DoContrastCtrl(&m_midImg, &m_LatestQBData.image.dstImg, degree);
|
|
|
|
|
|
ShowLatestQBData(); // 显示图像
|
|
|
SetTargetPixelCoordinate(GetTargetCoordinate());
|
|
|
|
|
|
SetiPreLatest(GetiLatest());
|
|
|
SetiLatest(3);
|
|
|
}
|
|
|
}
|
|
|
else if(GetiLatest() == 3)
|
|
|
{
|
|
|
DoContrastCtrl(&m_midImg, &m_LatestQBData.image.dstImg, degree);
|
|
|
ShowLatestQBData(); // 显示图像
|
|
|
SetTargetPixelCoordinate(GetTargetCoordinate());
|
|
|
|
|
|
SetiPreLatest(GetiLatest());
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
CloneImgStru(m_LatestQBData.image.dstImg, m_midImg);
|
|
|
|
|
|
DoContrastCtrl(&m_midImg, &m_LatestQBData.image.dstImg, degree);
|
|
|
ShowLatestQBData(); // 显示图像
|
|
|
SetTargetPixelCoordinate(GetTargetCoordinate());
|
|
|
|
|
|
SetiPreLatest(GetiLatest());
|
|
|
SetiLatest(3);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.what();
|
|
|
return;
|
|
|
}
|
|
|
catch (...)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 功能:图像清晰度调节
|
|
|
void CImgShowDlg::AdjustImgDefinition(BOOL bAdjust, int degree)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
if(bAdjust == TRUE)
|
|
|
{
|
|
|
if (degree == 10)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (m_bEnhanceEdit == true) // 增强
|
|
|
{
|
|
|
if (GetiLatest() == 0)
|
|
|
{
|
|
|
if (m_LatestQBData.image.dstImg.buff == NULL && m_midImg.buff == NULL)
|
|
|
{
|
|
|
CloneImgStru(m_LatestQBData.image.srcImg,m_midImg);
|
|
|
DoDefinitionCtrl(&m_midImg, &m_LatestQBData.image.dstImg, degree);
|
|
|
ShowLatestQBData(); // 显示图像
|
|
|
SetTargetPixelCoordinate(GetTargetCoordinate());
|
|
|
|
|
|
SetiPreLatest(GetiLatest());
|
|
|
SetiLatest(4);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
CloneImgStru(m_LatestQBData.image.dstImg,m_midImg);
|
|
|
DoDefinitionCtrl(&m_midImg, &m_LatestQBData.image.dstImg, degree);
|
|
|
ShowLatestQBData(); // 显示图像
|
|
|
SetTargetPixelCoordinate(GetTargetCoordinate());
|
|
|
|
|
|
SetiPreLatest(GetiLatest());
|
|
|
SetiLatest(4);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
else if(GetiLatest() == 4)
|
|
|
{
|
|
|
DoDefinitionCtrl(&m_midImg, &m_LatestQBData.image.dstImg, degree);
|
|
|
ShowLatestQBData(); // 显示图像
|
|
|
SetTargetPixelCoordinate(GetTargetCoordinate());
|
|
|
|
|
|
SetiPreLatest(GetiLatest());
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
CloneImgStru(m_LatestQBData.image.dstImg, m_midImg);
|
|
|
|
|
|
DoDefinitionCtrl(&m_midImg, &m_LatestQBData.image.dstImg, degree);
|
|
|
ShowLatestQBData(); // 显示图像
|
|
|
SetTargetPixelCoordinate(GetTargetCoordinate());
|
|
|
|
|
|
SetiPreLatest(GetiLatest());
|
|
|
SetiLatest(4);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.what();
|
|
|
return;
|
|
|
}
|
|
|
catch (...)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 功能:返回图像调节上一步图像状态
|
|
|
void CImgShowDlg::ReturnToPreImgState()
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
if (m_bEnhanceEdit == true)
|
|
|
{
|
|
|
CloneImgStru(m_midImg, m_LatestQBData.image.dstImg);
|
|
|
|
|
|
ShowLatestQBData(); // 显示图像
|
|
|
SetTargetPixelCoordinate(GetTargetCoordinate());
|
|
|
|
|
|
// 返回一步
|
|
|
SetiLatest(GetiPreLatest());
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
CloneImgStru(m_midImg, m_LatestQBData.image.dstImg);
|
|
|
|
|
|
// 标记 m_SrcFrame
|
|
|
cv::Mat srcFrameMat(m_SrcFrame, false);
|
|
|
|
|
|
if (srcFrameMat.type() == CV_8UC1)
|
|
|
{
|
|
|
memcpy(srcFrameMat.data, m_LatestQBData.image.dstImg.buff, srcFrameMat.cols * srcFrameMat.rows); // 图像数据复制
|
|
|
}
|
|
|
else if (srcFrameMat.type() == CV_8UC3)
|
|
|
{
|
|
|
memcpy(srcFrameMat.data, m_LatestQBData.image.dstImg.buff, srcFrameMat.cols * srcFrameMat.rows * 3); // 图像数据复制
|
|
|
}
|
|
|
|
|
|
Invalidate();
|
|
|
}
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.what();
|
|
|
return;
|
|
|
}
|
|
|
catch (...)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 功能:返回原始图像状态
|
|
|
void CImgShowDlg::ReturnToSrcImgState()
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
if (m_bEnhanceEdit == true)
|
|
|
{
|
|
|
SAFE_DELETE_ARRAY(m_midImg.buff);
|
|
|
m_midImg.buff = NULL;
|
|
|
|
|
|
SAFE_DELETE_ARRAY(m_LatestQBData.image.dstImg.buff);
|
|
|
m_LatestQBData.image.dstImg.buff = NULL;
|
|
|
|
|
|
ShowLatestQBData(); // 显示图像
|
|
|
SetTargetPixelCoordinate(GetTargetCoordinate());
|
|
|
|
|
|
// 一步还原
|
|
|
SetiLatest(0);
|
|
|
SetiPreLatest(0);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
CloneImgStru(m_LatestQBData.image.srcImg, m_midImg);
|
|
|
CloneImgStru(m_LatestQBData.image.srcImg, m_LatestQBData.image.dstImg);
|
|
|
|
|
|
// 标记 m_SrcFrame
|
|
|
cv::Mat srcFrameMat(m_SrcFrame, false);
|
|
|
|
|
|
if (srcFrameMat.type() == CV_8UC1)
|
|
|
{
|
|
|
memcpy(srcFrameMat.data, m_LatestQBData.image.srcImg.buff, srcFrameMat.cols * srcFrameMat.rows); // 图像数据复制
|
|
|
}
|
|
|
else if (srcFrameMat.type() == CV_8UC3)
|
|
|
{
|
|
|
memcpy(srcFrameMat.data, m_LatestQBData.image.srcImg.buff, srcFrameMat.cols * srcFrameMat.rows * 3); // 图像数据复制
|
|
|
}
|
|
|
|
|
|
Invalidate();
|
|
|
}
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.what();
|
|
|
return;
|
|
|
}
|
|
|
catch (...)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 18 功能:设置图像编辑类型
|
|
|
void CImgShowDlg::SetImgEditType(int type)
|
|
|
{
|
|
|
m_iImgEditType = type;
|
|
|
|
|
|
if (type == 1 || type == 2 || type == 3)
|
|
|
{
|
|
|
m_bEnhanceEdit = false;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
m_bEnhanceEdit = true;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 获取图像编辑模式 true 增强 false 标记
|
|
|
bool CImgShowDlg::GetImgEditMode()
|
|
|
{
|
|
|
return m_bEnhanceEdit;
|
|
|
}
|
|
|
|
|
|
// 20 功能:显示记忆图像队列中的指定某一张图像
|
|
|
void CImgShowDlg::ShowSelectedImgInMem(int order)
|
|
|
{
|
|
|
WaitForSingleObject(m_hMutex_ProcessData, INFINITE);
|
|
|
try
|
|
|
{
|
|
|
if (m_QBDataDeque.empty() == false)
|
|
|
{
|
|
|
if (order >= 1 && order <= static_cast<int>(m_QBDataDeque.size())/* && m_currentImgOrder != order*/)
|
|
|
{
|
|
|
// 释放
|
|
|
ReleaseQBData(&m_LatestQBData);
|
|
|
|
|
|
SAFE_DELETE(m_midImg.buff);
|
|
|
m_midImg.buff = NULL;
|
|
|
|
|
|
CloneQBData(m_QBDataDeque[order - 1], m_LatestQBData);
|
|
|
|
|
|
ShowLatestQBData();
|
|
|
m_currentImgOrder = order;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.what();
|
|
|
}
|
|
|
catch (...)
|
|
|
{
|
|
|
int a = 8;
|
|
|
}
|
|
|
ReleaseMutex(m_hMutex_ProcessData);
|
|
|
}
|
|
|
|
|
|
// 快速查找图像
|
|
|
void CImgShowDlg::OnFastLookupImgs()
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
if (m_pFastLookUpDlg != NULL)
|
|
|
{
|
|
|
// 为空时
|
|
|
if (m_pFastLookUpDlg->isEmpty() == true)
|
|
|
{
|
|
|
::MessageBoxA(NULL, _T("无记忆图像供查找!"),_T("操作提示"), MB_OK);
|
|
|
m_pFastLookUpDlg->ShowWindow(SW_HIDE);
|
|
|
return;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
if (TRUE == m_pFastLookUpDlg->IsWindowVisible())
|
|
|
{
|
|
|
m_pFastLookUpDlg->ShowWindow(SW_HIDE);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
m_pFastLookUpDlg->ShowWindow(SW_SHOW);
|
|
|
m_pFastLookUpDlg->ShowImgData();
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.what();
|
|
|
return;
|
|
|
}
|
|
|
catch (...)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
// 定位引导
|
|
|
void CImgShowDlg::OnTgtLocLead()
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
// 右键坐标
|
|
|
CPoint point;
|
|
|
point.x = m_RButtonPt.x;
|
|
|
point.y = m_RButtonPt.y;
|
|
|
|
|
|
if (m_bFirstSignal == TRUE || m_bSecondSignal == TRUE)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (m_SrcFrame != NULL)
|
|
|
{
|
|
|
// 计算 CPoint point 对应的像素坐标 CPoint LButtonDblClkPixelCoordinate;
|
|
|
if ((point.x > m_ShowRegionOnScreen.left) && (point.x < m_ShowRegionOnScreen.right) &&
|
|
|
(point.y > m_ShowRegionOnScreen.top) && (point.y < m_ShowRegionOnScreen.bottom)) // 鼠标在图像上
|
|
|
{
|
|
|
// 图像尺寸与显示区域尺寸之间的比例
|
|
|
double ratio = 1.0;
|
|
|
|
|
|
// 分母0值判断
|
|
|
if (m_ShowRegionOnScreen.Width() > 0)
|
|
|
{
|
|
|
ratio = (m_ShowRegion.Width() * 1.0) / m_ShowRegionOnScreen.Width();
|
|
|
}
|
|
|
|
|
|
CPoint PixelCoordinate; // 像素坐标
|
|
|
PixelCoordinate.x = static_cast<LONG>((point.x - m_ShowRegionOnScreen.left) * ratio) + m_ShowRegion.left;
|
|
|
PixelCoordinate.y = static_cast<LONG>((point.y - m_ShowRegionOnScreen.top) * ratio) + m_ShowRegion.top;
|
|
|
|
|
|
|
|
|
// 经纬度坐标
|
|
|
double Lon = -200;
|
|
|
double Lat = -200;
|
|
|
double H = 0;
|
|
|
|
|
|
// 图像四个顶点的经纬度坐标
|
|
|
double Lon1 = -200, Lat1 = -200, H1 = -200;
|
|
|
double Lon2 = -200, Lat2 = -200, H2 = -200;
|
|
|
double Lon3 = -200, Lat3 = -200, H3 = -200;
|
|
|
double Lon4 = -200, Lat4 = -200, H4 = -200;
|
|
|
|
|
|
if (false == DoCalAnyPtCoordinate(Lon, Lat, H, &m_LatestQBData.framePart, PixelCoordinate.x, PixelCoordinate.y))
|
|
|
{
|
|
|
if (m_boundbingBox.EastLon - m_boundbingBox.WestLon > 0
|
|
|
&& m_boundbingBox.WestLon >= -180
|
|
|
&& m_boundbingBox.WestLon <= 180
|
|
|
&& m_boundbingBox.EastLon >= -180
|
|
|
&& m_boundbingBox.EastLon <= 180
|
|
|
&& m_boundbingBox.NorthLat - m_boundbingBox.SouthLat > 0
|
|
|
&& m_boundbingBox.SouthLat >= -90
|
|
|
&& m_boundbingBox.SouthLat <= 90
|
|
|
&& m_boundbingBox.NorthLat >= -90
|
|
|
&& m_boundbingBox.NorthLat <= 90)
|
|
|
{
|
|
|
double LonResolution = (m_boundbingBox.EastLon - m_boundbingBox.WestLon) / m_SrcFrame->width;
|
|
|
double LatResolution = (m_boundbingBox.NorthLat - m_boundbingBox.SouthLat) / m_SrcFrame->height;
|
|
|
|
|
|
Lon = float(m_boundbingBox.WestLon + PixelCoordinate.x * LonResolution);
|
|
|
Lat = float(m_boundbingBox.NorthLat - PixelCoordinate.y * LatResolution);
|
|
|
|
|
|
|
|
|
// 四个角点经纬度
|
|
|
Lon1 = m_boundbingBox.WestLon, Lat1 = m_boundbingBox.NorthLat;
|
|
|
Lon2 = m_boundbingBox.EastLon, Lat2 = m_boundbingBox.NorthLat;
|
|
|
Lon3 = m_boundbingBox.EastLon, Lat3 = m_boundbingBox.SouthLat;
|
|
|
Lon4 = m_boundbingBox.WestLon, Lat4 = m_boundbingBox.SouthLat;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
Lon = -200.f;
|
|
|
Lat = -200.f;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
// 计算四个角点的经纬度坐标
|
|
|
bool ret1 = DoCalAnyPtCoordinate(Lon1, Lat1, H1, &m_LatestQBData.framePart, 0, 0);
|
|
|
bool ret2 = DoCalAnyPtCoordinate(Lon2, Lat2, H2, &m_LatestQBData.framePart, m_SrcFrame->width - 1, 0);
|
|
|
bool ret3 = DoCalAnyPtCoordinate(Lon3, Lat3, H3, &m_LatestQBData.framePart, m_SrcFrame->width - 1, m_SrcFrame->height - 1);
|
|
|
bool ret4 = DoCalAnyPtCoordinate(Lon4, Lat4, H4, &m_LatestQBData.framePart, 0, m_SrcFrame->height - 1);
|
|
|
}
|
|
|
|
|
|
// 修正
|
|
|
if (abs(Lon) < 180 && abs(Lat) < 90)
|
|
|
{
|
|
|
Lon += m_deltaLon;
|
|
|
Lat += m_deltaLat;
|
|
|
|
|
|
Lon1 += m_deltaLon, Lat1 += m_deltaLat;
|
|
|
Lon2 += m_deltaLon, Lat2 += m_deltaLat;
|
|
|
Lon3 += m_deltaLon, Lat3 += m_deltaLat;
|
|
|
Lon4 += m_deltaLon, Lat4 += m_deltaLat;
|
|
|
}
|
|
|
|
|
|
// 回调输出
|
|
|
if (m_lpSendTgrLocLeadLonLat != NULL)
|
|
|
{
|
|
|
m_lpSendTgrLocLeadLonLat(Lon, Lat,
|
|
|
Lon1, Lat1,
|
|
|
Lon2, Lat2,
|
|
|
Lon3, Lat3,
|
|
|
Lon4, Lat4);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.msg;
|
|
|
return;
|
|
|
}
|
|
|
catch(...)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void CImgShowDlg::LeadImgLoc()
|
|
|
{
|
|
|
CRect rect;
|
|
|
GetClientRect(&rect);
|
|
|
|
|
|
// 右键坐标
|
|
|
m_RButtonPt.x = rect.Width() / 2;
|
|
|
m_RButtonPt.y = rect.Height() / 2;
|
|
|
|
|
|
OnTgtLocLead();
|
|
|
}
|
|
|
|
|
|
// 几何校正 并显示图像
|
|
|
void CImgShowDlg::OnGeoCorrectAndShow()
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
// 当未设置定位导引输出函数指针时,即不用于地图匹配定位时,该功能设为无效
|
|
|
if (m_lpSendTgrLocLeadLonLat == NULL)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
|
|
|
// 几何校正: 选择该模式的原因是牵扯到图像增强等操作
|
|
|
if (TRUE == DoSysGeoCorrect(&m_LatestQBData))
|
|
|
{
|
|
|
SAFE_DELETE_ARRAY(m_LatestQBData.image.srcImg.buff);
|
|
|
SAFE_DELETE_ARRAY(m_LatestQBData.image.dstImg.buff);
|
|
|
|
|
|
CloneImgStru(m_LatestQBData.image.geoImg, m_LatestQBData.image.srcImg);
|
|
|
|
|
|
SAFE_DELETE_ARRAY(m_LatestQBData.image.geoImg.buff);
|
|
|
|
|
|
// 复接数据设置为0 无效
|
|
|
m_LatestQBData.framePart.bValid = false;
|
|
|
memset(&m_LatestQBData.framePart, 0, sizeof(m_LatestQBData.framePart));
|
|
|
|
|
|
// 设置经纬度盒子
|
|
|
SetBoundingBox(m_LatestQBData.image.srcImg.BoundingBox);
|
|
|
|
|
|
// 显示图像
|
|
|
ShowLatestQBData();
|
|
|
}
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.msg;
|
|
|
return;
|
|
|
}
|
|
|
catch (...)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
// 设置文件夹
|
|
|
void CImgShowDlg::SetSaveCurrentImgFolder(CString str)
|
|
|
{
|
|
|
m_sSaveCurrentImgFolder = str;
|
|
|
}
|
|
|
|
|
|
void CImgShowDlg::SetSavePreMultiImgFolder(CString str)
|
|
|
{
|
|
|
m_sSavePreMultiImgFolder = str;
|
|
|
}
|
|
|
|
|
|
// 21 功能:几何校正并显示图像
|
|
|
void CImgShowDlg::GeoCorrectAndShowImg()
|
|
|
{
|
|
|
OnGeoCorrectAndShow();
|
|
|
}
|
|
|
|
|
|
// 在图像中标绘目标 矩形 定位用
|
|
|
void CImgShowDlg::OnDrawSqureOnImg()
|
|
|
{
|
|
|
// 只有设置了目标导引情况下操作
|
|
|
if (m_lpSendTgrLocLeadLonLat != NULL)
|
|
|
{
|
|
|
m_bDrawSquareOnImg = !m_bDrawSquareOnImg;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
m_bDrawSquareOnImg = FALSE;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
// 图像加载线程(GDAL)
|
|
|
UINT LoadImgThroughGDAL(void *pt)
|
|
|
{
|
|
|
CImgShowDlg *ptr = (CImgShowDlg*)pt;
|
|
|
if (ptr == nullptr)
|
|
|
{
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
CString ImgFilePath = ptr->m_GDALLoadImgPath;
|
|
|
|
|
|
try
|
|
|
{
|
|
|
// 注册
|
|
|
GDALAllRegister();
|
|
|
CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO");
|
|
|
|
|
|
// 打开图像
|
|
|
GDALDataset* srcDataSet = nullptr;
|
|
|
srcDataSet = (GDALDataset*)GDALOpen(ImgFilePath, GA_ReadOnly);
|
|
|
|
|
|
if (srcDataSet != nullptr)
|
|
|
{
|
|
|
// 获取图像参数
|
|
|
int Width = srcDataSet->GetRasterXSize();
|
|
|
int Height = srcDataSet->GetRasterYSize();
|
|
|
int nBound = srcDataSet->GetRasterCount();
|
|
|
|
|
|
if (nBound == 1 || nBound == 3)
|
|
|
{
|
|
|
double r = 0;
|
|
|
if (Width > Height)
|
|
|
{
|
|
|
r = 10000.0 / Width;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
r = 10000.0 / Height;
|
|
|
}
|
|
|
|
|
|
if (r > 1)
|
|
|
{
|
|
|
r = 1.0;
|
|
|
}
|
|
|
|
|
|
int scaledWidth = int(Width * r);;
|
|
|
int scaledHeight = int(Height * r);
|
|
|
|
|
|
if (scaledWidth > 0 && scaledHeight > 0)
|
|
|
{
|
|
|
GDALRasterBand *pBand = srcDataSet->GetRasterBand(1);
|
|
|
GDALDataType type = pBand->GetRasterDataType();
|
|
|
|
|
|
cv::Mat img;
|
|
|
if (nBound == 1)
|
|
|
{
|
|
|
img = cv::Mat(scaledHeight, scaledWidth, CV_8UC1, cv::Scalar(0));
|
|
|
pBand->RasterIO(GF_Read, 0,0, Width, Height, img.data, img.cols, img.rows, type, 0, 0);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
img = cv::Mat(scaledHeight, scaledWidth, CV_8UC3, cv::Scalar(0));
|
|
|
int bandMap[3] = {3, 2, 1};
|
|
|
CPLErr error = srcDataSet->RasterIO(GF_Read, 0,0,
|
|
|
Width, Height,
|
|
|
img.data,
|
|
|
img.cols, img.rows,
|
|
|
type,
|
|
|
3,
|
|
|
bandMap,
|
|
|
3, // nPixelSpace
|
|
|
3 * scaledWidth, // nLineSpace
|
|
|
1); // nBandSpace
|
|
|
}
|
|
|
|
|
|
BITMAPINFO info;
|
|
|
info.bmiHeader.biWidth = img.cols;
|
|
|
info.bmiHeader.biHeight = img.rows;
|
|
|
info.bmiHeader.biBitCount = static_cast<WORD>(img.channels() * 8);
|
|
|
|
|
|
double GISDATA[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
|
|
|
|
|
|
srcDataSet->GetGeoTransform(GISDATA);
|
|
|
|
|
|
double WLon = GISDATA[0];
|
|
|
double ELon = GISDATA[0] + Width * GISDATA[1];
|
|
|
double NLat = GISDATA[3];
|
|
|
double SLat = GISDATA[3] + Height * GISDATA[5];
|
|
|
|
|
|
GeoBoundingBox LBbox;
|
|
|
LBbox.WestLon = WLon;
|
|
|
LBbox.EastLon = ELon;
|
|
|
LBbox.SouthLat = SLat;
|
|
|
LBbox.NorthLat = NLat;
|
|
|
|
|
|
ptr->LoadOneImgFromMenu(&info, img.data, LBbox);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
GDALClose(srcDataSet);
|
|
|
srcDataSet = NULL;
|
|
|
}
|
|
|
catch(...)
|
|
|
{
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
|
|
|
// 右键打开一副图像
|
|
|
void CImgShowDlg::OnOpenOneImg()
|
|
|
{
|
|
|
CFileDialog ImgDialog(
|
|
|
TRUE,
|
|
|
NULL,
|
|
|
NULL,
|
|
|
OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST|OFN_HIDEREADONLY,
|
|
|
_T("Image files (*.bmp;*.jpg;*.tif;) |*.bmp;*.jpg;*.tif;| All Files (*.*) |*.*||"),
|
|
|
NULL);
|
|
|
|
|
|
ImgDialog.m_ofn.lpstrTitle = _T("打开一幅图像");
|
|
|
if (ImgDialog.DoModal() != IDOK)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
CString ImgFilePath = ImgDialog.GetPathName();
|
|
|
|
|
|
m_GDALLoadImgPath = ImgFilePath;
|
|
|
|
|
|
int len = ImgFilePath.GetLength();
|
|
|
int leftLen = ImgFilePath.ReverseFind('.');
|
|
|
|
|
|
CString Type = ImgFilePath.Right(len - leftLen);
|
|
|
|
|
|
std::string path = ImgFilePath.GetString();
|
|
|
|
|
|
try
|
|
|
{
|
|
|
cv::Mat img = cv::imread(path, -1);
|
|
|
|
|
|
if (img.empty() == true)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
BITMAPINFO info;
|
|
|
info.bmiHeader.biWidth = img.cols;
|
|
|
info.bmiHeader.biHeight = img.rows;
|
|
|
info.bmiHeader.biBitCount = static_cast<WORD>(img.channels() * 8);
|
|
|
|
|
|
if (Type == ".tif")
|
|
|
{
|
|
|
// 读取文件地理信息
|
|
|
GDALAllRegister();
|
|
|
CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO");
|
|
|
|
|
|
GDALDataset* tempdata = nullptr;
|
|
|
tempdata = ( GDALDataset* )GDALOpen((LPSTR)(LPCTSTR)ImgFilePath, GA_ReadOnly);
|
|
|
|
|
|
double GISDATA[6] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
|
|
|
|
|
|
if (tempdata != NULL)
|
|
|
{
|
|
|
tempdata->GetGeoTransform(GISDATA);
|
|
|
|
|
|
// 获取尺寸
|
|
|
int width = tempdata->GetRasterXSize();
|
|
|
int height = tempdata->GetRasterYSize();
|
|
|
|
|
|
double WLon = GISDATA[0];
|
|
|
double ELon = GISDATA[0] + width * GISDATA[1];
|
|
|
double NLat = GISDATA[3];
|
|
|
double SLat = GISDATA[3] + height * GISDATA[5];
|
|
|
|
|
|
GeoBoundingBox LBbox;
|
|
|
LBbox.WestLon = WLon;
|
|
|
LBbox.EastLon = ELon;
|
|
|
LBbox.SouthLat = SLat;
|
|
|
LBbox.NorthLat = NLat;
|
|
|
|
|
|
LoadOneImgFromMenu(&info, img.data, LBbox);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
LoadOneImgFromMenu(&info, img.data);
|
|
|
}
|
|
|
|
|
|
GDALClose( tempdata );
|
|
|
tempdata = NULL;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
LoadOneImgFromMenu(&info, img.data);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.what();
|
|
|
|
|
|
::MessageBoxA(NULL, _T("图像过大,缩放显示!"),_T("操作提示"), MB_OK);
|
|
|
|
|
|
// 启动GDAL数据加载线程
|
|
|
AfxBeginThread(LoadImgThroughGDAL, this);
|
|
|
}
|
|
|
catch(...)
|
|
|
{
|
|
|
}
|
|
|
}
|
|
|
|
|
|
|
|
|
void CImgShowDlg::LoadOneImgFromMenu(const BITMAPINFO* pImgInfo,
|
|
|
BYTE* pImgData,
|
|
|
GeoBoundingBox LBbox,
|
|
|
BOOL isNeedFlip,
|
|
|
BOOL isNeedClip,
|
|
|
const CRect* pShowRegion,
|
|
|
float Strecth_Ratio,
|
|
|
POINT xyShift)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
// 数据有效性验证
|
|
|
if ( (pImgInfo == NULL) || (pImgData == NULL))
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// 设置一路输入正在输入标识
|
|
|
SetFirstSignal(TRUE);
|
|
|
|
|
|
// biBitCount 验证
|
|
|
if(pImgInfo->bmiHeader.biBitCount != 24 && pImgInfo->bmiHeader.biBitCount != 8)
|
|
|
{
|
|
|
SetFirstSignal(FALSE);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// 更新数据至全局变量:LatestQBData
|
|
|
if (pImgInfo->bmiHeader.biWidth > 0 &&
|
|
|
pImgInfo->bmiHeader.biHeight > 0 &&
|
|
|
pImgData != NULL)
|
|
|
{
|
|
|
// 设置一路输入正在输入标识
|
|
|
SetFirstSignal(TRUE);
|
|
|
|
|
|
// 构建临时对象
|
|
|
QBStru local;
|
|
|
local.image.srcImg.ImgWidth = pImgInfo->bmiHeader.biWidth;
|
|
|
local.image.srcImg.ImgHeight = pImgInfo->bmiHeader.biHeight;
|
|
|
local.image.srcImg.bitcount = pImgInfo->bmiHeader.biBitCount;
|
|
|
|
|
|
// 步长:每行像素所占字节数
|
|
|
int lineByte = (pImgInfo->bmiHeader.biWidth * pImgInfo->bmiHeader.biBitCount / 8);
|
|
|
|
|
|
// 位图数据缓冲区的大小,即图像大小
|
|
|
int imgBufSize = pImgInfo->bmiHeader.biHeight * lineByte;
|
|
|
|
|
|
if ( imgBufSize > 0)
|
|
|
{
|
|
|
local.image.srcImg.buff = new BYTE[imgBufSize];
|
|
|
|
|
|
if (local.image.srcImg.buff != NULL)
|
|
|
{
|
|
|
// 复制实际字节数
|
|
|
memcpy(local.image.srcImg.buff, pImgData, static_cast<size_t>(imgBufSize)); // 图像数据复制
|
|
|
|
|
|
// 设置图像数据有效
|
|
|
local.image.bValid = true;
|
|
|
|
|
|
// 是否需要反转
|
|
|
if (isNeedFlip == TRUE)
|
|
|
{
|
|
|
FlipImgStru(&local.image.srcImg);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
local.image.srcImg.BoundingBox = LBbox;
|
|
|
|
|
|
/*m_boundbingBox = LBbox;*/
|
|
|
|
|
|
// 将 local 复制到 m_LatestQBData
|
|
|
SetLatestQBData(local);
|
|
|
|
|
|
SetBoundingBox(LBbox);
|
|
|
|
|
|
// 释放 local
|
|
|
if (local.image.srcImg.buff != NULL)
|
|
|
{
|
|
|
SAFE_DELETE_ARRAY(local.image.srcImg.buff);
|
|
|
}
|
|
|
|
|
|
|
|
|
// 显示图像
|
|
|
// 接口转换
|
|
|
CRect ShowRegion;
|
|
|
|
|
|
if (pShowRegion != NULL)
|
|
|
{
|
|
|
ShowRegion = *pShowRegion;
|
|
|
}
|
|
|
|
|
|
ShowOneImage(const_cast<BITMAPINFO*>(pImgInfo), pImgData, isNeedClip, ShowRegion, isNeedFlip, Strecth_Ratio, xyShift);
|
|
|
|
|
|
// 图像去雾 亮度调节 对比度调节 清晰度调节 复位
|
|
|
SetiLatest(0); // 最近的一次
|
|
|
SetiPreLatest(0); // 最近的一次的前一次
|
|
|
|
|
|
// 关闭1路正在输入标识
|
|
|
SetFirstSignal(FALSE);
|
|
|
}
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.msg;
|
|
|
return;
|
|
|
}
|
|
|
catch(...)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 单点定位校准
|
|
|
void CImgShowDlg::OnTgtloccalibrate()
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
CTgtLocCalibrateDlg TLCdlg;
|
|
|
if (TLCdlg.DoModal() == IDOK)
|
|
|
{
|
|
|
// 获取校准值
|
|
|
double calibrateLon = TLCdlg.GetCalibrateLon();
|
|
|
double calibrateLat = TLCdlg.GetCalibrateLat();
|
|
|
|
|
|
if (abs(calibrateLon) > 180 || abs(calibrateLat) > 90)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// 取消校准
|
|
|
if (abs(calibrateLon) + abs(calibrateLat) < 1e-5)
|
|
|
{
|
|
|
m_deltaLon = 0;
|
|
|
m_deltaLat = 0;
|
|
|
}
|
|
|
|
|
|
// 获取校准前的值
|
|
|
|
|
|
// 经纬度坐标
|
|
|
double Lon = -200;
|
|
|
double Lat = -200;
|
|
|
double H = 0;
|
|
|
|
|
|
// 右键坐标
|
|
|
CPoint point;
|
|
|
point.x = m_RButtonPt.x;
|
|
|
point.y = m_RButtonPt.y;
|
|
|
|
|
|
if (m_bFirstSignal == TRUE || m_bSecondSignal == TRUE)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (m_SrcFrame != NULL)
|
|
|
{
|
|
|
// 计算 CPoint point 对应的像素坐标 CPoint LButtonDblClkPixelCoordinate;
|
|
|
if ((point.x > m_ShowRegionOnScreen.left) && (point.x < m_ShowRegionOnScreen.right) &&
|
|
|
(point.y > m_ShowRegionOnScreen.top) && (point.y < m_ShowRegionOnScreen.bottom)) // 鼠标在图像上
|
|
|
{
|
|
|
// 图像尺寸与显示区域尺寸之间的比例
|
|
|
double ratio = 1.0;
|
|
|
|
|
|
// 分母0值判断
|
|
|
if (m_ShowRegionOnScreen.Width() > 0)
|
|
|
{
|
|
|
ratio = (m_ShowRegion.Width() * 1.0) / m_ShowRegionOnScreen.Width();
|
|
|
}
|
|
|
|
|
|
CPoint PixelCoordinate; // 像素坐标
|
|
|
PixelCoordinate.x = static_cast<LONG>((point.x - m_ShowRegionOnScreen.left) * ratio) + m_ShowRegion.left;
|
|
|
PixelCoordinate.y = static_cast<LONG>((point.y - m_ShowRegionOnScreen.top) * ratio) + m_ShowRegion.top;
|
|
|
|
|
|
if (false == DoCalAnyPtCoordinate(Lon, Lat, H, &m_LatestQBData.framePart, PixelCoordinate.x, PixelCoordinate.y))
|
|
|
{
|
|
|
if (m_boundbingBox.EastLon - m_boundbingBox.WestLon > 0
|
|
|
&& m_boundbingBox.WestLon >= -180
|
|
|
&& m_boundbingBox.WestLon <= 180
|
|
|
&& m_boundbingBox.EastLon >= -180
|
|
|
&& m_boundbingBox.EastLon <= 180
|
|
|
&& m_boundbingBox.NorthLat - m_boundbingBox.SouthLat > 0
|
|
|
&& m_boundbingBox.SouthLat >= -90
|
|
|
&& m_boundbingBox.SouthLat <= 90
|
|
|
&& m_boundbingBox.NorthLat >= -90
|
|
|
&& m_boundbingBox.NorthLat <= 90)
|
|
|
{
|
|
|
double LonResolution = (m_boundbingBox.EastLon - m_boundbingBox.WestLon) / m_SrcFrame->width;
|
|
|
double LatResolution = (m_boundbingBox.NorthLat - m_boundbingBox.SouthLat) / m_SrcFrame->height;
|
|
|
|
|
|
Lon = float(m_boundbingBox.WestLon + PixelCoordinate.x * LonResolution);
|
|
|
Lat = float(m_boundbingBox.NorthLat - PixelCoordinate.y * LatResolution);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// 计算修正量
|
|
|
double deltaLon = calibrateLon - Lon;
|
|
|
double deltaLat = calibrateLat - Lat;
|
|
|
|
|
|
if (abs(deltaLon) > 1 || abs(deltaLat) > 1)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
m_deltaLon = deltaLon;
|
|
|
m_deltaLat = deltaLat;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.msg;
|
|
|
return;
|
|
|
}
|
|
|
catch(...)
|
|
|
{
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 查看 经纬度校准量
|
|
|
void CImgShowDlg::OnViewDeltaLonLat()
|
|
|
{
|
|
|
// TODO: 在此添加命令处理程序代码
|
|
|
CString sDeltaLon;
|
|
|
sDeltaLon.Format("%.6f", m_deltaLon);
|
|
|
CString sDeltaLat;
|
|
|
sDeltaLat.Format("%.6f", m_deltaLat);
|
|
|
|
|
|
CString msg = "delatLon = " + sDeltaLon + "\n" + "deltaLat = " + sDeltaLat;
|
|
|
|
|
|
::MessageBoxA(NULL, _T(msg), _T("操作提示"), MB_OK);
|
|
|
}
|
|
|
|
|
|
|
|
|
// 22 功能:获取当前显示图像
|
|
|
cv::Mat CImgShowDlg::GetCurrentImg()
|
|
|
{
|
|
|
cv::Mat img;
|
|
|
|
|
|
if (m_SrcFrame != NULL)
|
|
|
{
|
|
|
img = cv::Mat(m_SrcFrame, true);
|
|
|
}
|
|
|
|
|
|
return img;
|
|
|
}
|
|
|
|
|
|
|
|
|
// 24 功能:标注图像(矩形、区域边缘)
|
|
|
// 输入:
|
|
|
// 1. 区域边缘点 集合
|
|
|
void CImgShowDlg::MarkRegionOnImg(std::vector<std::vector<cv::Point>> &valisContours)
|
|
|
{
|
|
|
try
|
|
|
{
|
|
|
if (valisContours.size() > 0)
|
|
|
{
|
|
|
if (m_SrcFrame != NULL && m_SrcFrame->width > 0 && m_SrcFrame->height > 0)
|
|
|
{
|
|
|
cv::Mat img(m_SrcFrame, false);
|
|
|
|
|
|
for (size_t i = 0; i < valisContours.size(); i++)
|
|
|
{
|
|
|
cv::Rect rect = cv::boundingRect(valisContours[i]);
|
|
|
cv::rectangle(img, rect, cv::Scalar(0,255,255), 2);
|
|
|
}
|
|
|
cv::drawContours(img, valisContours, -1, cv::Scalar(0,255,255), 1);
|
|
|
|
|
|
// m_midImg
|
|
|
if (m_LatestQBData.image.dstImg.buff != NULL)
|
|
|
{
|
|
|
memcpy(m_LatestQBData.image.dstImg.buff, img.data, img.cols * img.rows * img.channels());
|
|
|
}
|
|
|
|
|
|
if (m_LatestQBData.image.srcImg.buff != NULL)
|
|
|
{
|
|
|
memcpy(m_LatestQBData.image.srcImg.buff, img.data, img.cols * img.rows * img.channels());
|
|
|
}
|
|
|
|
|
|
ShowLatestQBData();
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
catch(cv::Exception &e)
|
|
|
{
|
|
|
e.what();
|
|
|
}
|
|
|
catch (...)
|
|
|
{
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 功能:屏蔽右键按钮菜单
|
|
|
void CImgShowDlg::CloseRightBtnDownMenu(bool bClose)
|
|
|
{
|
|
|
m_bCloseRughtBtnMenu = bClose;
|
|
|
}
|
|
|
|
|
|
// 功能:设置空屏文字
|
|
|
void CImgShowDlg::SetThemeText(CString str)
|
|
|
{
|
|
|
m_sThemeText = str;
|
|
|
}
|
|
|
|
|
|
void CImgShowDlg::OnGetTargetImg()
|
|
|
{
|
|
|
if (m_bClipImgOn == true)
|
|
|
{
|
|
|
m_bGetTgtImgOn = false;
|
|
|
m_haveValidFirstPt = false;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
m_bGetTgtImgOn = !m_bGetTgtImgOn;
|
|
|
|
|
|
if (m_bGetTgtImgOn == false)
|
|
|
{
|
|
|
m_haveValidFirstPt = false;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 功能:获取图像边界地理坐标
|
|
|
bool CImgShowDlg::GetImgBoundingBox(double &leftLon, double &topLat, double &rigtLon, double &bottomLat)
|
|
|
{
|
|
|
double leftLon0 = m_LatestQBData.image.srcImg.BoundingBox.WestLon;
|
|
|
double rigtLon0 = m_LatestQBData.image.srcImg.BoundingBox.EastLon;
|
|
|
double topLat0 = m_LatestQBData.image.srcImg.BoundingBox.NorthLat;
|
|
|
double bottomLat0 = m_LatestQBData.image.srcImg.BoundingBox.SouthLat;
|
|
|
|
|
|
if (abs(leftLon0) <= 180 && abs(rigtLon0) <= 180 && leftLon0 < rigtLon0 &&
|
|
|
abs(topLat0) <= 90 && abs(bottomLat0) <= 90 && bottomLat0 < topLat0)
|
|
|
{
|
|
|
leftLon = leftLon0;
|
|
|
rigtLon = rigtLon0;
|
|
|
topLat = topLat0;
|
|
|
bottomLat = bottomLat0;
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void CImgShowDlg::OnClipImg()
|
|
|
{
|
|
|
m_bClipImgOn = !m_bClipImgOn;
|
|
|
|
|
|
if (m_bClipImgOn == true)
|
|
|
{
|
|
|
m_bGetTgtImgOn = false;
|
|
|
}
|
|
|
|
|
|
m_haveValidFirstPt = false;
|
|
|
}
|
|
|
|
|
|
|