海康opencv+qt圖像處理,記錄
securityrecoginate.cpp
#include "securityrecognite.h"
#include "ui_securityrecognite.h"
//#include "includes/video/hkvision/win32/HCNetSDK.h"
//#include "includes/video/hkvision/win32/plaympeg4.h"
#include <QDebug>
#include "opencv2/photo.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
#include <QBuffer>
#define USECOLOR 1
int SecurityRecognite::m_connectTime = 0;
int SecurityRecognite::m_reconnectTime = 0;
QString SecurityRecognite::m_ipAddress = "";
int SecurityRecognite::m_port = 0;
QString SecurityRecognite::m_userName = "";
QString SecurityRecognite::m_password = "";
LONG SecurityRecognite::m_userId = -1;
NET_DVR_USER_LOGIN_INFO SecurityRecognite::m_loginInfo = {0};
NET_DVR_DEVICEINFO_V40 SecurityRecognite::m_deviceInfo = {0};
NET_DVR_PREVIEWINFO SecurityRecognite::m_struPlayInfo = {0};
LONG SecurityRecognite::m_realPlayHandle = 0;
LONG SecurityRecognite::m_channelId = 1;
LONG nPort;
HWND hWnd=NULL;
SecurityRecognite::SecurityRecognite(QWidget *parent) :
QWidget(parent),
ui(new Ui::SecurityRecognite)
{
ui->setupUi(this);
videoLayout.addWidget(&videoWidget);
videoLayout.setSpacing(1);
videoLayout.setContentsMargins(0,0,0,0);
ui->videoWidget->setLayout(&videoLayout);
}
SecurityRecognite::~SecurityRecognite()
{
delete ui;
}
void CALLBACK g_ExceptionCallBack(DWORD dwType, LONG IUserID, LONG IHandle, void *pUser)
{
char tempbuf[256] = {};
switch (dwType)
{
case EXCEPTION_RECONNECT:
printf("--------reconnect-------%d\n", time(NULL));
break;
default:
break;
}
}
void SecurityRecognite::on_pushButton_clicked()
{
qDebug() << "CALLBACK started!";
}
void 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++)
{
//int colhalf=col>>1;
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];
if((idx+col*3+2)> (1200 * widthStep))
{
//printf("row * widthStep=%d,idx+col*3+2=%d.\n",1200 * widthStep,idx+col*3+2);
}
outYuv[idx+col*3] = Y;
outYuv[idx+col*3+1] = U;
outYuv[idx+col*3+2] = V;
}
}
//printf("col=%d,row=%d.\n",col,row);
}
void CALLBACK DecCBFun(long nPort,char * pBuf,long nSize,FRAME_INFO * pFrameInfo, long nReserved1,long nReserved2)
{
long lFrameType = pFrameInfo->nType;
if(lFrameType ==T_YV12)
{
//#if USECOLOR
// //int start = clock();
// IplImage* pImgYCrCb = cvCreateImage(cvSize(pFrameInfo->nWidth,pFrameInfo->nHeight), 8, 3);//得到圖像的Y分量
// yv12toYUV(pImgYCrCb->imageData, pBuf, pFrameInfo->nWidth,pFrameInfo->nHeight,pImgYCrCb->widthStep);//得到全部RGB圖像
// IplImage* pImg = cvCreateImage(cvSize(pFrameInfo->nWidth,pFrameInfo->nHeight), 8, 3);
// cvCvtColor(pImgYCrCb,pImg,CV_YCrCb2RGB);
// //int end = clock();
//#else
// IplImage* pImg = cvCreateImage(cvSize(pFrameInfo->nWidth,pFrameInfo->nHeight), 8, 1);
// memcpy(pImg->imageData,pBuf,pFrameInfo->nWidth*pFrameInfo->nHeight);
//#endif
// //printf("%d\n",end-start);
// cvShowImage("IPCamera",pImg);
// cv::Mat *frame = (cv::Mat *)pImg;
// cv::Mat frame;
// qDebug() <<"frame in<<<<<<<<<<";
// frame.create(cvSize(pFrameInfo->nWidth, pFrameInfo->nHeight),CV_8UC3);
// memcpy(frame.data, pBuf, pFrameInfo->nWidth*pFrameInfo->nHeight);
// cvWaitKey(100);
cv::Mat dst(pFrameInfo->nHeight,pFrameInfo->nWidth,CV_8UC3);//這裏nHeight爲720,nWidth爲1280,8UC3表示8bit uchar 無符號類型,3通道值
cv::Mat src(pFrameInfo->nHeight + pFrameInfo->nHeight/2,pFrameInfo->nWidth,CV_8UC1,(uchar*)pBuf);
cvtColor(src,dst,CV_YUV2BGR_YV12);
// imshow("bgr",dst);
// cv::waitKey(1);
// cv::VideoCapture cap;
// cap.open(pBuf);
// for (;;) {
// if(dst.empty())
// {
// qDebug() << ">>>>>>>>>>pBuf catched nothing!!<<<<<<<<<<<<<";
// return;
// }else {
// qDebug() << ">>>>>>>>>>pBuf has data!!<<<<<<<<<<<<<";
//}
// QJsonObject replyjson = dial_reading(dst);
// qDebug() << replyjson;
// }
// 此時是YV12格式的視頻數據,保存在pBuf中,可以fwrite(pBuf,nSize,1,Videofile);
// fwrite(pBuf,nSize,1,cap);
// fwrite()
}
/***************
else if (lFrameType ==T_AUDIO16)
{
//此時是音頻數據,數據保存在pBuf中,可以fwrite(pBuf,nSize,1,Audiofile);
}
else
{
}
*******************/
}
///實時流回調
void CALLBACK fRealDataCallBack(LONG lRealHandle,DWORD dwDataType,BYTE *pBuffer,DWORD dwBufSize,void *pUser)
{
DWORD dRet;
switch (dwDataType)
{
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;
}
//設置解碼回調函數 只解碼不顯示
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,hWnd))
{
dRet=PlayM4_GetLastError(nPort);
break;
}
//打開音頻解碼, 需要碼流是複合流
if (!PlayM4_PlaySound(nPort))
{
dRet=PlayM4_GetLastError(nPort);
break;
}
}
break;
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);
OutputDebugString(L"PlayM4_InputData failed \n");
}
// if (!PlayM4_InputData(nPort, pBuffer, dwBufSize))
// {
// std::cout << "fail input data" << std::endl;
// }
// else
// {
// std::cout << "success input data" << std::endl;
// }
// }
break;
}
}
}
void SecurityRecognite::on_startPushButton_clicked(){
// PlatformManager::stopRealPlay();
PlatformManager::init();
NET_DVR_SetExceptionCallBack_V30(0, NULL, g_ExceptionCallBack, NULL);
PlatformManager::registerDevice();
// int iRet;
// //獲取通道 1 的壓縮參數
// DWORD dwReturnLen;
// NET_DVR_COMPRESSIONCFG_V30 struParams = { 0 };
// iRet = NET_DVR_GetDVRConfig(m_userId, NET_DVR_GET_COMPRESSCFG_V30, 1, &struParams, \
// sizeof(NET_DVR_COMPRESSIONCFG_V30), &dwReturnLen);
// if (!iRet)
// {
// printf("NET_DVR_GetDVRConfig NET_DVR_GET_COMPRESSCFG_V30 error.\n");
// NET_DVR_Logout(m_userId);
// NET_DVR_Cleanup();
// return;
// }
// //設置通道 1 的壓縮參數
// struParams.struNormHighRecordPara.dwVideoBitrate = 0.5;
// iRet = NET_DVR_SetDVRConfig(m_userId, NET_DVR_SET_COMPRESSCFG_V30, 1, \
// &struParams, sizeof(NET_DVR_COMPRESSIONCFG_V30));
// if (!iRet)
// {
// printf("NET_DVR_GetDVRConfig NET_DVR_SET_COMPRESSCFG_V30 error.\n");
// NET_DVR_Logout(m_userId);
// NET_DVR_Cleanup();
// return;
// }
// //獲取通道 1 的壓縮參數
// iRet = NET_DVR_GetDVRConfig(m_userId, NET_DVR_GET_COMPRESSCFG_V30, 1, \
// &struParams, sizeof(NET_DVR_COMPRESSIONCFG_V30), &dwReturnLen);
// if (!iRet)
// {
// printf("NET_DVR_GetDVRConfig NET_DVR_GET_COMPRESSCFG_V30 error.\n");
// NET_DVR_Logout(m_userId);
// NET_DVR_Cleanup();
// return;
// }
// printf("Video Bitrate is %d\n", struParams.struNormHighRecordPara.dwVideoBitrate);
NET_DVR_PREVIEWINFO struPlayInfo = {0};
#ifdef WIN32
struPlayInfo.hPlayWnd = (HWND)videoWidget.winId(); //
#else
struPlayInfo.hPlayWnd = videoWidget.winId();
#endif
//(HWND)ui->opticalVideoWidget->winId(); //NULL; //窗口爲空,設置SDK不解碼只取流
struPlayInfo.lChannel = 1; //Channel number 設備通道
struPlayInfo.dwStreamType = 0;// 碼流類型,0-主碼流,1-子碼流,2-碼流3,3-碼流4, 4-碼流5,5-碼流6,7-碼流7,8-碼流8,9-碼流9,10-碼流10
struPlayInfo.dwLinkMode = 0;// 0:TCP方式,1:UDP方式,2:多播方式,3 - RTP方式,4-RTP/RTSP,5-RSTP/HTTP
struPlayInfo.bBlocked = 1; //0-非阻塞取流, 1-阻塞取流, 如果阻塞SDK內部connect失敗將會有5s的超時才能夠返回,不適合於輪詢取流操作.
PlatformManager::setStruPlayInfo(struPlayInfo);
//設置獲取實時視頻流的回調函數,先得到實時視頻流,再對視頻流解碼成BGR格式
LONG lRealPlayHandle = NET_DVR_RealPlay_V40(PlatformManager::getUserId(),
&struPlayInfo, fRealDataCallBack, nullptr);
PlatformManager::setRealPlayHandle(lRealPlayHandle);
PlatformManager::setChannelId(1);
if (lRealPlayHandle < 0)
{
//QMessageBox::information(this, tr("NET_DVR_RealPlay_V40"), tr("SDK_LAST_ERROR = %1").arg(NET_DVR_GetLastError()));
qDebug() << "error: " << NET_DVR_GetLastError();
NET_DVR_Logout(PlatformManager::getUserId());
NET_DVR_Cleanup();
return;
}
// Sleep(-1);
//關閉預覽
// if(!NET_DVR_StopRealPlay(lRealPlayHandle))
// {
// printf("NET_DVR_StopRealPlay error! Error number: %d\n",NET_DVR_GetLastError());
// return;
// }
// //註銷用戶
// NET_DVR_Logout(m_userId);
// NET_DVR_Cleanup();
// return;
}
securityrecognite.h
#ifndef SECURITYRECONITE_H
#define SECURITYRECONITE_H
#include <QWidget>
#include "stdio.h"
#include <iostream>
#include "windows.h"
#include "includes/video/hkvision/win32/HCNetSDK.h"
//#include "includes/video/hkvision/win32/PlayM4.h"
#if defined(WIN32)
#include "windows.h"
#include "includes/video/hkvision/win32/plaympeg4.h"
#endif
#include "time.h"
#include "platform/platformmanager.h"
#include <basevideowidget.h>
#include <QHBoxLayout>
#include "includes/video/opencv/dial_reading.h"
namespace Ui {
class SecurityRecognite;
}
class SecurityRecognite : public QWidget
{
Q_OBJECT
public:
explicit SecurityRecognite(QWidget *parent = nullptr);
~SecurityRecognite();
static int m_port;
private slots:
void on_startPushButton_clicked();
void on_pushButton_clicked();
private:
Ui::SecurityRecognite *ui;
static int m_connectTime;
static int m_reconnectTime;
static QString m_ipAddress;
static QString m_userName;
static QString m_password;
static LONG m_userId;
static NET_DVR_USER_LOGIN_INFO m_loginInfo;
static NET_DVR_DEVICEINFO_V40 m_deviceInfo;
static NET_DVR_PREVIEWINFO m_struPlayInfo;
static LONG m_realPlayHandle;
static LONG m_channelId;
private:
BaseVideoWidget videoWidget;
QHBoxLayout videoLayout;
static void initConnectionInfo();
};
#endif // SECURITYRECONITE_H