基于Qt和C++的海康网络摄像头SDK开发,详细步骤

​ 一、准备工作

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;
    }
}

 

 

 

<think>这个错误是因为在代码中使用了`QCheckBox`,但是没有从PyQt5中导入它。在PyQt5中,`QCheckBox`位于`PyQt5.QtWidgets`模块中。因此,我们需要在导入部分添加`QCheckBox`。 解决方案: 在代码的导入部分,修改`from PyQt5.QtWidgets import ...`,确保包含`QCheckBox`。 具体修改如下: 原导入语句可能是这样的: from PyQt5.QtWidgets import (QApplication, QMainWindow, QPushButton, QWidget, QVBoxLayout, QHBoxLayout, QMessageBox, QLabel, QFileDialog, QToolBar, QComboBox, QStatusBar, QGroupBox, QSlider, QDockWidget, QProgressDialog) 我们需要在导入列表中加入`QCheckBox`。 修改后的导入语句: from PyQt5.QtWidgets import (QApplication, QMainWindow, QPushButton, QWidget, QVBoxLayout, QHBoxLayout, QMessageBox, QLabel, QFileDialog, QToolBar, QComboBox, QStatusBar, QGroupBox, QSlider, QDockWidget, QProgressDialog, QCheckBox) # 添加QCheckBox 这样,在代码中使用`QCheckBox`就不会出现未定义的错误了。 另外,在错误信息中提到的行(第851行): ui.chkTextureAnalysis = QCheckBox("启用纹理分析") 这行代码是在创建复选框控件,用于启用/禁用纹理分析功能。确保在UI初始化部分正确创建。 注意:如果还有其他未定义的控件类型,同样需要检查导入语句。 下面给出修改后的导入部分代码示例: 修改前: from PyQt5.QtWidgets import (QApplication, QMainWindow, QPushButton, QWidget, QVBoxLayout, QHBoxLayout, QMessageBox, QLabel, QFileDialog, QToolBar, QComboBox, QStatusBar, QGroupBox, QSlider, QDockWidget, QProgressDialog) 修改后: from PyQt5.QtWidgets import (QApplication, QMainWindow, QPushButton, QWidget, QVBoxLayout, QHBoxLayout, QMessageBox, QLabel, QFileDialog, QToolBar, QComboBox, QStatusBar, QGroupBox, QSlider, QDockWidget, QProgressDialog, QCheckBox) # 新增QCheckBox 同时,检查代码中是否使用了其他未导入的控件,例如`QRadioButton`、`QSpinBox`等,如果有,也需要一并导入。 由于代码较长,请确保在代码的其他部分没有类似错误(即使用了未导入的控件类)。 如果问题仍然存在,请检查整个代码中所有使用到的控件类是否都已经正确导入。 另外,在代码中创建`QCheckBox`的地方,确保变量名正确,并且在使用前已经定义。 由于错误发生在第851行,所以请检查该行之前的代码是否有语法错误,或者是否在创建`QCheckBox`之前已经正确初始化了`ui`对象。 如果按照上述修改后问题解决,则可以继续运行程序。</think>这个错误是因为在使用 `QCheckBox` 之前没有正确导入它。让我详细解释问题并提供解决方案: ### 问题原因分析 `NameError: name 'QCheckBox' is not defined` 错误表明: 1. **缺少导入语句**:代码中没有从 PyQt5 导入 QCheckBox 2. **导入位置错误**:导入语句可能放在错误的位置 3. **作用域问题**:导入语句可能不在需要使用的代码范围内 4. **拼写错误**:导入语句或类名可能有拼写错误 ### 解决方案 #### 1. 在导入部分添加 QCheckBox 在代码开头修改导入语句,添加 QCheckBox: ```python # -*- coding: utf-8 -*- import sys import os import cv2 import numpy as np from PyQt5.QtWidgets import (QApplication, QMainWindow, QPushButton, QWidget, QVBoxLayout, QHBoxLayout, QMessageBox, QLabel, QFileDialog, QToolBar, QComboBox, QStatusBar, QGroupBox, QSlider, QDockWidget, QProgressDialog, QCheckBox) # 添加 QCheckBox from PyQt5.QtCore import QRect, Qt, QSettings, QThread, pyqtSignal # ... 其余导入保持不变 ... ``` #### 2. 完整修复代码(包含所有必要导入) 如果代码中还有其他缺失的导入,这里提供完整的导入修复: ```python # -*- coding: utf-8 -*- import sys import os import cv2 import numpy as np import json import time import logging import platform from datetime import datetime from scipy import ndimage from scipy.spatial import distance # PyQt5 导入 from PyQt5.QtWidgets import ( QApplication, QMainWindow, QPushButton, QWidget, QVBoxLayout, QHBoxLayout, QMessageBox, QLabel, QFileDialog, QToolBar, QComboBox, QStatusBar, QGroupBox, QSlider, QDockWidget, QProgressDialog, QCheckBox # 添加 QCheckBox ) from PyQt5.QtCore import QRect, Qt, QSettings, QThread, pyqtSignal from PyQt5.QtGui import QImage, QPixmap # 可能需要这些用于图像显示 # 海康 SDK 导入 sys.path.append("D:\\海康\\MVS\\Development\\Samples\\Python\\BasicDemo") from MvCameraControl_class import * from MvErrorDefine_const import * from CameraParams_header import * # 自定义模块导入 from CamOperation_class import CameraOperation from PyUICBasicDemo import Ui_MainWindow # 如果使用 UI 文件生成 # 图像处理库导入 try: from skimage.feature import local_binary_pattern from skimage import exposure except ImportError: # 提供替代方案或错误处理 pass ``` #### 3. 如果使用 Qt Designer 生成的 UI 文件 如果使用 `pyuic5` 生成的 UI 文件,确保在生成的代码中已经包含 QCheckBox: 1. 检查 `PyUICBasicDemo.py` 文件 2. 确保其中包含类似这样的导入: ```python from PyQt5 import QtCore, QtGui, QtWidgets ``` 3. 在 UI 类中,检查 QCheckBox 是否已正确定义 #### 4. 完整 UI 初始化修复 在初始化 UI 部分,确保正确创建 QCheckBox: ```python # 在 __init__ 方法中或 UI 设置代码中 def setup_ui(self): # ... 其他 UI 代码 ... # 创建 QCheckBox self.chkTextureAnalysis = QCheckBox("启用纹理分析") self.chkEdgeDetection = QCheckBox("启用边缘检测") self.chkAdaptiveThreshold = QCheckBox("使用自适应阈值") # 添加到布局 self.diff_layout.addWidget(self.chkTextureAnalysis) self.diff_layout.addWidget(self.chkEdgeDetection) self.diff_layout.addWidget(self.chkAdaptiveThreshold) ``` ### 常见问题预防措施 #### 1. 使用 IDE 的自动导入功能 大多数现代 IDE(PyCharm, VSCode)可以自动添加缺失的导入: 1. 将光标放在错误行 2. 按快捷键(PyCharm 是 Alt+Enter) 3. 选择 "Import 'QCheckBox' from 'PyQt5.QtWidgets'" #### 2. 创建 PyQt5 导入辅助函数 创建一个专门处理 PyQt5 导入的函数: ```python def import_pyqt5(): """导入所有常用的 PyQt5 模块""" from PyQt5.QtWidgets import ( QApplication, QMainWindow, QPushButton, QWidget, QVBoxLayout, QHBoxLayout, QMessageBox, QLabel, QFileDialog, QToolBar, QComboBox, QStatusBar, QGroupBox, QSlider, QDockWidget, QProgressDialog, QCheckBox, QRadioButton, QSpinBox, QDoubleSpinBox ) from PyQt5.QtCore import ( Qt, QTimer, QSize, QPoint, QRect, QSettings, QThread, pyqtSignal, pyqtSlot, QObject ) from PyQt5.QtGui import ( QImage, QPixmap, QIcon, QFont, QColor, QPainter, QPen, QBrush ) return locals() # 使用方式 qt = import_pyqt5() app = qt['QApplication'](sys.argv) window = qt['QMainWindow']() checkbox = qt['QCheckBox']("启用功能") ``` #### 3. 使用通配符导入(不推荐但快速) 虽然不推荐,但在开发阶段可以临时使用: ```python from PyQt5.QtWidgets import * ``` ### 错误预防最佳实践 1. **使用 Linter 工具**: ```bash pip install pylint pyflakes pylint your_script.py ``` 2. **类型提示检查**: ```python from typing import TYPE_CHECKING if TYPE_CHECKING: from PyQt5.QtWidgets import QCheckBox def create_checkbox() -> 'QCheckBox': return QCheckBox("选项") ``` 3. **创建 GUI 组件工厂函数**: ```python def create_checkbox(text: str, parent=None) -> QCheckBox: """创建并初始化 QCheckBox""" checkbox = QCheckBox(text, parent) checkbox.setStyleSheet("font-size: 12px;") checkbox.setChecked(True) return checkbox # 使用 ui.chkTextureAnalysis = create_checkbox("启用纹理分析") ``` ###
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值