fast/Plugin/Fast/DahuaFisheyeCamera.cpp
2025-01-20 10:30:01 +08:00

510 lines
13 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// MsgHandleDlg.cpp : 实现文件
//
#include "stdafx.h"
#include "afxdialogex.h"
#include "Fast.h"
#include "DahuaFisheyeCamera.h"
#include "FastView.h"
#include "dhplay.h"
#define TIMER_LOGIN 10
// CMsgHandleDlg 对话框
IMPLEMENT_DYNAMIC(CDahuaFisheyeCamera, CBaseCamera)
CDahuaFisheyeCamera::CDahuaFisheyeCamera(CFastView * pParentWnd, int nIdx, ENUM_PLAY_TYPE enPlayType, CWnd* pParent /*=NULL*/)
: CBaseCamera(IDD_DLG_CAM, pParentWnd)
{
m_nCameraIdx = nIdx;
m_nIndex = 0;
m_pParentWnd = pParentWnd;
m_hCameraHandle = NULL;
m_nPlayTyp = enPlayType;
}
CDahuaFisheyeCamera::~CDahuaFisheyeCamera()
{
}
void CDahuaFisheyeCamera::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CDahuaFisheyeCamera, CDialog)
ON_WM_DESTROY()
ON_WM_TIMER()
ON_MESSAGE(WM_CAMERA_SNAP, &CDahuaFisheyeCamera::OnSnap)
END_MESSAGE_MAP()
/*
int GetDahuaCameraIdxByLoginID(CDahuaFisheyeCamera *pThis, LLONG lLoginID)
{
for (int i = 0; i < theApp.m_nCameraCount; i++)
{
if (theApp.m_CameraArray[i].lLoginId == lLoginID)
{
return i;
}
}
return -1;
}
*/
//断线回调
void CALLBACK DahuaDisConnectFunc(LLONG lLoginID, char *pchDVRIP, LONG nDVRPort, LDWORD dwUser)
{
if (dwUser == 0)
{
return;
}
CDahuaFisheyeCamera *pThis = (CDahuaFisheyeCamera *)dwUser;
TRACE("[%I64d - %d]*********************** 断开连接 *********************\r\n", lLoginID, pThis->m_hWnd);
HWND hWnd = pThis->GetSafeHwnd();
if (NULL == hWnd)
{
return;
}
//int nIdx = GetDahuaCameraIdxByLoginID(pThis, lLoginID);
if (pThis->m_lLoginId == lLoginID)
{
pThis->m_nCameraState = 0;
}
//pThis->m_pParentWnd->RefreshCameraList();
//pThis->m_pParentWnd->VoiceReminder();
}
void CALLBACK DahuaReConnectFunc(LLONG lLoginID, char *pchDVRIP, LONG nDVRPort, LDWORD dwUser)
{
if (dwUser == 0)
{
return;
}
CDahuaFisheyeCamera *pThis = (CDahuaFisheyeCamera *)dwUser;
TRACE("[%I64d - %d]*********************** 重新连接 *********************\r\n", lLoginID, pThis->m_hWnd);
HWND hWnd = pThis->GetSafeHwnd();
if (NULL == hWnd)
{
return;
}
if (pThis->m_lLoginId == lLoginID)
{
pThis->m_nCameraState = 1;
}
//int nIdx = GetDahuaCameraIdxByLoginID(pThis, lLoginID);
//pThis->m_nCameraState = 1;
//pThis->m_pParentWnd->RefreshCameraList();
//pThis->m_pParentWnd->VoiceReminder();
}
void CALLBACK DahuaSnapPicRet(LLONG lLoginID, BYTE *pBuf, UINT RevLen, UINT EncodeType, DWORD CmdSerial, LDWORD dwUser)
{
CDahuaFisheyeCamera *pThis = (CDahuaFisheyeCamera*)dwUser;
if (pThis->m_lLoginId == lLoginID)
{
CTime currentTime = CTime::GetCurrentTime(); // 获取当前时间
CString dateStr = currentTime.Format(_T("%Y_%m_%d")); // 格式化为字符串
CString tiemStr = currentTime.Format(_T("%H_%M_%S")); // 格式化为字符串
CString strPath = theApp.m_strDataPath + "\\" + dateStr;
if (!PathIsDirectory(strPath))//判断日期路径是否存在
{
CreateDirectory(strPath, NULL);//新建日期文件夹
}
//原图
char acFileName[256] = "";
sprintf(acFileName, "%s\\%s-%d.jpg", strPath, tiemStr, pThis->m_nCameraIdx);
//分析后的图片
//char acAnalysisName[256] = "";
//sprintf(acAnalysisName, "%s\\analysis-%d.JPG", strPath, 0);
/* Save image original file */
FILE *stream;
if ((stream = fopen((const char*)acFileName, "wb")) != NULL)
{
int numwritten = fwrite(pBuf, sizeof(char), RevLen, stream);
fclose(stream);
}
pThis->m_pParentWnd->StartPlay(acFileName);
//theApp.m_CameraArray[nIdx].strImagePath[0] = acFileName;
//theApp.m_CameraArray[nIdx].strImagePath[1] = acAnalysisName;
//pThis->m_pParentWnd->ShowCameraImage(acFileName, nIdx);
//SetEvent(theApp.m_EventHandles[nIdx]);
/*if (theApp.m_CameraArray[nIdx].bAnalysis == TRUE)
{
//需要解析
ParseImage(pThis, acFileName, acAnalysisName, nIdx);
}
else
{
SetEvent(theApp.m_EventHandles[nIdx]);
theApp.m_CameraArray[nIdx].strImagePath[0] = acFileName;
theApp.m_CameraArray[nIdx].strImagePath[1] = acFileName;
pThis->m_pParentWnd->ShowCameraImage(acFileName, nIdx);
}*/
}
return;
}
// netsdk 实时回调函数
void CALL_METHOD fRealDataCB(LLONG lRealHandle, DWORD dwDataType, BYTE *pBuffer, DWORD dwBufSize, LDWORD dwUser)
{
CDahuaFisheyeCamera *pWnd = (CDahuaFisheyeCamera*)dwUser;
if (pWnd->m_lRealHandle != lRealHandle)return;
// 把大华实时码流数据送到playsdk中
PLAY_InputData(pWnd->m_nWndID, pBuffer, dwBufSize);
return;
}
// playsdk 回调 yuv数据
void CALL_METHOD fDisplayCB(LONG nPort, char * pBuf, LONG nSize, LONG nWidth, LONG nHeight, LONG nStamp, LONG nType, void* pReserved)
{
CDahuaFisheyeCamera *pShowWnd = (CDahuaFisheyeCamera *)(pReserved);
if (pShowWnd->m_nWndID != nPort)return;
//TRACE("%d\n", pThis->m_nWndID);
//if (pThis->m_nWndID > 1)return;
pShowWnd->m_nIndex++;
if (pShowWnd->m_nIndex == 10)
{
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::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->m_pParentWnd->DrawMat(imgTmp, (rect.Width() - nWidth) / 2);
cv::waitKey(10);
}
return;
}
CString CDahuaFisheyeCamera::ConvertString(CString strText)
{
char *val = new char[200];
CString strIniPath, strRet;
memset(val, 0, 200);
GetPrivateProfileString("String", strText, "",
val, 200, "./langchn.ini");
strRet = val;
if (strRet.GetLength() == 0)
{
//If there is no corresponding string in ini file then set it to be deafault value(English).
strRet = strText;
}
delete[] val;
return strRet;
}
//Display log in failure reason
void CDahuaFisheyeCamera::ShowLoginErrorReason(int nError)
{
if (1 == nError) MessageBox(ConvertString("Invalid password!"), ConvertString("Prompt"));
else if (2 == nError) MessageBox(ConvertString("Invalid account!"), ConvertString("Prompt"));
else if (3 == nError) MessageBox(ConvertString("Timeout!"), ConvertString("Prompt"));
else if (4 == nError) MessageBox(ConvertString("The user has logged in!"), ConvertString("Prompt"));
else if (5 == nError) MessageBox(ConvertString("The user has been locked!"), ConvertString("Prompt"));
else if (6 == nError) MessageBox(ConvertString("The user has listed into illegal!"), ConvertString("Prompt"));
else if (7 == nError) MessageBox(ConvertString("The system is busy!"), ConvertString("Prompt"));
else if (9 == nError) MessageBox(ConvertString("You Can't find the network server!"), ConvertString("Prompt"));
else MessageBox(ConvertString("Login failed!"), ConvertString("Prompt"));
}
// CMsgHandleDlg 消息处理程序
BOOL CDahuaFisheyeCamera::OnInitDialog()
{
CDialog::OnInitDialog();
InitCameraSDK();
CString strIpAddr = "192.168.0.102";
int nPort = 37777;
CString strUser = "admin";
CString strPW = "wdq@2023";
m_lLoginId = Login(strIpAddr, nPort, strUser, strPW);
if (m_lLoginId > 0)
{
m_nCameraState = 1;
KillTimer(TIMER_LOGIN);
}
else
{
m_nCameraState = 0;
SetTimer(TIMER_LOGIN, 10000, NULL);
}
return TRUE; // return TRUE unless you set the focus to a control
}
BOOL CDahuaFisheyeCamera::InitCameraSDK()
{
TRACE("[%d - %d]*********************** InitNetSDK *********************\r\n", m_nCameraIdx, this->m_hWnd);
BOOL ret = CLIENT_Init(DahuaDisConnectFunc, (LDWORD)this);
if (ret)
{
LOG_SET_PRINT_INFO stLogPrintInfo = { sizeof(stLogPrintInfo) };
CLIENT_LogOpen(&stLogPrintInfo);
CLIENT_SetSnapRevCallBack(DahuaSnapPicRet, (LDWORD)this);
CLIENT_SetAutoReconnect(DahuaReConnectFunc, (LDWORD)this);
//CLIENT_SetConnectTime(0, 0);
TRACE("[%d - %d]*********************** InitNetSDK SUCCEED*********************\r\n", m_nCameraIdx, this->m_hWnd);
}
else
{
MessageBox(ConvertString("initialize SDK failed!"), ConvertString("prompt"));
}
// 初始化成功后设置网络参数
NET_PARAM stuNetParam = { 0 };
// 目前仅单独设置获取设备信息时间(部分设备因性能问题,没法在默认时间内完成,其他参数暂时保持默认)
stuNetParam.nGetDevInfoTime = 3000;
CLIENT_SetNetworkParam(&stuNetParam);
return TRUE;
}
LLONG CDahuaFisheyeCamera::Login(CString strIpAddr, int nPort, CString strUser, CString strPW)
{
//依次登录摄像机获取登录ID
NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY stInparam;
memset(&stInparam, 0, sizeof(stInparam));
stInparam.dwSize = sizeof(stInparam);
strncpy(stInparam.szIP, strIpAddr.GetBuffer(), strIpAddr.GetLength());
strncpy(stInparam.szPassword, strPW.GetBuffer(), strPW.GetLength());
strncpy(stInparam.szUserName, strUser.GetBuffer(), strUser.GetLength());
stInparam.nPort = nPort;
stInparam.emSpecCap = EM_LOGIN_SPEC_CAP_TCP;
NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY stOutparam;
memset(&stOutparam, 0, sizeof(stOutparam));
stOutparam.dwSize = sizeof(stOutparam);
LLONG lLoginHandle = CLIENT_LoginWithHighLevelSecurity(&stInparam, &stOutparam);
if (0 == lLoginHandle)
{
//Display log in failure reason
//ShowLoginErrorReason(stOutparam.nError);
return -1;
}
else
{
if (SNAP_PICTURE == m_nPlayTyp)
{
//m_LoginID = lRet;
int nRetLen = 0;
NET_DEV_CHN_COUNT_INFO stuChn = { sizeof(NET_DEV_CHN_COUNT_INFO) };
stuChn.stuVideoIn.dwSize = sizeof(stuChn.stuVideoIn);
stuChn.stuVideoOut.dwSize = sizeof(stuChn.stuVideoOut);
BOOL bRet = CLIENT_QueryDevState(lLoginHandle, DH_DEVSTATE_DEV_CHN_COUNT, (char*)&stuChn, stuChn.dwSize, &nRetLen);
if (!bRet)
{
DWORD dwError = CLIENT_GetLastError() & 0x7fffffff;
}
}
else if (RT_STREAMING == m_nPlayTyp)
{
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);
//拉流
m_lRealHandle = CLIENT_RealPlayEx(lLoginHandle, 0, 0);
//设置拉流回调
CLIENT_SetRealDataCallBack(m_lRealHandle, fRealDataCB, (LDWORD)this);
}
return lLoginHandle;
}
//SetWindowText(ConvertString("CapturePicture"));
/*
char *pchDVRIP;
//CString strDvrIP = GetDvrIP();
pchDVRIP = (LPSTR)(LPCSTR)strIpAddr;
WORD wDVRPort = (WORD)nPort;
char *pchUserName = (LPSTR)(LPCSTR)strUser;
char *pchPassword = (LPSTR)(LPCSTR)strPW;
NET_DEVICEINFO_Ex stLoginInfo = { 0 };
int nErrcode = 0;
LLONG lLoginHandle = CLIENT_LoginEx2(pchDVRIP, nPort, 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;
}
if (0 == m_lRealHandle)
{
//cout << "CLIENT_RealPlayEx fail!" << endl;
Sleep(100000);
return -1;
}
//cout << "CLIENT_RealPlayEx success!" << endl;
*/
}
LRESULT CDahuaFisheyeCamera::OnSnap(WPARAM wParam, LPARAM lParam)
{
//AfxMessageBox("采样");
//摄像头离线无需下发
if (m_nCameraState == 0)
return 0;
//Fill in request structure
SNAP_PARAMS snapparams = { 0 };
snapparams.Channel = 0;
snapparams.mode = 0;
snapparams.CmdSerial = 0;
BOOL b = CLIENT_SnapPicture(m_lLoginId, snapparams);
if (!b)
{
//连接成功但截屏式失败的情况
//MessageBox(ConvertString("begin to snap failed!"), ConvertString("prompt"));
}
return 0;
}
void CDahuaFisheyeCamera::OnTimer(UINT_PTR nIDEvent)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
if (nIDEvent == TIMER_LOGIN)
{
//设备断开,重新打开
}
CDialog::OnTimer(nIDEvent);
}
void CDahuaFisheyeCamera::OnDestroy()
{
CDialog::OnDestroy();
}
void CDahuaFisheyeCamera::TargetDetection(int nCameraIdx, cv::Mat &mat_img, vector<CRect> &findRects)
{
CRect findRect;
try {
cv::Mat dst = mat_img;
//cv::Size newSize(mat_img.size().width / 4, mat_img.size().height / 4); // 设置新的尺寸
//cv::resize(mat_img, dst, newSize); // 调整图像尺寸
auto det_image = theApp.m_yoloV4.m_pDetector->mat_to_image_resize(dst);
auto start = std::chrono::steady_clock::now();
std::vector<bbox_t> result_vec = theApp.m_yoloV4.m_pDetector->detect_resized(*det_image, dst.size().width, dst.size().height);
auto end = std::chrono::steady_clock::now();
std::chrono::duration<double> spent = end - start;
std::cout << " Time: " << spent.count() << " sec \n";
theApp.m_yoloV4.DrawObjectBoxes(dst, result_vec, theApp.m_yoloV4.m_vObjects_Names);
for (int i = 0; i < result_vec.size(); i++)
{
bbox_t result_area = result_vec.at(i);
std::string obj_name = theApp.m_yoloV4.m_vObjects_Names[result_area.obj_id];
//if (result_area.prob >= 0.9 && (0 == obj_name.compare("up") ))
{
CRect rect;
rect.left = result_area.x;
rect.top = result_area.y;
rect.right = result_area.x + result_area.w;
rect.bottom = result_area.y + result_area.h;
findRects.push_back(rect);
}
}
}
catch (std::exception &e) { std::cerr << "exception: " << e.what() << "\n"; getchar(); }
catch (...) { std::cerr << "unknown exception \n"; getchar(); }
}