diff --git a/fast/DrawImage.h b/fast/DrawImage.h new file mode 100644 index 0000000..fcad5e8 --- /dev/null +++ b/fast/DrawImage.h @@ -0,0 +1,60 @@ +#pragma once + +class CDrawImg +{ +public: + CDrawImg(HWND wnd) + { + m_hbrush = CreateSolidBrush(RGB(0, 0, 0)); + pBmpInfo = (BITMAPINFO *)chBmpBuf; + pBmpInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + pBmpInfo->bmiHeader.biPlanes = 1; + pBmpInfo->bmiHeader.biCompression = BI_RGB; + for (int i = 0; i < 256; i++) + { + pBmpInfo->bmiColors[i].rgbBlue = i; + pBmpInfo->bmiColors[i].rgbGreen = i; + pBmpInfo->bmiColors[i].rgbRed = i; + pBmpInfo->bmiColors[i].rgbReserved = i; + } + GetClientRect(wnd, wrect); + hdc = GetDC(wnd); + } + void Draw(int width, int height, int channels, uchar* data) + { + pBmpInfo->bmiHeader.biWidth = width; + pBmpInfo->bmiHeader.biHeight = height; + pBmpInfo->bmiHeader.biBitCount = 8 * channels; + + FillRect(hdc, wrect, m_hbrush); + int DesX = 0; + int DesY = wrect.Height(); + int DesWidth = wrect.Width(); + int DesHeight = wrect.Height(); + double ratio = width / (double)height; + int WidthRequest = ratio * wrect.Height(); + int HeightRequest = wrect.Width() / ratio; + if (wrect.Width() < WidthRequest) + { + DesHeight = DesWidth / ratio; + DesY = (wrect.Height() - DesHeight) / 2 + DesHeight; + } + else if (wrect.Height() < HeightRequest) + { + DesWidth = DesHeight * ratio; + DesX = (wrect.Width() - DesWidth) / 2; + } + ::SetStretchBltMode(hdc, COLORONCOLOR); + ::StretchDIBits(hdc, + DesX, DesY, DesWidth, -DesHeight, + 0, 0, width, height, + data, pBmpInfo, + DIB_RGB_COLORS, SRCCOPY); + } +private: + char chBmpBuf[2048]; + BITMAPINFO *pBmpInfo; + CRect wrect; + HDC hdc; + HBRUSH m_hbrush; +}; diff --git a/fast/Fast.cpp b/fast/Fast.cpp index fb1114a..7cd8ffa 100644 --- a/fast/Fast.cpp +++ b/fast/Fast.cpp @@ -33,7 +33,7 @@ CFastApp::CFastApp() // TODO: 将以下应用程序 ID 字符串替换为唯一的 ID 字符串;建议的字符串格式 //为 CompanyName.ProductName.SubProduct.VersionInformation SetAppID(_T("MFCApplication6.AppID.NoVersion")); - + m_bCalibrator = FALSE; // TODO: 在此处添加构造代码, // 将所有重要的初始化放置在 InitInstance 中 } @@ -41,7 +41,6 @@ CFastApp::CFastApp() // 唯一的一个 CMFCApplication6App 对象 CFastApp theApp; -CPlayAPI g_PlayAPI; // CMFCApplication6App 初始化 @@ -64,7 +63,6 @@ BOOL CFastApp::InitInstance() m_strModulePath = path; - g_PlayAPI.LoadPlayDll(); // 初始化 OLE 库 if (!AfxOleInit()) diff --git a/fast/Fast.h b/fast/Fast.h index a26e545..5f4fa50 100644 --- a/fast/Fast.h +++ b/fast/Fast.h @@ -9,6 +9,7 @@ #include "resource.h" // 主符号 #include "PlayApi.h" +#include "PtzScreen.h" // CMFCApplication6App: // 有关此类的实现,请参阅 MFCApplication6.cpp @@ -20,7 +21,9 @@ public: CFastApp(); public: - CString m_strModulePath; + CString m_strModulePath; + BOOL m_bCalibrator; + // 重写 public: @@ -33,4 +36,3 @@ public: }; extern CFastApp theApp; -extern CPlayAPI g_PlayAPI; diff --git a/fast/Fast.rc b/fast/Fast.rc index 84dda0c..ae9e703 100644 --- a/fast/Fast.rc +++ b/fast/Fast.rc @@ -1,11 +1,11 @@ -//Microsoft Visual C++ 生成的资源脚本。 +// Microsoft Visual C++ generated resource script. // #include "resource.h" #define APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // -// 从 TEXTINCLUDE 2 资源生成。 +// Generated from the TEXTINCLUDE 2 resource. // #ifndef APSTUDIO_INVOKED #include "targetver.h" @@ -16,19 +16,25 @@ ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS -#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// 中文(简体,中国) resources +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS) +LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED +#pragma code_page(936) + +#ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // TEXTINCLUDE // -1 TEXTINCLUDE +1 TEXTINCLUDE BEGIN "resource.h\0" END -2 TEXTINCLUDE +2 TEXTINCLUDE BEGIN "#ifndef APSTUDIO_INVOKED\r\n" "#include ""targetver.h""\r\n" @@ -38,7 +44,7 @@ BEGIN "\0" END -3 TEXTINCLUDE +3 TEXTINCLUDE BEGIN "#define _AFX_NO_OLE_RESOURCES\r\n" "#define _AFX_NO_TRACKER_RESOURCES\r\n" @@ -57,92 +63,87 @@ END ///////////////////////////////////////////////////////////////////////////// // -// 图标 +// Icon // -// ID 值最低的图标放在最前面,以确保应用程序图标 -// 在所有系统中保持一致。 +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDR_MAINFRAME ICON "res\\Fast.ico" + +IDR_MFCApplication6TYPE ICON "res\\FastMainDoc.ico" -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS) -LANGUAGE 4, 2 -IDR_MAINFRAME ICON "res\\Fast.ico" -IDR_MFCApplication6TYPE ICON "res\\FastMainDoc.ico" -#endif -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS) -LANGUAGE 4, 2 ///////////////////////////////////////////////////////////////////////////// // -// 菜单 +// Menu // IDR_MAINFRAME MENU BEGIN POPUP "文件(&F)" BEGIN - MENUITEM "新建(&N)\tCtrl+N", ID_FILE_NEW - MENUITEM "打开(&O)...\tCtrl+O", ID_FILE_OPEN - MENUITEM "保存(&S)\tCtrl+S", ID_FILE_SAVE - MENUITEM "另存为(&A)...", ID_FILE_SAVE_AS + MENUITEM "新建(&N)\tCtrl+N", ID_FILE_NEW + MENUITEM "打开(&O)...\tCtrl+O", ID_FILE_OPEN + MENUITEM "保存(&S)\tCtrl+S", ID_FILE_SAVE + MENUITEM "另存为(&A)...", ID_FILE_SAVE_AS MENUITEM SEPARATOR - MENUITEM "最近的文件", ID_FILE_MRU_FILE1,GRAYED + MENUITEM "鱼眼", ID_FISHEYE + MENUITEM "展平", ID_CALIBRATOR + MENUITEM "最近的文件", ID_FILE_MRU_FILE1, GRAYED MENUITEM SEPARATOR - MENUITEM "退出(&X)", ID_APP_EXIT + MENUITEM "退出(&X)", ID_APP_EXIT END POPUP "编辑(&E)" BEGIN - MENUITEM "撤消(&U)\tCtrl+Z", ID_EDIT_UNDO + MENUITEM "撤消(&U)\tCtrl+Z", ID_EDIT_UNDO MENUITEM SEPARATOR - MENUITEM "剪切(&T)\tCtrl+X", ID_EDIT_CUT - MENUITEM "复制(&C)\tCtrl+C", ID_EDIT_COPY + MENUITEM "剪切(&T)\tCtrl+X", ID_EDIT_CUT + MENUITEM "复制(&C)\tCtrl+C", ID_EDIT_COPY MENUITEM "粘贴(&P)\tCtrl+V", ID_EDIT_PASTE END POPUP "视图(&V)" BEGIN - MENUITEM "状态栏(&S)", ID_VIEW_STATUS_BAR + MENUITEM "状态栏(&S)", ID_VIEW_STATUS_BAR END POPUP "帮助(&H)" BEGIN - MENUITEM "关于 FastApp(&A)...", ID_APP_ABOUT + MENUITEM "关于 FastApp(&A)...", ID_APP_ABOUT END END - ///////////////////////////////////////////////////////////////////////////// // -// 加速器 +// Accelerator // IDR_MAINFRAME ACCELERATORS BEGIN - "N", ID_FILE_NEW, VIRTKEY,CONTROL - "O", ID_FILE_OPEN, VIRTKEY,CONTROL - "S", ID_FILE_SAVE, VIRTKEY,CONTROL - "Z", ID_EDIT_UNDO, VIRTKEY,CONTROL - "X", ID_EDIT_CUT, VIRTKEY,CONTROL - "C", ID_EDIT_COPY, VIRTKEY,CONTROL - "V", ID_EDIT_PASTE, VIRTKEY,CONTROL - VK_BACK, ID_EDIT_UNDO, VIRTKEY,ALT - VK_DELETE, ID_EDIT_CUT, VIRTKEY,SHIFT - VK_INSERT, ID_EDIT_COPY, VIRTKEY,CONTROL - VK_INSERT, ID_EDIT_PASTE, VIRTKEY,SHIFT - VK_F6, ID_NEXT_PANE, VIRTKEY - VK_F6, ID_PREV_PANE, VIRTKEY,SHIFT + "N", ID_FILE_NEW, VIRTKEY, CONTROL + "O", ID_FILE_OPEN, VIRTKEY, CONTROL + "S", ID_FILE_SAVE, VIRTKEY, CONTROL + "Z", ID_EDIT_UNDO, VIRTKEY, CONTROL + "X", ID_EDIT_CUT, VIRTKEY, CONTROL + "C", ID_EDIT_COPY, VIRTKEY, CONTROL + "V", ID_EDIT_PASTE, VIRTKEY, CONTROL + VK_BACK, ID_EDIT_UNDO, VIRTKEY, ALT + VK_DELETE, ID_EDIT_CUT, VIRTKEY, SHIFT + VK_INSERT, ID_EDIT_COPY, VIRTKEY, CONTROL + VK_INSERT, ID_EDIT_PASTE, VIRTKEY, SHIFT + VK_F6, ID_NEXT_PANE, VIRTKEY + VK_F6, ID_PREV_PANE, VIRTKEY, SHIFT END - - ///////////////////////////////////////////////////////////////////////////// // -// 对话框 +// Dialog // IDD_ABOUTBOX DIALOGEX 0, 0, 170, 62 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "关于 MFCApplication6" -FONT 9, "MS Shell Dlg" +FONT 9, "MS Shell Dlg", 0, 0, 0x1 BEGIN ICON IDR_MAINFRAME,IDC_STATIC,14,14,21,20 LTEXT "MFCApplication6,1.0 版",IDC_STATIC,42,14,114,8,SS_NOPREFIX @@ -150,32 +151,31 @@ BEGIN DEFPUSHBUTTON "确定",IDOK,113,41,50,14,WS_GROUP END -IDD_MFCAPPLICATION6_FORM DIALOGEX 0, 0, 320, 200 -STYLE DS_SHELLFONT | WS_CHILD -FONT 9, "MS Shell Dlg" +IDD_MFCAPPLICATION6_FORM DIALOGEX 0, 0, 320, 200 +STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD +FONT 9, "MS Shell Dlg", 0, 0, 0x1 BEGIN - LTEXT "TODO: 将窗体控件放置在此对话框上。",IDC_STATIC,24,42, - 280,8 + LTEXT "TODO: 将窗体控件放置在此对话框上。",IDC_STATIC,24,42,280,8 END ///////////////////////////////////////////////////////////////////////////// // -// 版本 +// Version // -VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,0,0,1 - PRODUCTVERSION 1,0,0,1 - FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,1 + PRODUCTVERSION 1,0,0,1 + FILEFLAGSMASK 0x3fL #ifdef _DEBUG - FILEFLAGS VS_FF_DEBUG + FILEFLAGS 0x1L #else FILEFLAGS 0x0L #endif - FILEOS VOS_NT_WINDOWS32 - FILETYPE VFT_APP - FILESUBTYPE VFT2_UNKNOWN + FILEOS 0x40004L + FILETYPE 0x1L + FILESUBTYPE 0x0L BEGIN BLOCK "StringFileInfo" BEGIN @@ -183,20 +183,21 @@ BEGIN BEGIN VALUE "CompanyName", "TODO: <公司名>" VALUE "FileDescription", "MFCApplication6" - VALUE "FileVersion", "1.0.0.1" - VALUE "InternalName", "MFCApplication6.exe" + VALUE "FileVersion", "1.0.0.1" + VALUE "InternalName", "MFCApplication6.exe" VALUE "LegalCopyright", "TODO: (C) <公司名>。 保留所有权利。" - VALUE "OriginalFilename","MFCApplication6.exe" + VALUE "OriginalFilename", "MFCApplication6.exe" VALUE "ProductName", "TODO: <产品名>" - VALUE "ProductVersion", "1.0.0.1" + VALUE "ProductVersion", "1.0.0.1" END END BLOCK "VarFileInfo" BEGIN - VALUE "Translation", 0x0804, 1200 + VALUE "Translation", 0x804, 1200 END END + ///////////////////////////////////////////////////////////////////////////// // // DESIGNINFO @@ -212,6 +213,7 @@ BEGIN TOPMARGIN, 7 BOTTOMMARGIN, 55 END + IDD_MFCAPPLICATION6_FORM, DIALOG BEGIN LEFTMARGIN, 7 @@ -222,26 +224,28 @@ BEGIN END #endif // APSTUDIO_INVOKED + ///////////////////////////////////////////////////////////////////////////// // -// 字符串表 +// String Table // STRINGTABLE BEGIN - IDP_OLE_INIT_FAILED "OLE 初始化失败。 请确保 OLE 库是正确的版本。" + IDP_OLE_INIT_FAILED "OLE 初始化失败。 请确保 OLE 库是正确的版本。" END + STRINGTABLE BEGIN -// 非 Mac 应用程序将移除额外的两个子字符串 IDR_MAINFRAME "MFCApplication6\n\nMFCApplication6\n\n\nMFCApplication6.Document\nMFCApplication6.Document" - END + STRINGTABLE BEGIN AFX_IDS_APP_TITLE "MFCApplication6" AFX_IDS_IDLEMESSAGE "就绪" END + STRINGTABLE BEGIN ID_INDICATOR_EXT "EXT" @@ -251,6 +255,7 @@ BEGIN ID_INDICATOR_OVR "OVR" ID_INDICATOR_REC "REC" END + STRINGTABLE BEGIN ID_FILE_NEW "创建新文档\n新建" @@ -258,8 +263,16 @@ BEGIN ID_FILE_CLOSE "关闭活动文档\n关闭" ID_FILE_SAVE "保存活动文档\n保存" ID_FILE_SAVE_AS "用新名称保存活动文档\n另存为" +END + +STRINGTABLE +BEGIN ID_APP_ABOUT "显示程序信息、版本号和版权信息\n关于" ID_APP_EXIT "退出应用程序;提示保存文档\n退出" +END + +STRINGTABLE +BEGIN ID_FILE_MRU_FILE1 "打开此文档" ID_FILE_MRU_FILE2 "打开此文档" ID_FILE_MRU_FILE3 "打开此文档" @@ -276,9 +289,21 @@ BEGIN ID_FILE_MRU_FILE14 "打开此文档" ID_FILE_MRU_FILE15 "打开此文档" ID_FILE_MRU_FILE16 "打开此文档" +END + +STRINGTABLE +BEGIN ID_NEXT_PANE "切换到下一个窗格\n下一窗格" ID_PREV_PANE "切换回上一个窗格\n上一窗格" +END + +STRINGTABLE +BEGIN ID_WINDOW_SPLIT "将活动窗口拆分为多个窗格\n拆分" +END + +STRINGTABLE +BEGIN ID_EDIT_CLEAR "清除所选内容\n清除" ID_EDIT_CLEAR_ALL "清除全部内容\n全部清除" ID_EDIT_COPY "复制所选内容,将其放入剪贴板\n复制" @@ -290,6 +315,10 @@ BEGIN ID_EDIT_SELECT_ALL "选定整个文档\n全选" ID_EDIT_UNDO "撤消上一操作\n撤消" ID_EDIT_REDO "重做上次撤消的操作\n重做" +END + +STRINGTABLE +BEGIN ID_VIEW_STATUS_BAR "显示或隐藏状态栏\n切换状态栏" END @@ -302,26 +331,34 @@ BEGIN AFX_IDS_SCNEXTWINDOW "切换到下一个文档窗口" AFX_IDS_SCPREVWINDOW "切换到上一个文档窗口" AFX_IDS_SCCLOSE "关闭活动窗口并提示保存文档" +END + +STRINGTABLE +BEGIN AFX_IDS_SCRESTORE "将窗口恢复到正常大小" AFX_IDS_SCTASKLIST "激活任务列表" END +#endif // 中文(简体,中国) resources +///////////////////////////////////////////////////////////////////////////// + -#endif #ifndef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // -// 从 TEXTINCLUDE 3 资源生成。 +// Generated from the TEXTINCLUDE 3 resource. // - #define _AFX_NO_OLE_RESOURCES #define _AFX_NO_TRACKER_RESOURCES #define _AFX_NO_PROPERTY_RESOURCES #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS) LANGUAGE 4, 2 -#include "res\\Fast.rc2" // 非 Microsoft Visual C++ 编辑的资源 -#include "l.CHS\\afxres.rc" // 标准组件 +#include "res\Fast.rc2" // 非 Microsoft Visual C++ 编辑的资源 +#include "l.CHS\afxres.rc" // 标准组件 #endif -#endif // 不是 APSTUDIO_INVOKED + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/fast/Fast.vcxproj b/fast/Fast.vcxproj index a324a3f..b8104bf 100644 --- a/fast/Fast.vcxproj +++ b/fast/Fast.vcxproj @@ -21,7 +21,7 @@ {DF8ED0A5-CC46-45BF-A8A1-594F5F6EAB22} Fast - 10.0 + 8.1 MFCProj Fast @@ -29,14 +29,14 @@ Application true - v143 + v140 Unicode Dynamic Application false - v143 + v140 true Unicode Dynamic @@ -44,14 +44,14 @@ Application true - v143 + v140 MultiByte Dynamic Application false - v143 + v140 true MultiByte Dynamic @@ -118,7 +118,7 @@ Windows $(SolutionDir)\3rdparty\dahua\lib\win64;$(SolutionDir)\3rdparty\opencv\lib - dhnetsdk.lib;dhconfigsdk.lib;dhplay.lib;opencv_core454d.lib;opencv_dnn454d.lib;opencv_features2d454d.lib;opencv_flann454d.lib;opencv_highgui454d.lib;opencv_imgcodecs454d.lib;opencv_imgproc454d.lib;opencv_ml454d.lib;opencv_video454d.lib;opencv_videoio454d.lib;opencv_face454d.lib;opencv_objdetect454d.lib;opencv_photo454d.lib + dhnetsdk.lib;dhconfigsdk.lib;dhplay.lib;opencv_core454d.lib;opencv_dnn454d.lib;opencv_features2d454d.lib;opencv_flann454d.lib;opencv_highgui454d.lib;opencv_imgcodecs454d.lib;opencv_imgproc454d.lib;opencv_ml454d.lib;opencv_video454d.lib;opencv_videoio454d.lib;opencv_face454d.lib;opencv_objdetect454d.lib;opencv_photo454d.lib;opencv_calib3d454d.lib false @@ -171,7 +171,7 @@ true true $(SolutionDir)\3rdparty\dahua\lib\win64;$(SolutionDir)\3rdparty\opencv\lib - dhnetsdk.lib;dhconfigsdk.lib;dhplay.lib;opencv_core454.lib;opencv_dnn454.lib;opencv_features2d454.lib;opencv_flann454.lib;opencv_highgui454.lib;opencv_imgcodecs454.lib;opencv_imgproc454.lib;opencv_ml454.lib;opencv_video454.lib;opencv_videoio454.lib;opencv_face454.lib;opencv_objdetect454.lib;opencv_photo454.lib + dhnetsdk.lib;dhconfigsdk.lib;opencv_calib3d454.lib;dhplay.lib;opencv_core454.lib;opencv_dnn454.lib;opencv_features2d454.lib;opencv_flann454.lib;opencv_highgui454.lib;opencv_imgcodecs454.lib;opencv_imgproc454.lib;opencv_ml454.lib;opencv_video454.lib;opencv_videoio454.lib;opencv_face454.lib;opencv_objdetect454.lib;opencv_photo454.lib false @@ -193,6 +193,7 @@ + @@ -206,6 +207,7 @@ + diff --git a/fast/Fast.vcxproj.filters b/fast/Fast.vcxproj.filters index efbba43..2b3bb50 100644 --- a/fast/Fast.vcxproj.filters +++ b/fast/Fast.vcxproj.filters @@ -51,6 +51,9 @@ 澶存枃浠 + + 澶存枃浠 + @@ -80,6 +83,9 @@ 婧愭枃浠 + + 婧愭枃浠 + diff --git a/fast/FastMainFrm.cpp b/fast/FastMainFrm.cpp index 72dc388..1ac4ed1 100644 --- a/fast/FastMainFrm.cpp +++ b/fast/FastMainFrm.cpp @@ -17,6 +17,8 @@ IMPLEMENT_DYNCREATE(CFastMainFrame, CFrameWnd) BEGIN_MESSAGE_MAP(CFastMainFrame, CFrameWnd) ON_WM_CREATE() + ON_COMMAND(ID_CALIBRATOR, &CFastMainFrame::OnCalibrator) + ON_COMMAND(ID_FISHEYE, &CFastMainFrame::OnFisheye) END_MESSAGE_MAP() static UINT indicators[] = @@ -93,3 +95,17 @@ void CFastMainFrame::ActivateFrame(int nCmdShow) // TODO: 在此添加专用代码和/或调用基类 CFrameWnd::ActivateFrame(nCmdShow); } + + +void CFastMainFrame::OnCalibrator() +{ + // TODO: 在此添加命令处理程序代码 + theApp.m_bCalibrator = TRUE; +} + + +void CFastMainFrame::OnFisheye() +{ + // TODO: 在此添加命令处理程序代码 + theApp.m_bCalibrator = FALSE; +} diff --git a/fast/FastMainFrm.h b/fast/FastMainFrm.h index e42855c..6ea7260 100644 --- a/fast/FastMainFrm.h +++ b/fast/FastMainFrm.h @@ -39,6 +39,8 @@ protected: public: virtual void ActivateFrame(int nCmdShow = -1); + afx_msg void OnCalibrator(); + afx_msg void OnFisheye(); }; diff --git a/fast/FastMainView.h b/fast/FastMainView.h index 4ea1301..404dfe6 100644 --- a/fast/FastMainView.h +++ b/fast/FastMainView.h @@ -40,7 +40,7 @@ public: #endif public: - CPtzScreen m_ptzScreen; + CPtzScreen m_ptzScreen; CRect m_clientRect; protected: diff --git a/fast/ImageCalibrator.cpp b/fast/ImageCalibrator.cpp new file mode 100644 index 0000000..419cd2e --- /dev/null +++ b/fast/ImageCalibrator.cpp @@ -0,0 +1,48 @@ +#include "stdafx.h" +#include "ImageCalibrator.h" +#include +using namespace std; + +CImageCalibrator::CImageCalibrator() +{ +} + +CImageCalibrator::~CImageCalibrator() +{ +} + +cv::Mat CImageCalibrator::imageCalibration(cv::Mat inImg) +{ + + //相机内参矩阵与畸变系数,通过黑白棋盘格标定法测定得到 + cv::Mat cameraMatrix = (cv::Mat_ (3, 3) << 720.689879, 0, 957.57171, 0, 721.705519, 935.484724, 0, 0, 1), + distCoeffs = (cv::Mat_ (1, 4) << -0.0765657862, 0.0190079504, -0.032948619, 0.0159874152); //重投影误差rms:0.601462 + + //平移操作,修正鱼眼图像位置偏差,对照测定参数用相机采集的图片 + cv::Mat warp_matrix = (cv::Mat_(2, 3) << + cos(0), -sin(0), -63, //x轴平移像素 + sin(0), cos(0), -68); //y轴平移像素 + cv::warpAffine(inImg, inImg, warp_matrix, inImg.size(), cv::INTER_LINEAR); + + //取有效鱼眼镜头区域 + cv::Mat inImg2(inImg, cv::Rect(324, 0, 1944, 1944)); + //鱼眼画面展平 + cv::Mat outImg, new_intrinsic_mat; + cameraMatrix.copyTo(new_intrinsic_mat); + //调节视场大小,乘的系数越小视场越大,可调整 + new_intrinsic_mat.at(0, 0) *= 0.7; + new_intrinsic_mat.at(1, 1) *= 0.7; + //调节校正图中心,建议置于校正图中心 + new_intrinsic_mat.at(0, 2) = 0.5 * inImg2.cols; + new_intrinsic_mat.at(1, 2) = 0.5 * inImg2.rows; + cv::fisheye::undistortImage(inImg2, outImg, cameraMatrix, distCoeffs, new_intrinsic_mat); + + //展平后扣出有效分析区域 + //Mat roi(outImg, cv::Rect(711, 465, 557, 941)); + //显示展平后的图像 + //cv::imshow("标定效果", outImg); cv::waitKey(0); + + return outImg; + +} + diff --git a/fast/ImageCalibrator.h b/fast/ImageCalibrator.h new file mode 100644 index 0000000..83b68db --- /dev/null +++ b/fast/ImageCalibrator.h @@ -0,0 +1,9 @@ +#pragma once +class CImageCalibrator +{ +public: + CImageCalibrator(); + ~CImageCalibrator(); + static cv::Mat imageCalibration(cv::Mat inImg); +}; + diff --git a/fast/PlayWnd.cpp b/fast/PlayWnd.cpp index 8b103d2..0e93d21 100644 --- a/fast/PlayWnd.cpp +++ b/fast/PlayWnd.cpp @@ -2,6 +2,8 @@ #include "Fast.h" #include "PlayWnd.h" #include "PtzScreen.h" +#include "DrawImage.h" +#include "ImageCalibrator.h" #include "dhplay.h" //#include "RealPlayAndPTZControlDlg.h" @@ -12,6 +14,7 @@ static char THIS_FILE[] = __FILE__; #endif +#define LOGIN_TIMER 1 ///////////////////////////////////////////////////////////////////////////// // CPlayWnd dialog @@ -22,6 +25,9 @@ CPlayWnd::CPlayWnd():m_nWndID(0), m_FlagRect(FALSE),bIsPlaying(false) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT m_nIndex = 0; + m_nPlayPort = 0; + + //cv::namewindow("fsf"); } BEGIN_MESSAGE_MAP(CPlayWnd, CWnd) @@ -204,6 +210,13 @@ void CPlayWnd::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized) void CPlayWnd::OnTimer(UINT_PTR nIDEvent) { + switch (nIDEvent) + { + case 1: + m_llLoginId = Login(); + KillTimer(1); + break; + } CWnd::OnTimer(nIDEvent); } @@ -227,18 +240,30 @@ void CPlayWnd::ShowLoginErrorReason(int nError) else MessageBox(ConvertString("Login failed!"), ConvertString("Prompt")); } +// netsdk 实时回调函数 +void CALL_METHOD fRealDataCB(LLONG lRealHandle, DWORD dwDataType, BYTE *pBuffer, DWORD dwBufSize, LDWORD dwUser) +{ -LLONG CPlayWnd::Login(CString strIpAddr, int nPort, CString strUser, CString strPW) + CPlayWnd *pWnd = (CPlayWnd*)dwUser; + if (pWnd->m_lRealHandle != lRealHandle)return; + + // 把大华实时码流数据送到playsdk中 + PLAY_InputData(pWnd->m_nWndID, pBuffer, dwBufSize); + return; +} + + +LLONG CPlayWnd::Login() { //依次登录摄像机,获取登录ID - + //m_strCameraIp, m_nCameraPort, m_strUserName, m_strPassWord); char *pchDVRIP; //CString strDvrIP = GetDvrIP(); - pchDVRIP = (LPSTR)(LPCSTR)strIpAddr; - WORD wDVRPort = (WORD)nPort; - char *pchUserName = (LPSTR)(LPCSTR)strUser; - char *pchPassword = (LPSTR)(LPCSTR)strPW; - + pchDVRIP = (LPSTR)(LPCSTR)m_strCameraIp; + WORD wDVRPort = (WORD)m_nCameraPort; + char *pchUserName = (LPSTR)(LPCSTR)m_strUserName; + char *pchPassword = (LPSTR)(LPCSTR)m_strPassWord; +/* NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY stInparam; memset(&stInparam, 0, sizeof(stInparam)); stInparam.dwSize = sizeof(stInparam); @@ -274,7 +299,47 @@ LLONG CPlayWnd::Login(CString strIpAddr, int nPort, CString strUser, CString s } return lRet; } - //SetWindowText(ConvertString("CapturePicture")); + //SetWindowText(ConvertString("CapturePicture"));*/ + + PLAY_GetFreePort(&m_nWndID); + PLAY_SetStreamOpenMode(m_nWndID, STREAME_REALTIME); + PLAY_OpenStream(m_nWndID, NULL, 0, 1024 * 512 * 6); + //设置视频抓图回调函数 可以回调出YUV数据 + PLAY_SetDisplayCallBack(m_nWndID, fDisplayCB, this); + PLAY_Play(m_nWndID, NULL); + + + NET_DEVICEINFO_Ex stLoginInfo = { 0 }; + int nErrcode = 0; + + LLONG lLoginHandle = CLIENT_LoginEx2(pchDVRIP, m_nCameraPort, pchUserName, pchPassword, (EM_LOGIN_SPAC_CAP_TYPE)0, NULL, &stLoginInfo, &nErrcode); + if (0 == lLoginHandle) + { + //cout << "Login device failed" << endl; + //cin >> szIpAddr; + return -1; + } + else + { + //cout << "Login device success" << endl; + } + + //拉流 + m_lRealHandle = CLIENT_RealPlayEx(lLoginHandle, 0, 0); + + if (0 == m_lRealHandle) + { + //cout << "CLIENT_RealPlayEx fail!" << endl; + Sleep(100000); + return -1; + } + //cout << "CLIENT_RealPlayEx success!" << endl; + + //设置拉流回调 + CLIENT_SetRealDataCallBack(m_lRealHandle, fRealDataCB, (LDWORD)this); + + return lLoginHandle; + } @@ -288,78 +353,73 @@ int CPlayWnd::OnCreate(LPCREATESTRUCT lpCreateStruct) { return -1; } + SetTimer(1, 5000, NULL); - m_llLoginId = Login(m_strCameraIp, m_nCameraPort, m_strUserName, m_strPassWord); - ServerPlayMode(); return 0; } - -//Play video in data callback mode -void CPlayWnd::ServerPlayMode() +void CPlayWnd::StopPlayForServerMode() { - //Close current video - //CloseDispVideo(m_nWndID); - - int iChannel = 0; - - //Enable stream - BOOL bOpenRet = g_PlayAPI.PLAY_OpenStream(m_nWndID, 0, 0, 1024 * 512 * 6); - if (bOpenRet) +/* + BOOL bRealPlay = CLIENT_StopRealPlayEx(m_DispHanle); + if (bRealPlay) { - //Begin play - //设置视频抓图回调函数 可以回调出YUV数据 - PLAY_SetDisplayCallBack(m_nWndID, CPlayWnd::fDisplayCB, this); + this->SetWndPlaying(false); - BOOL bPlayRet = g_PlayAPI.PLAY_Play(m_nWndID, NULL); - if (bPlayRet) + //And then close PLAY_Play + BOOL bPlay = g_PlayAPI.PLAY_Stop(m_nWndID); + if (bPlay) { - //Real-time play - m_DispHanle = CLIENT_RealPlayEx(m_llLoginId, iChannel, 0); - if (0 != m_DispHanle) - { - //SetPlayVideoInfo(iDispNum, iChannel, ServerMode); - CLIENT_SetRealDataCallBackEx2(m_DispHanle, RealDataCallBackEx, (LDWORD)this, 0x0f); - - } - else - { - MessageBox(ConvertString("Fail to play!"), ConvertString("Prompt")); - g_PlayAPI.PLAY_Stop(m_nWndID); - g_PlayAPI.PLAY_CloseStream(m_nWndID); - } + //At last close PLAY_OpenStream + BOOL bStream = g_PlayAPI.PLAY_CloseStream(m_nWndID); } - else - { - g_PlayAPI.PLAY_CloseStream(m_nWndID); - } - } + }*/ } - // playsdk 回调 yuv数据 void CALL_METHOD CPlayWnd::fDisplayCB(LONG nPort, char * pBuf, LONG nSize, LONG nWidth, LONG nHeight, LONG nStamp, LONG nType, void* pReserved) { + CPlayWnd *pShowWnd = (CPlayWnd *)(pReserved); - CPlayWnd * pThis = (CPlayWnd *)pReserved; + if (pShowWnd->m_nWndID != nPort)return; + //TRACE("%d\n", pThis->m_nWndID); + //if (pThis->m_nWndID > 1)return; - pThis->m_nIndex++; - if (pThis->m_nIndex == 24) + pShowWnd->m_nIndex++; + if (pShowWnd->m_nIndex == 24) { - TRACE("%d\n", pThis->m_nWndID); + cv::Mat cv_img; cv::Mat cv_yuv(nHeight + nHeight / 2, nWidth, CV_8UC1, pBuf);//pFrame为YUV数据地址,另外这里就是用 CV_8UC1非 CV_8UC3. cv_img = cv::Mat(nHeight, nWidth, CV_8UC3); cv::cvtColor(cv_yuv, cv_img, cv::COLOR_YUV2BGR_I420); //cv::COLOR_YUV2BGR_I420 //cv::imshow("video", cv_img); - //cv::imwrite("d:\\1.jpg", cv_img); - pThis->m_nIndex = 0; - pThis->DrawMat(cv_img); - cv::waitKey(50); + + cv::Mat imgTmp; + + CRect rect; + pShowWnd->GetClientRect(&rect); // 获取控件大小 + int nWidth = cv_img.cols * rect.Height() *1.0 / cv_img.rows; + + if (rect.Width() == 0)return; + + + //鱼眼照片站展平 + if (theApp.m_bCalibrator) + { + cv_img = CImageCalibrator::imageCalibration(cv_img); + } + + cv::resize(cv_img, imgTmp, cv::Size(nWidth, rect.Height()));// 缩放Mat并备份 + + pShowWnd->m_nIndex = 0; + pShowWnd->DrawMat(imgTmp, (rect.Width() - nWidth) / 2); + cv::waitKey(10); + } return; @@ -368,15 +428,16 @@ void CALL_METHOD CPlayWnd::fDisplayCB(LONG nPort, char * pBuf, LONG nSize, LONG //参数1:opencv即将读的图, //参数2:需要展示的Picture Control的ID -void CPlayWnd::DrawMat(cv::Mat& img) +void CPlayWnd::DrawMat(cv::Mat& imageMat, int nOffset) { - cv::Mat imgTmp; + /*cv::Mat img; CRect rect; GetClientRect(&rect); // 获取控件大小 - int nWidth = img.cols * rect.Height() *1.0 / img.rows; - cv::resize(img, imgTmp, cv::Size(nWidth, rect.Height()));// 缩放Mat并备份 - // 转一下格式 ,这段可以放外面, - switch (imgTmp.channels()) + int nWidth = imageMat.cols * rect.Height() *1.0 / imageMat.rows; + cv::resize(imageMat, img, cv::Size(nWidth, rect.Height()));// 缩放Mat并备份 + // 转一下格式 ,这段可以放外面,*/ + + /*switch (imgTmp.channels()) { case 1: cv::cvtColor(imgTmp, imgTmp, CV_GRAY2BGRA); // GRAY单通道 @@ -412,66 +473,28 @@ void CPlayWnd::DrawMat(cv::Mat& img) DIB_RGB_COLORS, SRCCOPY ); - ReleaseDC(pDC); + ReleaseDC(pDC);*/ + + CImage image; + image.Create(imageMat.cols, imageMat.rows, 24); + for (int y = 0; y < imageMat.rows; ++y) { + const uchar* src = imageMat.ptr(y); + uchar* dst = reinterpret_cast(image.GetBits()) + y * image.GetPitch(); + for (int x = 0; x < imageMat.cols; ++x) { + dst[0] = src[0]; + dst[1] = src[1]; + dst[2] = src[2]; + src += 3; + dst += 3; + } + } + + HDC hdc = ::GetDC(m_hWnd); + image.Draw(hdc, CRect(CPoint(nOffset, 0), CSize(imageMat.cols, imageMat.rows))); + image.Destroy(); + ::ReleaseDC(m_hWnd, hdc); + } -void CALLBACK CPlayWnd::RealDataCallBackEx(LLONG lRealHandle, DWORD dwDataType, BYTE *pBuffer, DWORD dwBufSize, LLONG lParam, LDWORD dwUser) -{ - - if (dwUser == 0) - { - return; - } - - CPlayWnd *pWnd = (CPlayWnd *)dwUser; - pWnd->ReceiveRealData(lRealHandle, dwDataType, pBuffer, dwBufSize, lParam); -} - -//Process after receiving real-time data -void CPlayWnd::ReceiveRealData(LLONG lRealHandle, DWORD dwDataType, BYTE *pBuffer, DWORD dwBufSize, LLONG lParam) -{ - //Stream port number according to the real-time handle. - LONG lRealPort = 1;// GetStreamPort(lRealHandle); - - if (lRealHandle == m_DispHanle) - { - lRealPort = m_nWndID; - } - - if (0 == lRealPort) - { - return; - } - //Input the stream data getting from the card - BOOL bInput = FALSE; - switch (dwDataType) - { - case 0: - - { - //Original data - bInput = g_PlayAPI.PLAY_InputData(lRealPort, pBuffer, dwBufSize); - - - break; - } - case 1: - //data with frame info - - break; - case 2: - //yuv data - AfxMessageBox(""); - break; - case 3: - //pcm audio data - - break; - default: - break; - } -} - - diff --git a/fast/PlayWnd.h b/fast/PlayWnd.h index ddebf95..09878f5 100644 --- a/fast/PlayWnd.h +++ b/fast/PlayWnd.h @@ -41,6 +41,8 @@ ///////////////////////////////////////////////////////////////////////////// // CPlayWnd dialog +class CPtzScreen; + class CPlayWnd : public CWnd { // Construction @@ -85,7 +87,7 @@ protected: DECLARE_MESSAGE_MAP() public: - void SetWinID(int ID, CString strName, CString strIp, int nPort, CString strUser, CString strPassword) + void SetWinID(int ID, CString strName, CString strIp, int nPort, CString strUser, CString strPassword, CPtzScreen *pParent) { m_strCameraName = strName; m_strCameraIp = strIp; @@ -93,12 +95,13 @@ public: m_strUserName = strUser; m_strPassWord = strPassword; m_nWndID = ID; + m_pParentWnd = pParent; } int GetWinID(void){return m_nWndID;} void SetWndPlaying(bool bPlay){ bIsPlaying = bPlay; } private: - int m_nWndID; + CPoint pointStart; CPoint pointEnd; CPoint pointMove; @@ -106,27 +109,31 @@ private: bool bIsPlaying; -private: +public: CString m_strCameraName; CString m_strCameraIp; CString m_strUserName; CString m_strPassWord; int m_nCameraPort; - + LONG m_nWndID; LLONG m_llLoginId; LLONG m_DispHanle; + LLONG m_lRealHandle; + int m_nIndex; int m_nState; + LONG m_nPlayPort; + CPtzScreen *m_pParentWnd; public: - LLONG Login(CString strIpAddr, int nPort, CString strUser, CString strPW); - void ServerPlayMode(); + LLONG Login(); static void CALL_METHOD fDisplayCB(LONG nPort, char * pBuf, LONG nSize, LONG nWidth, LONG nHeight, LONG nStamp, LONG nType, void* pReserved); - static void CALLBACK RealDataCallBackEx(LLONG lRealHandle, DWORD dwDataType, BYTE *pBuffer, DWORD dwBufSize, LLONG lParam, LDWORD dwUser); - void ReceiveRealData(LLONG lRealHandle, DWORD dwDataType, BYTE *pBuffer, DWORD dwBufSize, LLONG lParam); - void DrawMat(cv::Mat& img); + + + void DrawMat(cv::Mat& img, int nOffset); void ShowLoginErrorReason(int nError); + void StopPlayForServerMode(); }; ///////////////////////////////////////////////////////////////////////////// diff --git a/fast/PtzScreen.cpp b/fast/PtzScreen.cpp index 23a739a..e539c43 100644 --- a/fast/PtzScreen.cpp +++ b/fast/PtzScreen.cpp @@ -224,7 +224,7 @@ int CPtzScreen::OnCreate(LPCREATESTRUCT lpCreateStruct) int nPort = GetPrivateProfileInt("CAMERA", strParam, 37777, iniPath); - m_wndVideo[i].SetWinID(i+1, strName, strIp, nPort, strUser, strPassword); + m_wndVideo[i].SetWinID(i+1, strName, strIp, nPort, strUser, strPassword, this); m_wndVideo[i].Create( NULL, @@ -235,16 +235,16 @@ int CPtzScreen::OnCreate(LPCREATESTRUCT lpCreateStruct) 1979, NULL); - + //m_wndVideo[i].Login(strIp, nPort, strUser, strPassword); AddPage(&m_wndVideo[i]); + } SetActivePage(&m_wndVideo[0], TRUE); SetDrawActivePage(TRUE, RGB(248,5,182), RGB(248,5,182)); return 0; - return 0; } void CPtzScreen::OnDestroy() @@ -318,343 +318,3 @@ void CPtzScreen::OnCaptureChanged(CWnd *pWnd) CWnd::OnCaptureChanged(pWnd); } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/fast/Resource.h b/fast/Resource.h index 5789ef8..a005253 100644 --- a/fast/Resource.h +++ b/fast/Resource.h @@ -1,20 +1,24 @@ //{{NO_DEPENDENCIES}} -// 生成的 Microsoft Visual C++ 包含文件。 -// 由 MFCApplication6.rc 使用 +// Microsoft Visual C++ 生成的包含文件。 +// 供 Fast.rc 使用 // -#define IDD_ABOUTBOX 100 -#define IDD_MFCAPPLICATION6_FORM 101 -#define IDP_OLE_INIT_FAILED 100 -#define IDR_MAINFRAME 128 -#define IDR_MFCApplication6TYPE 130 +#define IDD_ABOUTBOX 100 +#define IDP_OLE_INIT_FAILED 100 +#define IDD_MFCAPPLICATION6_FORM 101 +#define IDR_MAINFRAME 128 +#define IDR_MFCApplication6TYPE 130 +#define ID_32771 32771 +#define ID_CALIBRATOR 32772 +#define ID_32773 32773 +#define ID_FISHEYE 32774 -// 新对象的下一组默认值 -// +// Next default values for new objects +// #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 310 -#define _APS_NEXT_CONTROL_VALUE 1000 -#define _APS_NEXT_SYMED_VALUE 310 -#define _APS_NEXT_COMMAND_VALUE 32771 +#define _APS_NEXT_RESOURCE_VALUE 310 +#define _APS_NEXT_COMMAND_VALUE 32775 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 310 #endif #endif