项目背景

很久没有做工程项目了,最近突然接单,要做多摄像头下运动物体入侵检测及拌线检测,本文测试用到的摄像头是海康威视的DS-2CD23**D摄像头。

环境配置:

1.下载SDK

2.vs2010开发环境

3..opencv2.4.8

具体配置自行百度吧。下面贴上我这边的主要配置,需要注意的是需要在x64环境下编译。

将摄像头插入以太网口后,那么我们就可以通过官方提供的“设备网络搜索软件“——SADP工具,这个软件可以在海康威视的官方网站下载最新版本。本篇文章的很大程度上参照了lonelyrains的教程,在此基础上进行改进,同时在此表示感谢。

1.先在官网下载到SDK开发包:

下载下来SDK后我们解压,就可以看到里面包含一些开发文档以及一些Demo示例:

2.VS2010下环境配置

首先,配置属性---常规

1)输出目录:$(SolutionDir)\bin\

2.)中间目录:$(SolutionDir)\Temp\Compile\$(ProjectName)\$(ConfigurationName)

接着,配置属性---调试

VC++目录

包含目录:

..\include

opencv目录也要包含进来,继承值里如果没有的话

库目录:

接着C/C++

常规--附加包含目录 ../include/

链接器--常规 --附加库目录  ../lib/

链接器--输入--附加依赖项

HCNetSDK.lib

ws2_32.lib
PlayCtrl.lib
winmm.lib
GdiPlus.lib
IPHlpApi.Lib

3.opencv配置,参见这里

视频采集

下面进入重点,实时视频采集。

先看看SDK里的demo函数,参见这里

代码如下:

NesunCamDriver.h

添加了进程锁,由于考虑到项目保密性,下面开放部分源码。

.cpp源码开放出来:

#include "StdAfx.h"
#include "NesunCamDriver.h"
#include <windows.h>IplImage * NesunCamDriver::m_pImg = NULL;
long NesunCamDriver::nPort = -1;
float NesunCamDriver::Scalefactor = 1.0f;
MTCMutex NesunCamDriver::m_hMutex;
HWND NesunCamDriver::m_hPlayWnd=NULL;
NesunCamDriver::NesunCamDriver(void): lUserID(0), lRealPlayHandle(-1)
{/*  Create a mutex Lock when a object create *///m_pImg = NULL;//hMutex = CreateMutex(NULL,FALSE,NULL);}NesunCamDriver::~NesunCamDriver(void)
{ReleaseCamera();
}int NesunCamDriver::ReleaseCamera(void)
{if(!NET_DVR_StopRealPlay(lRealPlayHandle)){printf("NET_DVR_StopRealPlay error! Error number: %d\n",NET_DVR_GetLastError());return 0;}NET_DVR_Logout(lUserID);NET_DVR_Cleanup();cvReleaseImage(&m_pImg);//gavin++if (m_pImg){m_pImg = NULL;}return 1;
}void NesunCamDriver::InitHKNetSDK(void)
{/*  SDK Init                                 */NET_DVR_Init();/*  Set the Connect Time and Reconnect time  */NET_DVR_SetConnectTime(200, 1);NET_DVR_SetReconnect(10000, true);}CamHandle NesunCamDriver::InitCamera(char *sIP,char *UsrName,char *PsW, HWND hPlayWnd,int Port)
{m_hPlayWnd = hPlayWnd;NET_DVR_DEVICEINFO_V30 struDeviceInfo;memset(&struDeviceInfo,0,sizeof(NET_DVR_DEVICEINFO_V30));lUserID = NET_DVR_Login_V30(sIP, Port,UsrName,PsW, &struDeviceInfo);if (lUserID < 0){printf("Login error, %d\n", NET_DVR_GetLastError());NET_DVR_Cleanup();return -1;}NET_DVR_SetExceptionCallBack_V30(0, NULL,ExceptionCallBack, NULL);NET_DVR_CLIENTINFO ClientInfo;ClientInfo.lChannel = 1;                    /* Channel number Device channel number. */ClientInfo.hPlayWnd = NULL;                 //NULL;  窗口为空,设备SDK不解码只取流    ClientInfo.lLinkMode = 0;                   /* Main Stream                           */ClientInfo.sMultiCastIP = NULL;lRealPlayHandle = NET_DVR_RealPlay_V30(lUserID,&ClientInfo,fRealDataCallBack,NULL,TRUE);if(-1 == lRealPlayHandle){DWORD err=NET_DVR_GetLastError();printf("NET_DVR_RealPlay_V30 failed! Error number: %d\n", err);CString sErr;sErr.Format("播放出错,错误代码:%d",err);AfxMessageBox(sErr);return 0;}return lRealPlayHandle;
}void CALLBACK  NesunCamDriver::DecCBFun(long nPort,char * pBuf,long nSize,FRAME_INFO * pFrameInfo, long nReserved1,long nReserved2)
{long lFrameType = pFrameInfo->nType;  char WindowName[15];static IplImage* pImgYCrCb =NULL;sprintf_s(WindowName,"Windows:%d",nPort);if(lFrameType ==T_YV12){m_hMutex.Lock();/*    Single Camera decode 3.5%    */if(pImgYCrCb == NULL){pImgYCrCb = cvCreateImage(cvSize(pFrameInfo->nWidth,pFrameInfo->nHeight), 8, 3);        }if (m_pImg == NULL){m_pImg = cvCreateImage(cvSize((int)(pFrameInfo->nWidth*Scalefactor),(int)(pFrameInfo->nHeight*Scalefactor)), 8, 3); }/*    CPU: 0.1%                    */yv12toYUV(pImgYCrCb->imageData, pBuf, pFrameInfo->nWidth,pFrameInfo->nHeight,pImgYCrCb->widthStep);  cvResize(pImgYCrCb,m_pImg, CV_INTER_LINEAR);/*    CPU  3.4%                    */cvCvtColor(m_pImg,m_pImg,CV_YCrCb2RGB); /*   1080p Video Display Need 3.5%per Cmaera                    */m_hMutex.UnLock();cvReleaseImage(&pImgYCrCb);//gavin++}
}void CALLBACK  NesunCamDriver::ExceptionCallBack(DWORD dwType, LONG lUserID, LONG lHandle, void *pUser)
{char tempbuf[256] = {0};switch(dwType) {case EXCEPTION_RECONNECT:    /* Reconnet when Error Happen */break;default:break;}
}void NesunCamDriver::yv12toYUV(char *outYuv, char *inYv12, int width, int height,int widthStep)
{int col,row;unsigned int Y,U,V;int tmp;int idx;for (row=0; row<height; row++){idx=row * widthStep;int rowptr=row*width;for (col=0; col<width; col++){tmp = (row/2)*(width/2)+(col/2);Y=(unsigned int) inYv12[row*width+col];U=(unsigned int) inYv12[width*height+width*height/4+tmp];V=(unsigned int) inYv12[width*height+tmp];outYuv[idx+col*3]   = Y;outYuv[idx+col*3+1] = U;outYuv[idx+col*3+2] = V;}}
}
/*     Realtime Steam Callback           */
void CALLBACK NesunCamDriver::fRealDataCallBack(LONG lRealHandle,DWORD dwDataType,BYTE *pBuffer,DWORD dwBufSize,void *pUser)
{DWORD dRet;DWORD CameraIndex = 0;CameraIndex  = lRealHandle;printf("lRealHandle = %ld\n",CameraIndex);switch (dwDataType){/*  System Head    */case NET_DVR_SYSHEAD:    if (!PlayM4_GetPort(&nPort))break;if(dwBufSize > 0){if (!PlayM4_OpenStream(nPort,pBuffer,dwBufSize,1024*1024)){dRet=PlayM4_GetLastError(nPort);break;}//fix by gavin//设置解码回调函数 只解码不显示//       if (!PlayM4_SetDecCallBack(nPort,DecCBFun))//       {//             dRet=PlayM4_GetLastError(nPort);//             break;//        }//设置解码回调函数 解码且显示if (!PlayM4_SetDecCallBackEx(nPort,DecCBFun,NULL,NULL)){dRet=PlayM4_GetLastError(nPort);break;}/*if (!PlayM4_Play(nPort,NULL)){dRet=PlayM4_GetLastError(nPort);break;}   *///打开视频解码if (!PlayM4_Play(nPort,m_hPlayWnd)){dRet=PlayM4_GetLastError(nPort);break;}//打开音频解码, 需要码流是复合流if (!PlayM4_PlaySound(nPort)){dRet=PlayM4_GetLastError(nPort);break;}break;}break;/* Code steam data    */case NET_DVR_STREAMDATA:   if (dwBufSize > 0 && nPort != -1) {BOOL inData=PlayM4_InputData(nPort,pBuffer,dwBufSize);while (!inData){Sleep(10);inData=PlayM4_InputData(nPort,pBuffer,dwBufSize);}}break;  }
}int NesunCamDriver::GetCamMat(Mat &Img,CamHandle handle,float factor)
{/*  Get the Port using handle    */int iPort = nPort;/*  Check the iPort is vaild     */if(iPort != -1){//WaitForSingleObject(hMutex[iPort],INFINITE);m_hMutex.Lock();Mat(m_pImg).copyTo(Img);//ReleaseMutex(hMutex[iPort]);cvReleaseImage(&m_pImg);//gavin++m_pImg = NULL;//gavin++m_hMutex.UnLock();resize(Img,Img,cv::Size(),factor,factor);return 1;}/* If iPort is invaild, return empty                         */return 0;
}void NesunCamDriver::SetScaleFactor(float factor)
{Scalefactor = factor;
}// 抓图保存到指定路径
int NesunCamDriver::CaptureImg(char* szPath,char* szError)
{FILE *file=NULL;static long iPicNum = 0;NET_DVR_JPEGPARA JpegPara;JpegPara.wPicQuality=0;JpegPara.wPicSize=0xff;char *JpegPicBuffer= new char[352*288*2]; //这里的缓冲区大小需要根据抓图的分辨率大小自己调节,建议设置成2*图片的分辨率宽*图片的分辨率高LONG iPChannel = 1;//Channel number 设备通道号DWORD  SizeReturned=0;   BOOL bRet= NET_DVR_CaptureJPEGPicture_NEW(lUserID, iPChannel,&JpegPara,JpegPicBuffer,352*288*2,&SizeReturned);if (!bRet){sprintf(szError, "NET_DVR_CaptureJPEGPicture_NEW failed! Error number: %d\n", NET_DVR_GetLastError());return 0;}if (file==NULL){sprintf(szPath,"%s\\JpegCAP%d_%d.jpg",szPath,lUserID,iPicNum);file = fopen(szPath,"wb");}fwrite(JpegPicBuffer,SizeReturned,1,file);iPicNum++;delete JpegPicBuffer;fclose(file);file=NULL;return 1;
}

调用:

        CString strMode;GetDlgItemText(IDC_BT_PLAY, strMode);    if (_T("播放") == strMode){m_hkCamDriver[0].InitHKNetSDK();m_hkCamDriver[0].SetScaleFactor(0.5f);Sleep(500);if (m_hkHandle[0] >= 0){NET_DVR_StopRealPlay(m_hkHandle[0]);m_hkHandle[0] = -1;}//m_lPlayHandle = NET_DVR_RealPlay_V30(m_lUserID, &struPlayInfo, NULL, NULL, TRUE); m_hkHandle[0] = m_hkCamDriver[0].InitCamera("192.168.1.222","admin","12345",m_hPlayWnd[0]);if (m_hkHandle[0] < 0){char szTemp[128] = {0};sprintf(szTemp, "视频播放出错, %s", NET_DVR_GetErrorMsg());AfxMessageBox(szTemp);}GetDlgItem(IDC_BT_PLAY)->SetWindowText("停止");}else if (_T("停止") == strMode){m_hkCamDriver[0].ReleaseCamera();GetDlgItem(IDC_BT_PLAY)->SetWindowText("播放");}

注意对应窗口显示区域,HWND m_hPlayWnd[12];

m_hPlayWnd[0] = GetDlgItem(IDC_STATIC_PLAY)->GetSafeHwnd();

其他参考:

1.https://blog.csdn.net/log_zhan/article/details/75041352#commentsedit

2.https://blog.csdn.net/qq_15029743/article/details/79733960

3.OpenCV笔记(2)打开海康威视摄像头

4.海康摄像头实时显示与字符叠加详解

5.海康威视IP摄像头基于OPENCV的二次开发

6.ROS:海康威视+opencv运动检测

7.捕获海康威视IPCamera图像,转成OpenCV可以处理的图像(二)

海康威视多摄像头实时视频预览(基于SDK的二次开发)相关推荐

  1. 实现flv格式网络摄像头实时视频预览(nginx-rtmp,ffmpeg)

    实现http-flv格式网络摄像头实时视频预览(nginx-rtmp,ffmpeg) 实现思路 获取摄像头rtsp流→流媒体拉流转码推流成rtmp流(网页具备flash可播放,谷歌浏览器已经禁用)→不 ...

  2. 海康网络摄像头实时视频预览(流媒体转码推流 red5,nginx-rtmp,ffmpeg)

    海康网络摄像头实时视频预览(流媒体转码推流 red5,nginx-rtmp,ffmpeg) 实现思路 获取摄像头rtsp流→流媒体拉流转码推流成rtmp流(网页具备flash可播放)→根据rtmp流地 ...

  3. 基于海康威视的SDK实现二次开发

    文章目录 前言 1.对接海康威视的SDK 进入海康威视官网 下载你所需要的SDK开发包(这里我就用windows来作为案列) 下载完SDK解压 运行Demo示例 开发接口之前的环境配置 开始基于海康威 ...

  4. android m在哪下载地址,android m预览版SDK下载地址 android m预览版SDK下载网址

    android m预览版SDK,其中包括开发工具.Android系统文件.库文件以及将在该平台下个版本发布时到来的全新API,这些工具和文件可以帮助开发者测试应用. 开发者可通过Android SDK ...

  5. 基于Qt的海康威视网络摄像头SDK的二次开发——摄像头登录和预览

    海康威视网络摄像头SDK的二次开发,需要摄像头IP地址,与主机的IP地址在同一网段,能够ping通摄像头IP,才能登录成功.摄像头是有账户名和密码,这需要记住,在开发的时候需要用到. 在开发前可以先用 ...

  6. Java海康威视摄像头实时预览视频流保存到指定文件中

    海康威视摄像头实时预览视频流保存到文件中 目前在开发海康威视sdk ,IPC设备,视频回调用的是官方提供的Demo中的(fRealDataCallBack ) 在最下面代码可以设置Thread.sle ...

  7. 基于Qt的海康威视网络摄像头SDK的二次开发

    最近用Qt做了一个基于海康威视网络摄像头SDK的二次开发,效果还不错.文章最后将开发的资料和demo软件通过链接方式分享,有兴趣的可以看下效果. 开发情况介绍: qt版本:Qt5.14.2 海康SDK ...

  8. FFmpeg入门详解之124:Qt5 FFmpeg单路网络摄像头采集预览

    Qt5+FFmpeg单路网络摄像头采集预览 源码工程:S26_Test4 RTSP协议简介 RTSP(Real Time Streaming Protocol),RFC2326 RTSP(Real T ...

  9. C#界面设计--4--C#实现多个IP摄像头画面预览以及截图

    1.C# 多个ip摄像头画面预览以及截图界面 2.winform VS2013 .NET4 Client Profile 3.测试摄像头:海康威视,USB摄像头 4.需要输入IP地址,端口号,用户名和 ...

最新文章

  1. WPF捕获全局未处理异常
  2. Leetcode 47. 全排列 II (每日一题 20211015)
  3. 【转载】SQL update select结合语句详解及应用
  4. Android之sqlite常见用法以及取最新多少条数据(包括删除和不删除之外的数据)
  5. python导入模块有几种方式、各有什么特点_Python导入模块的几种姿势
  6. 美国计算机授课型硕士,美国高校一年制硕士项目中,哪些项目最值得推荐?
  7. html辅助方法以及常用属性值,ASP.NET MVC 2博客系列之一:强类型HTML辅助方法
  8. 3类兼职渠道,赚钱的方法来了
  9. 再谈和字体有关的几个问题
  10. 【地理信息技术】 上机04 栅格数据的空间分析(一) 学校选址分析
  11. python实现鼠标键盘事件_鼠标与键盘操作事件
  12. locust性能测试工具
  13. html设置图片与边框的距离,css图片如何设置上边框距离
  14. 基于标准库函数与基于HAL库函数的stm32编程方式对比
  15. Sentinel整合Dubbo限流实战
  16. 如何在网上查阅和免费下载标准-网站推荐
  17. mycat分库分表(线上实际案例)
  18. 基于jsp+mysql的JSP校园自行车租赁网站平台管理系统
  19. 写时复制技术(摘自C语言中文网)
  20. sqli-labs靶场第五关

热门文章

  1. 3.10 杭电复试题2012
  2. Android 开发技术干货
  3. 【ArcGIS Addin开发】No GUI components found in this Add-In. Add-In version does not match
  4. 关于继电器开关带来的干扰
  5. 中学计算机教育论文,【中学计算机教育互动式培养策略计算机教育论文材料】...
  6. (七)JMockit 的MockUp+@Mock--基础篇
  7. 一般3d模型代做多少钱_3d打印一个模型多少钱
  8. java rsa sha1_将SHA1和RSA与java.security.Signature和MessageDigest和Cipher结合使用
  9. eMMC(二)——分区管理
  10. 日常工作要想有效提高工作效率 常用的在线工具网站