一、准备工作
1.从 Qt 官方网站(https://www.qt.io/download - open - source)下载适合您操作系统的 Qt 版本并安装。我这里安装的是Qt5.14
2.下载海康摄像头SDK
在网站(https://open.hikvision.com/download/5cda567cf47ae80dd41a54b3?type=10)可以下载海康SDK,我这里下载的是win64位的SDK
解压之后的文件内容如下:
其中lib文件夹是库文件目录下所有的.lib的库,以后会用到。
3.下载设备网络搜索工具
在海康威视官网上,服务支持,工具专区里面下载并安装设备网络搜索工具。
电脑连接摄像头,打开设备网络搜索工具
4.设置IP地址
在设备网络搜索工具里面完成在线摄像头IP地址的修改,输入自己的密码保存。我这里设置的IP地址为192.168.43.1
之后还要在电脑上完成IP地址的设置。在控制面板上面搜索,查看网络连接,找到以太网2
右击进入属性页面,找到Internet协议版本4(TCP/IPv4),选择使用下面的IP地址,进行如下IP地址设置,设置IP地址必须为192.168.43.X,X可以为任意不为1的数。
5.网络连接
在浏览器中输入设备的IP地址,然后登陆即可(默认的账号为admin,密码是在设备网络搜索工具设置的密码
如果第一次进去没有画面就需要下载插件,点击右上角的插件下载即可,可以看到能在网页里面出现摄像头画面。
二、建立qt项目
首先海康摄像头开发需要qt里面配置MSVC的编译环境,可以在工具,选项里面配置
我这里电脑安装的是2022的VS,qt是qt5,所以MSVC是红色的,但是可以正常使用。
新建qt的mainwindow,运行之后出现两个文件夹,一个test(项目名称),一个build开头的文件夹。
在test文件夹里面新建一个MVS的文件夹,里面再新建两个文件夹,一个命名为lib,一个命名为include。lib文件夹里面放所有的.lib库文件,include文件夹里面放所有的.h头文件。库文件和头文件在SDK包解压出来文件里面。
之后在build文件夹里面新建一个命名为bin的文件夹,将所有的.dll文件放在里面。如果图方便也可以将库文件目录下所以文件包括.lib放在里面。
三、编写程序
在将库文件和头文件添加到项目中后,打开.pro的项目文件,在pro文件里面添加路径以及库文件。
里面的.pro项目文件的代码如下:
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
MOC_DIR = temp/moc
RCC_DIR = temp/rcc
UI_DIR = temp/ui
OBJECTS_DIR = temp/obj
DESTDIR = bin
#QMAKE_CXXFLAGS += /utf-8
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
MvCamera.cpp \
MvCamera.cpp \
main.cpp \
mainwindow.cpp
HEADERS += \
MvCamera.h \
mainwindow.h
FORMS += \
mainwindow.ui
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
#相机SDK
INCLUDEPATH += $$PWD/MVS/include
DEPENDPATH += $$PWD/MVS/include
#添加库文件
LIBS += -L$$PWD/MVS/lib -lHCNetSDK
#LIBS += -L$$PWD/MVS/lib -lHCCore.lib
#LIBS += -L$$PWD/MVS/lib -lPlayCtrl.lib
#LIBS += -L$$PWD/MVS/lib -lGdiPlus.lib
#LIBS += -L$$PWD/MVS/lib -lHCAlarm.lib
#LIBS += -L$$PWD/MVS/lib -lHCGeneralCfgMgr.lib
#LIBS += -L$$PWD/MVS/lib -lHCPreview.lib
#LIBS += -L$$PWD/MVS/lib -lMvCameraControl.lib
#win32 {
# LIBS += -LD:/Anaconda/libs -lpython311
# }
#INCLUDEPATH += C:/Users/Andy/AppData/Roaming/Python/Python311/site-packages/paddle
RESOURCES += \
res.qrc
之后可以在.ui界面在拖动各种控件,完成界面的设计
接下来就是视频播放的代码,我在这里新建了一个MvCamera.h以及MvCamera.cpp的文件
在mainwindow.cpp里面输入自己的IP,用户名,密码登录,可以在ui界面的widget里面播放摄像头画面。这里有一些导入python深度学习模型的代码,我注释掉了,与本文无关,里面只有开始播放,停止播放以及一些窗口操作的代码,欢迎大家完善补充。代码我也发布了。
代码如下:
1.mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QCoreApplication>
#include <QProcess>
#include <QApplication>
#include <QDebug>
#include <QMainWindow>
#include "QPushButton"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_btn_start_clicked();
void on_btn_stop_clicked();
void on_btn_close_clicked();
void on_btn_max_clicked();
void on_btn_min_clicked();
void on_btn_normal_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
2.MvCamera.h
#ifndef HASCAMERA_H
#define HASCAMERA_H
#include "HCNetSDK.h"
#include "plaympeg4.h"
#include "DecodeCardSdk.h"
#include "DataType.h"
#include <QThread>
#include <QVector>
#include <QMutex>
#include <QMap>
using namespace std;
typedef struct STRU_CHANNEL_INFO
{
char chChanName[40]; //通道名称
int iChanIndex; //监控通道号 = 数组索引+startchan
int iPicResolution; //图片分辨率
int iPicQuality; //图片质量
char chAccessChanIP[16]; //ip接入通道的ip地址
BOOL bEnable; //是否有效
NET_DVR_DECODERCFG_V30 struDecodercfg; //通道的解码器信息
STRU_CHANNEL_INFO()
{
chChanName[0] ='\0';
iChanIndex = -1;
iPicResolution = 0;
iPicQuality = 2;
chAccessChanIP[0] = '\0';
bEnable = FALSE;
}
}CHANNEL_INFO,*pCHANNEL_INFO;
typedef struct STRU_DEVICE_INFO
{
LONG lLoginID;
int iDeviceChanNum; //设备的通道数
int iStartChan; //设备开始通道号
int iIPChanNum; //最大数字通道个数
int iIPStartChan; //数字通道起始通道号
int iEnableChanNum; //有效通道数
BOOL bIPRet; //是否支持ip接入
CHANNEL_INFO struChanInfo[MAX_CHANNUM_V30];
STRU_DEVICE_INFO()
{
lLoginID = -1;
iDeviceChanNum = -1;
iStartChan = 0;
iIPChanNum = 0;
iEnableChanNum = -1;
bIPRet = FALSE;
}
}LOCAL_DEVICE_INFO,*pLOCAL_DEVICE_INFO;
//海康相机
class HASCamera : public QObject
{
Q_OBJECT
public:
static HASCamera* GetInstance()
{
static HASCamera s_Instance;
return &s_Instance;
}
HASCamera();
~HASCamera();
//登录
bool login(const QString &ip, int port, const QString &username, const QString &password);
//播放
bool startPlay(const int& iChanIndex,const int& winId);
//停止
void stopPlay();
private:
//登录信息
LOCAL_DEVICE_INFO m_struDeviceInfo;
//播放句柄
LONG m_lPlayHandle;
};
#endif // HASCAMERA_H
3.main.cpp
#include "mainwindow.h"
#include <QCoreApplication>
#include <QProcess>
#include <QApplication>
#include <QDebug>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// //加载paddle_model.py模型
// QProcess process;
// QStringList args;
// args << "paddle_model.py";
// process.start("python", args);
// process.waitForFinished();
// //判断模型是否正确加载
// if (process.exitCode() == 0)
// {
// qDebug() << "Python script executed successfully";
// qDebug() << "Output: " << process.readAllStandardOutput();
// }
// else
// {
// qDebug() << "Error executing Python script";
// qDebug() << "Error output: " << process.readAllStandardError();
// }
MainWindow w;
w.show();
return a.exec();
}
4.mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "HCNetSDK.h"
#include <plaympeg4.h>
#include <DecodeCardSdk.h>
#include <DataType.h>
#include "MvCamera.h"
#include "QPushButton"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
//显示父类窗口mainwindow
ui->setupUi(this);
this->setWindowIcon(QIcon(":/res/hkc.png"));
HASCamera::GetInstance()->login("192.168.43.1",8000,"admin","密码");
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_btn_start_clicked()
{
HASCamera::GetInstance()->startPlay(0,ui->widget->winId());
}
void MainWindow::on_btn_close_clicked()
{
close();
}
void MainWindow::on_btn_max_clicked()
{
showMaximized();
}
void MainWindow::on_btn_min_clicked()
{
showMinimized();
}
void MainWindow::on_btn_normal_clicked()
{
showNormal();
}
void MainWindow::on_btn_stop_clicked()
{
HASCamera::GetInstance()->stopPlay();
}
5.MvCamera.cpp
#include "MVCamera.h"
#include <QDebug>
#include <QImage>
#include <QCoreApplication>
#include <QTextCodec>
#include <QBuffer>
#include <QDir>
#include "HCNetSDK.h"
#include <plaympeg4.h>
#include <DecodeCardSdk.h>
#include <DataType.h>
HASCamera::HASCamera()
{
// 初始化
NET_DVR_Init();
}
HASCamera::~HASCamera()
{
NET_DVR_Logout(m_struDeviceInfo.lLoginID);
NET_DVR_Cleanup();
}
//登录
bool HASCamera::login(const QString &ip, int port, const QString &username, const QString &password)
{
NET_DVR_DEVICEINFO_V30 DeviceInfoTmp;
memset(&DeviceInfoTmp,0,sizeof(NET_DVR_DEVICEINFO_V30));
LONG lLoginID = NET_DVR_Login_V30(ip.toLocal8Bit().data(), port,
username.toLocal8Bit().data(),
password.toLocal8Bit().data(),
&DeviceInfoTmp);
if(lLoginID == -1)
{
DWORD err=NET_DVR_GetLastError();
qDebug()<<"错误代码:"<<err;
return false;
}
m_struDeviceInfo.lLoginID = lLoginID;
m_struDeviceInfo.iDeviceChanNum = DeviceInfoTmp.byChanNum;
m_struDeviceInfo.iIPChanNum = DeviceInfoTmp.byIPChanNum;
m_struDeviceInfo.iStartChan = DeviceInfoTmp.byStartChan;
m_struDeviceInfo.iIPStartChan = DeviceInfoTmp.byStartDChan;
return true;
}
//开始播放
bool HASCamera::startPlay(const int &iChanIndex,const int& winId)
{
NET_DVR_CLIENTINFO ClientInfo;
ClientInfo.hPlayWnd = (HWND)winId;
ClientInfo.lChannel = iChanIndex + 1;
ClientInfo.lLinkMode = 0;
ClientInfo.sMultiCastIP = NULL;
m_lPlayHandle = NET_DVR_RealPlay_V30(m_struDeviceInfo.lLoginID,&ClientInfo,NULL,NULL,TRUE);
if(-1 == m_lPlayHandle)
{
DWORD err=NET_DVR_GetLastError();
qDebug()<<"错误代码:"<<err;
return false;
}
return true;
}
//停止播放
void HASCamera::stopPlay()
{
if(m_lPlayHandle != -1)
{
NET_DVR_StopRealPlay(m_lPlayHandle);
m_lPlayHandle=-1;
}
}