经过很多天的配置,终于能在工程中调用海康威视的网络摄像头了,为了后人能快速上手,我整理内容如下:
2.在/etc/ld.so.conf文件结尾添加网络sdk库的路径,如/XXX和/XXX/HCNetSDKCom/,保存之后,然后执行ldconfig。
三. 在Ubuntu16.04 的qt中新建一个工程
1. 在工程的 ×.pro文件中添加以下内容:
INCLUDEPATH += /usr/local/include \ /usr/local/include/opencv \ /usr/local/include/opencv2
LIBS += /usr/local/lib/libopencv_calib3d.so
/usr/local/lib/libopencv_ml.so.2.4.9
/usr/local/lib/libopencv_calib3d.so.2.4
/usr/local/lib/libopencv_nonfree.so
/usr/local/lib/libopencv_calib3d.so.2.4.9
/usr/local/lib/libopencv_nonfree.so.2.4
/usr/local/lib/libopencv_contrib.so
/usr/local/lib/libopencv_nonfree.so.2.4.9
/usr/local/lib/libopencv_contrib.so.2.4
/usr/local/lib/libopencv_objdetect.so
/usr/local/lib/libopencv_contrib.so.2.4.9
/usr/local/lib/libopencv_objdetect.so.2.4
/usr/local/lib/libopencv_core.so
/usr/local/lib/libopencv_objdetect.so.2.4.9
/usr/local/lib/libopencv_core.so.2.4
/usr/local/lib/libopencv_ocl.so
/usr/local/lib/libopencv_core.so.2.4.9
/usr/local/lib/libopencv_ocl.so.2.4
/usr/local/lib/libopencv_features2d.so
/usr/local/lib/libopencv_ocl.so.2.4.9
/usr/local/lib/libopencv_features2d.so.2.4
/usr/local/lib/libopencv_photo.so
/usr/local/lib/libopencv_features2d.so.2.4.9
/usr/local/lib/libopencv_photo.so.2.4
/usr/local/lib/libopencv_flann.so
/usr/local/lib/libopencv_photo.so.2.4.9
/usr/local/lib/libopencv_flann.so.2.4
/usr/local/lib/libopencv_stitching.so
/usr/local/lib/libopencv_flann.so.2.4.9
/usr/local/lib/libopencv_stitching.so.2.4
/usr/local/lib/libopencv_gpu.so
/usr/local/lib/libopencv_stitching.so.2.4.9
/usr/local/lib/libopencv_gpu.so.2.4
/usr/local/lib/libopencv_superres.so
/usr/local/lib/libopencv_gpu.so.2.4.9
/usr/local/lib/libopencv_superres.so.2.4
/usr/local/lib/libopencv_highgui.so
/usr/local/lib/libopencv_superres.so.2.4.9
/usr/local/lib/libopencv_highgui.so.2.4
/usr/local/lib/libopencv_highgui.so.2.4.9
/usr/local/lib/libopencv_video.so
/usr/local/lib/libopencv_imgproc.so
/usr/local/lib/libopencv_video.so.2.4
/usr/local/lib/libopencv_imgproc.so.2.4
/usr/local/lib/libopencv_video.so.2.4.9
/usr/local/lib/libopencv_imgproc.so.2.4.9
/usr/local/lib/libopencv_videostab.so
/usr/local/lib/libopencv_legacy.so
/usr/local/lib/libopencv_videostab.so.2.4
/usr/local/lib/libopencv_legacy.so.2.4
/usr/local/lib/libopencv_videostab.so.2.4.9
/usr/local/lib/libopencv_legacy.so.2.4.9
/usr/local/lib/libopencv_ml.so
INCLUDEPATH += /home/ding/opencvprojects/CH_HCNetSDK_V5.2.7.4build20170606_Linux64/incCn
LIBS += /home/ding/opencv_projects/CH_HCNetSDK_V5.2.7.4_build20170606_Linux64/lib/libhcnetsdk.so</span>
/home/ding/opencv_projects/CH_HCNetSDK_V5.2.7.4_build20170606_Linux64/lib/libHCCore.so</span>
/home/ding/opencv_projects/CH_HCNetSDK_V5.2.7.4_build20170606_Linux64/lib/libhpr.so</span>
/home/ding/opencv_projects/CH_HCNetSDK_V5.2.7.4_build20170606_Linux64/lib/libPlayCtrl.so</span>
/home/ding/opencv_projects/CH_HCNetSDK_V5.2.7.4_build20170606_Linux64/lib/libSuperRender.so</span>
/home/ding/opencv_projects/CH_HCNetSDK_V5.2.7.4_build20170606_Linux64/lib/libAudioRender.so2. 在main.cpp函数中添加以下内容:
#include "opencv2/opencv.hpp" #include <QDir> #include <fstream> #include <unistd.h> //#include "auto_entercs.h" #include "HCNetSDK.h" #include "PlayM4.h" #include "LinuxPlayM4.h" #define HPR_ERROR -1 #define HPR_OK 0 #define USECOLOR 0 static cv::Mat dst; HWND h = NULL; LONG nPort= -1; LONG lUserID; pthread_mutex_t mutex; std:: list<cv::Mat> g_frameList; FILE *g_pFile = NULL; void CALLBACK PsDataCallBack(LONG lRealHandle, DWORD dwDataType,BYTE *pPacketBuffer,DWORD nPacketSize, void* pUser) { if (dwDataType == NET_DVR_SYSHEAD) { //写入头数据 g_pFile = fopen( "/home/lds/source/ps.dat", "wb"); if (g_pFile == NULL) { printf( "CreateFileHead fail\n"); return; } //写入头数据 fwrite(pPacketBuffer, sizeof( unsigned char), nPacketSize, g_pFile); printf( "write head len=%d\n", nPacketSize); } else { if(g_pFile != NULL) { fwrite(pPacketBuffer, sizeof( unsigned char), nPacketSize, g_pFile); printf( "write data len=%d\n", nPacketSize); } } } //void CALLBACK DecCBFun(LONG nPort, char *pBuf, LONG nSize, FRAME_INFO *pFrameInfo, LONG nReserved1, LONG nReserved2) void CALLBACK DecCBFun(LONG nPort, char *pBuf, LONG nSize, FRAME_INFO *pFrameInfo, void* nReserved1, LONG nReserved2) { long lFrameType = pFrameInfo->nType; if (lFrameType == T_YV12) { //cv::Mat dst(pFrameInfo->nHeight, pFrameInfo->nWidth, // CV_8UC3); // 8UC3表示8bit uchar无符号类型,3通道值 dst.create(pFrameInfo->nHeight, pFrameInfo->nWidth, CV_8UC3); cv::Mat src(pFrameInfo->nHeight + pFrameInfo->nHeight / 2, pFrameInfo->nWidth, CV_8UC1, (uchar *)pBuf); cv::cvtColor(src, dst, CV_YUV2BGR_YV12); pthread_mutex_lock(&mutex); g_frameList.push_back(dst); pthread_mutex_unlock(&mutex); } usleep( 1000); //cv::Mat src(pFrameInfo->nHeight + pFrameInfo->nHeight / 2, pFrameInfo->nWidth, CV_8UC1, (uchar *)pBuf); //cv::cvtColor(src, dst, CV_YUV2BGR_YV12); //cv::imshow("bgr", dst); //pthread_mutex_lock(&mutex); //g_frameList.push_back(dst); //pthread_mutex_unlock(&mutex); //vw << dst; //cv::waitKey(10); } void CALLBACK g_RealDataCallBack_V30(LONG lRealHandle, DWORD dwDataType, BYTE *pBuffer, DWORD dwBufSize,void* dwUser) { /* if (dwDataType == 1) { PlayM4_GetPort(&nPort); PlayM4_SetStreamOpenMode(nPort, STREAME_REALTIME); PlayM4_OpenStream(nPort, pBuffer, dwBufSize, 1024 * 1024); PlayM4_SetDecCallBackEx(nPort, DecCBFun, NULL, NULL); PlayM4_Play(nPort, h); } else { BOOL inData = PlayM4_InputData(nPort, pBuffer, dwBufSize); }*/ DWORD dRet; switch (dwDataType) { case NET_DVR_SYSHEAD: //系统头 if (!PlayM4_GetPort(&nPort)) //获取播放库未使用的通道号 { break; } if (dwBufSize > 0) { if (!PlayM4_SetStreamOpenMode(nPort, STREAME_REALTIME)) { dRet = PlayM4_GetLastError(nPort); break; } if (!PlayM4_OpenStream(nPort, pBuffer, dwBufSize, 1024 * 1024)) { dRet = PlayM4_GetLastError(nPort); break; } //设置解码回调函数 只解码不显示 // 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, h)) { dRet = PlayM4_GetLastError(nPort); break; } //打开音频解码, 需要码流是复合流 if (!PlayM4_PlaySound(nPort)) { dRet = PlayM4_GetLastError(nPort); break; } } break; //usleep(500); case NET_DVR_STREAMDATA: //码流数据 if (dwBufSize > 0 && nPort != -1) { BOOL inData = PlayM4_InputData(nPort, pBuffer, dwBufSize); while (!inData) { sleep( 100); inData = PlayM4_InputData(nPort, pBuffer, dwBufSize); std:: cerr << "PlayM4_InputData failed \n" << std:: endl; } } break; } } void CALLBACK g_ExceptionCallBack(DWORD dwType, LONG lUserID, LONG lHandle, void *pUser) { char tempbuf[ 256] = { 0}; std:: cout << "EXCEPTION_RECONNECT = " << EXCEPTION_RECONNECT << std:: endl; switch(dwType) { case EXCEPTION_RECONNECT: //预览时重连 printf( "pyd----------reconnect--------%d\n", time( NULL)); break; default: break; } } void *RunIPCameraInfo(void *) { char IP[] = "192.168.**.***"; //海康威视网络摄像头的ip char UName[] = "****"; //海康威视网络摄像头的用户名 char PSW[] = "*****"; //海康威视网络摄像头的密码 NET_DVR_Init(); NET_DVR_SetConnectTime( 2000, 1); NET_DVR_SetReconnect( 1000, true); NET_DVR_SetLogToFile( 3, "./sdkLog"); NET_DVR_DEVICEINFO_V30 struDeviceInfo = { 0}; NET_DVR_SetRecvTimeOut( 5000); lUserID = NET_DVR_Login_V30(IP, 8000, UName, PSW, &struDeviceInfo); NET_DVR_SetExceptionCallBack_V30( 0, NULL, g_ExceptionCallBack, NULL); long lRealPlayHandle; NET_DVR_CLIENTINFO ClientInfo = { 0}; ClientInfo.lChannel = 1; ClientInfo.lLinkMode = 0; ClientInfo.hPlayWnd = 0; ClientInfo.sMultiCastIP = NULL; //lRealPlayHandle = NET_DVR_RealPlay_V30(lUserID, &ClientInfo, PsDataCallBack, NULL, 0); lRealPlayHandle = NET_DVR_RealPlay_V30(lUserID, &ClientInfo, g_RealDataCallBack_V30, NULL, 0); //NET_DVR_SaveRealData(lRealPlayHandle, "/home/lds/source/yuntai.mp4"); if (lRealPlayHandle < 0) { printf( "pyd1---NET_DVR_RealPlay_V30 error\n"); } sleep( -1); NET_DVR_Cleanup(); } int main(int argc, char *argv[]) { pthread_t getframe; pthread_mutex_init(&mutex, NULL); int ret; ret = pthread_create(&getframe, NULL, RunIPCameraInfo, NULL); if(ret!= 0) { printf( "Create pthread error!\n"); } cv::Mat image; while( 1) { pthread_mutex_lock(&mutex); if(g_frameList.size()) { std:: list<cv::Mat>::iterator it; it = g_frameList.end(); it--; image = (*(it)); if (!image.empty()) { imshow( "frame from camera",image); cv::waitKey( 1); } g_frameList.pop_front(); } g_frameList.clear(); // 丢掉旧的帧 pthread_mutex_unlock(&mutex); } return 0; }