Qt下集成大华网络相机SDK示例开发

文章目录

  • 前言
  • 一、下载并集成大华网络相机SDK
  • 二、示例实现功能
  • 三、示例完整代码
  • 四、下载链接
  • 总结


前言

近期在Qt环境下进行大华网络相机的使用,发现官网下载的SDK中提供的示例没有Qt的demo,通过学习其提供的MFC示例代码,我在这里也实现了一个比较简单的Qt下调用大华网络相机的示例程序,并将相关代码展现出来以便大家学习,如有错误之处,欢迎大家批评指正。

项目效果
请添加图片描述


提示:以下是本篇文章正文内容,下面案例可供参考

一、下载并集成大华网络相机SDK

到大华官网进行下载:大华设备网络SDK,也可以通过文末我的百度网盘链接下载本示例使用到的SDK(建议直接官网进行下载,有详细的示例文档及函数接口说明)

在官网下根据项目需求选择对应的SDK,下面是本示例使用到的:
在这里插入图片描述

在集成该SDK时,我是把需要用到的h和lib文件打包在一个文件夹内,然后放在项目pro文件的同级目录下,然后在pro文件中添加下列代码:(也可以直接在Qt中通过添加库的方式进行集成)

#SDK
INCLUDEPATH += $$PWD/SDK/Includes
DEPENDPATH += $$PWD/SDK/Includes
LIBS += -L$$PWD/SDK/Lib/ -ldhnetsdk

SDK文件夹内容如图(dll文件夹中存放程序运行时需要的dll,运行时需要放在exe同级目录下)
在这里插入图片描述

二、示例实现功能

在我的示例项目代码中有详细的注释,这里就不对各功能一一介绍了:

1.绑定窗口句柄实时显示相机数据:

//开始
void Widget::on_pb_start_clicked()
{if(0 != m_lRealPlayHandle){CLIENT_StopRealPlay(m_lRealPlayHandle);m_lRealPlayHandle = 0;ui->pb_start->setText("开始");}else{int nChannel = 0;HWND hWnd = reinterpret_cast<HWND>(ui->lb_show->winId());m_lRealPlayHandle = CLIENT_StartRealPlay(m_lLoginHandle, nChannel, hWnd, DH_RType_Realplay, NULL, NULL, NULL);if (0 == m_lRealPlayHandle){QMessageBox::information(this,"提示","开始失败!");return;}ui->pb_start->setText("停止");CLIENT_RenderPrivateData(m_lRealPlayHandle, TRUE);}
}

2.开启智能事件订阅,绑定事件回调:

//订阅
void Widget::on_pb_event_clicked()
{if (0 != m_lRealLoadHandle){CLIENT_StopLoadPic(m_lRealLoadHandle);m_lRealLoadHandle = 0;ui->pb_event->setText("订阅");}else{int nChannel = 0;m_lRealLoadHandle = CLIENT_RealLoadPictureEx(m_lLoginHandle, nChannel, EVENT_IVS_ALL, TRUE, EventCallback, (LDWORD)this, NULL);if (m_lRealLoadHandle == 0){QMessageBox::information(this,"提示","订阅失败!");return;}ui->pb_event->setText("停止订阅");}
}//事件回调
int CALLBACK Widget::EventCallback(LLONG lAnalyzerHandle, DWORD dwAlarmType, void* pAlarmInfo, BYTE *pBuffer, DWORD dwBufSize, LDWORD dwUser, int nSequence, void *reserved)
{if(0 == dwUser){return -1;}//绊线入侵事件if(dwAlarmType == EVENT_IVS_CROSSLINEDETECTION)   //EVENT_IVS_HUMANTRAIT{//检查是否有有效的图像数据if (pBuffer == NULL || dwBufSize == 0){LOGDEBUG<<"事件回调图像数据无效";return -1;}//保存图像QPointer<Widget> camera = reinterpret_cast<Widget*>(dwUser);QMetaObject::invokeMethod(camera, [=](){//这里SaveImage中有直接操作ui控件,所以需要使用QMetaObject::invokeMethodcamera->SaveImage(pBuffer,dwBufSize);});}return 0;
}

3.主动抓图,触发抓图回调并保存图像:

//抓图
void Widget::on_pb_get_clicked()
{if (0 != m_lLoginHandle){//主动抓图SNAP_PARAMS snapparams = {0};snapparams.Channel = 0;snapparams.mode = 0;snapparams.CmdSerial = 0;BOOL flag = CLIENT_SnapPicture(m_lLoginHandle, snapparams);if (!flag){QMessageBox::information(this,"提示","抓图失败!");}else{ui->pte_text->appendPlainText("开始抓图");}}
}//抓图回调
void CALLBACK Widget::CaptureCallback(LLONG ILoginID, BYTE *pBuf, UINT RevLen, UINT EncodeType, DWORD CmdSerial, LDWORD dwUser)
{//跨线程调用,相机回调函数是有另开子线程的QPointer<Widget> camera = reinterpret_cast<Widget*>(dwUser);QMetaObject::invokeMethod(camera, [=](){//多个相机就需要//if(ILoginID == camera->m_lLoginHandle){camera->OnOnePicture(ILoginID,pBuf,RevLen,EncodeType,CmdSerial);}});
}//抓图
void Widget::OnOnePicture(LLONG ILoginID, BYTE *pBuf, UINT RevLen, UINT EncodeType, UINT CmdSerial)
{//检查输入合法性if(!pBuf || RevLen == 0){LOGDEBUG<<"抓图图像数据无效";return;}//保存图像SaveImage(pBuf,RevLen);
}//保存图像
bool Widget::SaveImage(BYTE *pBuffer, DWORD dwBufSize)
{//定义输出文件名static int num = 0;num++;char outputFileName[256];snprintf(outputFileName, sizeof(outputFileName), "output_image_%d.jpg", num);//打开文件以写入二进制数据FILE* file = fopen(outputFileName, "wb");if (file == NULL){LOGDEBUG<<"图像保存失败!";return false;}//写入图像数据到文件fwrite(pBuffer, 1, dwBufSize, file);//关闭文件fclose(file);LOGDEBUG<<"图像保存成功!";ui->pte_text->appendPlainText("图像保存成功!");return true;
}

4.鼠标事件过滤,进行云台控制

//事件过滤器
bool Widget::eventFilter(QObject *watched, QEvent *event)
{if(watched ==ui->lb_show){QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);if (event->type() == QEvent::MouseButtonPress){//鼠标按下,记录起点m_startPos = mouseEvent->pos();m_currentPos = m_startPos;m_drawing = true;return true;}else if (event->type() == QEvent::MouseMove && m_drawing){//鼠标移动,更新终点并绘制临时矩形m_currentPos = mouseEvent->pos();return true;}else if (event->type() == QEvent::MouseButtonRelease && m_drawing){//鼠标释放,绘制最终矩形m_drawing = false;m_currentPos = mouseEvent->pos();//坐标转换QRect winRect = ui->lb_show->rect();double xScale =  winRect.width() / 2560.0;double yScale =  winRect.height() / 1440.0;m_startPos = QPoint(m_startPos.x()/xScale,m_startPos.y()/yScale);m_currentPos = QPoint(m_currentPos.x()/xScale,m_currentPos.y()/yScale);UpDateShow(m_startPos,m_currentPos);return true;}}return QWidget::eventFilter(watched,event);
}

5.相机断线与重连回调:

//设备断连回调
void CALLBACK Widget::DisConnect(LLONG lLoginID, char *pchDVRIP, LONG nDVRPort, LDWORD dwUser)
{if(0 != dwUser){QPointer<Widget> camera = reinterpret_cast<Widget*>(dwUser);camera->SetConnect(0);}
}//设备重连回调
void CALLBACK Widget::ReConnect(LLONG lLoginID, char *pchDVRIP, LONG nDVRPort, LDWORD dwUser)
{if(0 != dwUser){QPointer<Widget> camera = reinterpret_cast<Widget*>(dwUser);camera->SetConnect(1);}
}

、、、、、、

三、示例完整代码

1.DahuaDemo.pro

QT       += core guigreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsCONFIG += c++11DEFINES += QT_DEPRECATED_WARNINGSSOURCES += \main.cpp \widget.cppHEADERS += \widget.h \FORMS += \widget.uiqnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target#SDK
INCLUDEPATH += $$PWD/SDK/Includes
DEPENDPATH += $$PWD/SDK/Includes
LIBS += -L$$PWD/SDK/Lib/ -ldhnetsdk

2.widget.h

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QObject>
#include <QMessageBox>
#include <QPen>
#include <QPainter>
#include <QMouseEvent>
#include <QLabel>
#include <QRect>
#include <QTime>
#include <QTimer>
#include <QPointer>
#include <QDebug>#include "dhnetsdk.h"#define LOGDEBUG qDebug()<<QTime::currentTime().toString("[hh:mm:ss:zzz]")using namespace std;struct HUMAN_TRAIT_EVENT_INFO
{DEV_EVENT_HUMANTRAIT_INFO stuEvent;BYTE* pBuf;int nBufSize;
};QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();void InitWidget();void InitNetSDK();void SetConnect(int type);bool SaveImage(BYTE *pBuffer, DWORD dwBufSize);void UpDateShow(const QPoint &start, const QPoint &end);void PtzExtControl(DWORD dwCommand, DWORD dwParam = 0);void OnOnePicture(LLONG ILoginID, BYTE *pBuf, UINT RevLen, UINT EncodeType, UINT CmdSerial);protected:bool eventFilter(QObject *watched, QEvent *event);private:static void CALLBACK DisConnect(LLONG lLoginID, char *pchDVRIP, LONG nDVRPort, LDWORD dwUser);static void CALLBACK ReConnect(LLONG lLoginID, char *pchDVRIP, LONG nDVRPort, LDWORD dwUser);static void CALLBACK CaptureCallback(LLONG ILoginID, BYTE *pBuf, UINT RevLen, UINT EncodeType, DWORD CmdSerial, LDWORD dwUser);static int CALLBACK EventCallback(LLONG lAnalyzerHandle, DWORD dwAlarmType, void* pAlarmInfo, BYTE *pBuffer, DWORD dwBufSize, LDWORD dwUser, int nSequence, void *reserved);private slots:void on_pb_login_clicked();void on_pb_start_clicked();void on_pb_event_clicked();void on_pb_get_clicked();private:Ui::Widget *ui;LLONG m_lLoginHandle;      //登录句柄LLONG m_lRealPlayHandle;   //播放句柄LLONG m_lRealLoadHandle;   //订阅句柄int m_posX;   //水平坐标int m_posY;   //垂直坐标int m_posZoom;    //变倍bool m_drawing;   //绘制标志QPoint m_startPos;     //鼠标起点QPoint m_currentPos;   //鼠标当前点};
#endif // WIDGET_H

3.widget.cpp

#include "widget.h"
#include "ui_widget.h"#pragma execution_character_set("utf-8")//LLONG m_lHandle;Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);InitWidget();
}Widget::~Widget()
{delete ui;if(0 != m_lLoginHandle){on_pb_login_clicked();}CLIENT_Cleanup();
}//初始化界面
void Widget::InitWidget()
{m_lLoginHandle = 0;m_lRealPlayHandle = 0;m_lRealLoadHandle = 0;ui->le_ip->setText("192.168.1.108");ui->le_port->setText("37777");ui->le_user->setText("admin");ui->le_password->setText("12345678");ui->lb_show->installEventFilter(this);//初始化相机InitNetSDK();}//初始化相机
void Widget::InitNetSDK()
{//初始化BOOL ret = CLIENT_Init(DisConnect, (LDWORD)this);if (ret){LOG_SET_PRINT_INFO  stLogPrintInfo = {sizeof(stLogPrintInfo)};CLIENT_LogOpen(&stLogPrintInfo);//初始化成功后设置网络参数//目前仅单独设置获取设备信息时间(部分设备因性能问题,没法在默认时间内完成,其他参数暂时保持默认)NET_PARAM stuNetParam = {0};stuNetParam.nGetDevInfoTime = 3000;stuNetParam.nPicBufSize = 10*1024*1024;CLIENT_SetNetworkParam(&stuNetParam);//设置回调CLIENT_SetSnapRevCallBack(CaptureCallback,(LDWORD)this);CLIENT_SetAutoReconnect(ReConnect, (LDWORD)this);}else{QMessageBox::information(this,"提示","初始化SDK失败!");}
}//设置连接
void Widget::SetConnect(int type)
{if(type == 0){LOGDEBUG<<"相机断连";}else{LOGDEBUG<<"相机重连";}
}//保存图像
bool Widget::SaveImage(BYTE *pBuffer, DWORD dwBufSize)
{//定义输出文件名static int num = 0;num++;char outputFileName[256];snprintf(outputFileName, sizeof(outputFileName), "output_image_%d.jpg", num);//打开文件以写入二进制数据FILE* file = fopen(outputFileName, "wb");if (file == NULL){LOGDEBUG<<"图像保存失败!";return false;}//写入图像数据到文件fwrite(pBuffer, 1, dwBufSize, file);//关闭文件fclose(file);LOGDEBUG<<"图像保存成功!";ui->pte_text->appendPlainText("图像保存成功!");return true;
}//更新界面显示
void Widget::UpDateShow(const QPoint &start, const QPoint &end)
{QRect winRect = ui->lb_show->rect();   //窗口矩形区域//LOGDEBUG<<"start:"<<start<<"   end:"<<end;double xScale =  winRect.width() / 2560.0;double yScale =  winRect.height() / 1440.0;QPoint pointStart = QPoint(start.x()*xScale,start.y()*yScale);   //起始点QPoint pointEnd = QPoint(end.x()*xScale,end.y()*yScale);   //结束点//LOGDEBUG<<"pointStart:"<<pointStart<<"   pointEnd:"<<pointEnd;QPoint origin;QPoint sendPoint;//计算窗口中心点(Qt的坐标系以左上角为原点)origin.setX( (winRect.left() + winRect.right()) / 2 );origin.setY( (winRect.top() + winRect.bottom()) / 2 );//计算两点中点坐标int dx = (pointStart.x() + pointEnd.x()) / 2;int dy = (pointStart.y() + pointEnd.y()) / 2;//获取窗口尺寸(Qt推荐使用width()/height()方法)int width  = winRect.width();int height = winRect.height();//坐标映射:将中点坐标转换为标准化的设备坐标//注意:Qt的Y轴方向向下,根据具体需求可能需要符号处理sendPoint.setX( (dx - origin.x()) * 8192 * 2 / width );sendPoint.setY( (dy - origin.y()) * 8192 * 2 / height ); // 反转Y轴方向//计算拖动区域尺寸(允许负值)int width2  = pointEnd.x() - pointStart.x();int height2 = pointEnd.y() - pointStart.y();int multiple = 0;//计算面积比例(带方向)if (height2 != 0 && width2 != 0){if (pointEnd.y() >= pointStart.y()){multiple = (width * height) / (width2 * height2);}else{multiple = -(width * height) / (width2 * height2);}}m_posX = sendPoint.x();m_posY = sendPoint.y();m_posZoom = multiple;//qDebug()<<"m_posX:"<<m_posX<<"   m_posY:"<<m_posY<<"   m_posZoom:"<<m_posZoom;PtzExtControl(DH_EXTPTZ_FASTGOTO);
}//云台控制
void Widget::PtzExtControl(DWORD dwCommand, DWORD dwParam)
{if (0 == m_lLoginHandle){return;}long param1=0,param2=0,param3 = 0;char param4[256]={0};char *pchPresetName = NULL;switch(dwCommand) {case DH_PTZ_POINT_MOVE_CONTROL://Go to presetparam1=0;param2=1;param3=0;break;case DH_PTZ_POINT_SET_CONTROL://Add presetparam1=0;param2=1;param3=0;break;case DH_EXTPTZ_FASTGOTO:   //快速定位case DH_EXTPTZ_EXACTGOTO://3D intelligent positionparam1=m_posX;param2=m_posY;param3=m_posZoom;break;case DH_EXTPTZ_RESETZERO:param1=0;param2=0;param3=0;break;default:break;}BOOL bRet=CLIENT_DHPTZControlEx2(m_lLoginHandle,0,dwCommand,param1,param2,param3,FALSE,(void*)param4);if(bRet){LOGDEBUG<<"移动成功!";}else{LOGDEBUG<<"移动失败!";}
}//抓图
void Widget::OnOnePicture(LLONG ILoginID, BYTE *pBuf, UINT RevLen, UINT EncodeType, UINT CmdSerial)
{//检查输入合法性if(!pBuf || RevLen == 0){LOGDEBUG<<"抓图图像数据无效";return;}//保存图像SaveImage(pBuf,RevLen);
}//事件过滤器
bool Widget::eventFilter(QObject *watched, QEvent *event)
{if(watched ==ui->lb_show){QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);if (event->type() == QEvent::MouseButtonPress){//鼠标按下,记录起点m_startPos = mouseEvent->pos();m_currentPos = m_startPos;m_drawing = true;return true;}else if (event->type() == QEvent::MouseMove && m_drawing){//鼠标移动,更新终点并绘制临时矩形m_currentPos = mouseEvent->pos();return true;}else if (event->type() == QEvent::MouseButtonRelease && m_drawing){//鼠标释放,绘制最终矩形m_drawing = false;m_currentPos = mouseEvent->pos();//坐标转换QRect winRect = ui->lb_show->rect();double xScale =  winRect.width() / 2560.0;double yScale =  winRect.height() / 1440.0;m_startPos = QPoint(m_startPos.x()/xScale,m_startPos.y()/yScale);m_currentPos = QPoint(m_currentPos.x()/xScale,m_currentPos.y()/yScale);UpDateShow(m_startPos,m_currentPos);return true;}}return QWidget::eventFilter(watched,event);
}//设备断连回调
void CALLBACK Widget::DisConnect(LLONG lLoginID, char *pchDVRIP, LONG nDVRPort, LDWORD dwUser)
{if(0 != dwUser){QPointer<Widget> camera = reinterpret_cast<Widget*>(dwUser);camera->SetConnect(0);}
}//设备重连回调
void CALLBACK Widget::ReConnect(LLONG lLoginID, char *pchDVRIP, LONG nDVRPort, LDWORD dwUser)
{if(0 != dwUser){QPointer<Widget> camera = reinterpret_cast<Widget*>(dwUser);camera->SetConnect(1);}
}//抓图回调
void CALLBACK Widget::CaptureCallback(LLONG ILoginID, BYTE *pBuf, UINT RevLen, UINT EncodeType, DWORD CmdSerial, LDWORD dwUser)
{//跨线程调用,相机回调函数是有另开子线程的QPointer<Widget> camera = reinterpret_cast<Widget*>(dwUser);QMetaObject::invokeMethod(camera, [=](){//多个相机就需要//if(ILoginID == camera->m_lLoginHandle){camera->OnOnePicture(ILoginID,pBuf,RevLen,EncodeType,CmdSerial);}});
}//事件回调
int CALLBACK Widget::EventCallback(LLONG lAnalyzerHandle, DWORD dwAlarmType, void* pAlarmInfo, BYTE *pBuffer, DWORD dwBufSize, LDWORD dwUser, int nSequence, void *reserved)
{if(0 == dwUser){return -1;}//绊线入侵事件if(dwAlarmType == EVENT_IVS_CROSSLINEDETECTION)   //EVENT_IVS_HUMANTRAIT{//检查是否有有效的图像数据if (pBuffer == NULL || dwBufSize == 0){LOGDEBUG<<"事件回调图像数据无效";return -1;}//保存图像QPointer<Widget> camera = reinterpret_cast<Widget*>(dwUser);QMetaObject::invokeMethod(camera, [=](){//这里SaveImage中有直接操作ui控件,所以需要使用QMetaObject::invokeMethodcamera->SaveImage(pBuffer,dwBufSize);});}return 0;
}//登录
void Widget::on_pb_login_clicked()
{if (0 != m_lLoginHandle ){if (0 != m_lRealPlayHandle){on_pb_start_clicked();}if (0 != m_lRealLoadHandle){}CLIENT_Logout(m_lLoginHandle);m_lLoginHandle = 0;ui->pb_login->setText("登录");}else{NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY stInparam;memset(&stInparam, 0, sizeof(stInparam));stInparam.dwSize = sizeof(stInparam);strncpy(stInparam.szIP, ui->le_ip->text().toLocal8Bit(), sizeof(stInparam.szIP) - 1);strncpy(stInparam.szPassword, ui->le_password->text().toLocal8Bit(), sizeof(stInparam.szPassword) - 1);strncpy(stInparam.szUserName, ui->le_user->text().toLocal8Bit(), sizeof(stInparam.szUserName) - 1);stInparam.nPort = ui->le_port->text().toInt();stInparam.emSpecCap = EM_LOGIN_SPEC_CAP_TCP;NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY stOutparam;memset(&stOutparam, 0, sizeof(stOutparam));stOutparam.dwSize = sizeof(stOutparam);m_lLoginHandle = CLIENT_LoginWithHighLevelSecurity(&stInparam, &stOutparam);if (0 != m_lLoginHandle){ui->pb_login->setText("登出");}else{QMessageBox::information(this,"提示","登录失败!");m_lLoginHandle = 0;}}
}//开始
void Widget::on_pb_start_clicked()
{if(0 != m_lRealPlayHandle){CLIENT_StopRealPlay(m_lRealPlayHandle);m_lRealPlayHandle = 0;ui->pb_start->setText("开始");}else{int nChannel = 0;HWND hWnd = reinterpret_cast<HWND>(ui->lb_show->winId());m_lRealPlayHandle = CLIENT_StartRealPlay(m_lLoginHandle, nChannel, hWnd, DH_RType_Realplay, NULL, NULL, NULL);if (0 == m_lRealPlayHandle){QMessageBox::information(this,"提示","开始失败!");return;}ui->pb_start->setText("停止");CLIENT_RenderPrivateData(m_lRealPlayHandle, TRUE);}
}//订阅
void Widget::on_pb_event_clicked()
{if (0 != m_lRealLoadHandle){CLIENT_StopLoadPic(m_lRealLoadHandle);m_lRealLoadHandle = 0;ui->pb_event->setText("订阅");}else{int nChannel = 0;m_lRealLoadHandle = CLIENT_RealLoadPictureEx(m_lLoginHandle, nChannel, EVENT_IVS_ALL, TRUE, EventCallback, (LDWORD)this, NULL);if (m_lRealLoadHandle == 0){QMessageBox::information(this,"提示","订阅失败!");return;}ui->pb_event->setText("停止订阅");}
}//抓图
void Widget::on_pb_get_clicked()
{if (0 != m_lLoginHandle){//主动抓图SNAP_PARAMS snapparams = {0};snapparams.Channel = 0;snapparams.mode = 0;snapparams.CmdSerial = 0;BOOL flag = CLIENT_SnapPicture(m_lLoginHandle, snapparams);if (!flag){QMessageBox::information(this,"提示","抓图失败!");}else{ui->pte_text->appendPlainText("开始抓图");}}
}

4.widget.ui
在这里插入图片描述

四、下载链接

我这里将使用到的SDK打包在百度网盘,链接:https://pan.baidu.com/s/1RvS1qxdlkw6leKyGMGrOzQ?pwd=xxcj
提取码: xxcj


总结

这个示例实现了Qt下调用大华网络相机SDK进行实时显示,相较于大华提供的demo也是精简了部分功能,详细的可以运行官网提供的demo进行学习。在本文中有写到对智能事件的订阅回调,这个是需要通过浏览器对网络相机进行配置的,可以查看使用说明书来进行配置哦。


hello:
共同学习,共同进步,如果还有相关问题,可在评论区留言进行讨论。

参考博客:使用QT对接大华网络摄像头SDK的示例程序(建议收藏)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/38435.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[学习笔记] 部署Docker搭建靶场

前言 我们需要部署Docker来搭建靶场题目&#xff0c;他可以提供一个隔离的环境&#xff0c;方便在不同的机器上部署&#xff0c;接下来&#xff0c;我会记录我的操作过程&#xff0c;简单的部署一道题目 Docker安装 不推荐在物理机上部署&#xff0c;可能会遇到一些问题&…

网络华为HCIA+HCIP IPv6

目录 IPv4现状 IPv6基本报头 IPv6扩展报头 IPv6地址 IPv6地址缩写规范 ​编辑 IPv6地址分配 IPv6单播地址分配 IPv6单播地址接口标识 IPv6常见单播地址 - GUA &#xff08;2 / 3 开头&#xff09; IPv6常见单播地址 - ULA IPv6常见单播地址 - LLA IPv6组播地…

可视化动态表单动态表单界的天花板--Formily(阿里开源)

文章目录 1、Formily表单介绍2、安装依赖2.1、安装内核库2.2、 安装 UI 桥接库2.3、Formily 支持多种 UI 组件生态&#xff1a; 3、表单设计器3.1、核心理念3.2、安装3.3、示例源码 4、场景案例-登录注册4.1、Markup Schema 案例4.2、JSON Schema 案例4.3、纯 JSX 案例 1、Form…

C++::多态

目录 一.多态的概念 二.多态的定义及实现 二.1多态的构成条件 二.2虚函数 1.虚函数的写法 2.虚函数的重写/覆盖 3.协变 二.3析构函数的重写 二.4override和final关键字 ​编辑二.5重载/重写/隐藏的对比 三.多态的运行原理&#xff08;一部分&#xff09; 四.多态的常…

Mistral AI发布开源多模态模型Mistral Small 3.1:240亿参数实现超越GPT-4o Mini的性能

法国人工智能初创公司Mistral AI于2025年3月正式推出新一代开源模型Mistral Small 3.1 &#xff0c;该模型凭借240亿参数的轻量级设计&#xff0c;在多项基准测试中表现优异&#xff0c;甚至超越了Google的Gemma 3和OpenAI的GPT-4o Mini等主流专有模型。 1、核心特性与优势 多…

从零开发数据可视化

一、可视化模版展示 二、知识及素材准备 div css 布局flex布局Less原生js jquery 的使用rem适配echarts基础 相关js、images、font百度网盘下载链接&#xff1a; 通过百度网盘分享的文件&#xff1a;素材1 链接: https://pan.baidu.com/s/1vmZHbhykcvfLzzQT5USr8w?pwdwjx9…

WSL git文件异常 所有文件均显示已修改

如图&#xff0c;文件中没有任何修改&#xff0c;但是都显示多了一个^M 原因&#xff1a;是因为在Windows系统中git clone的文件夹&#xff0c;在WSL中会显示冲突。 解决方案&#xff1a;删掉之前在windows下git clone的文件夹&#xff0c; 然后在WSL中重新git clone

基于STM32进行FFT滤波并计算插值DA输出

文章目录 一、前言背景二、项目构思1. 确定FFT点数、采样率、采样点数2. 双缓存设计 三、代码实现1. STM32CubeMX配置和HAL库初始化2. 核心代码 四、效果展示和后话五、项目联想与扩展1. 倍频2. 降频3. 插值3.1 线性插值3.2 样条插值 一、前言背景 STM32 对 AD 采样信号进行快…

ENSP学习day9

ACL访问控制列表实验 ACL&#xff08;Access Control List&#xff0c;访问控制列表&#xff09;是一种用于控制用户或系统对资源&#xff08;如文件、文件夹、网络等&#xff09;访问权限的机制。通过ACL&#xff0c;系统管理员可以定义哪些用户或系统可以访问特定资源&#x…

Ubuntu22.04通过DKMS包安装Intel WiFi系列适配器(网卡驱动)

下载驱动包 访问 backport-iwlwifi-dkmshttps://launchpad.net/ubuntu/source/backport-iwlwifi-dkms 网站&#xff0c;找到适用于Ubuntu 22.04的update版本&#xff08;如backport-iwlwifi-dkms_xxxx_all.deb&#xff09;&#xff0c;下载至本地。 安装驱动 在下载目录中执行以…

c#难点整理2

1.对象池的使用 就是先定义一系列的对象&#xff0c;用一个&#xff0c;调一个。 public class ObjectPool<T> where T : new(){private Queue<T> pool; // 用于存储对象的队列private int maxSize; // 对象池的最大容量// 构造函数public ObjectPool(int maxSi…

音频录制小妙招-自制工具-借助浏览器录一段单声道16000采样率wav格式音频

先看效果 1、打开页面 2、点击开始录音&#xff0c;弹出权限提示&#xff0c;点击“仅这次访问时允许” 3、录完后&#xff0c;点击停止 4、文件自动下载到默认目录 上代码 js 部分 document.addEventListener(DOMContentLoaded, () > {const startBtn document.getEleme…

C++:背包问题习题

1. 货币系统 1371. 货币系统 - AcWing题库 给定 V 种货币&#xff08;单位&#xff1a;元&#xff09;&#xff0c;每种货币使用的次数不限。 不同种类的货币&#xff0c;面值可能是相同的。 现在&#xff0c;要你用这 V 种货币凑出 N 元钱&#xff0c;请问共有多少种不同的…

Python设计模式 - 适配器模式

定义 适配器模式&#xff08;Adapter Pattern&#xff09;是一种结构型设计模式&#xff0c;它用于将一个类的接口转换为客户端所期待的另一个接口。 注&#xff1a;在适配器模式定义中所提及的接口是指广义的接口&#xff0c;它可以表示一个方法或者一组方法的集合。 结构 …

Word中公式自动标号带章节编号

&#xff08;1&#xff09;插入一行三列的表格&#xff0c;设置宽度分别为0.5&#xff0c;13.39和1.5&#xff0c;设置纵向居中&#xff0c;中间列居中对齐&#xff0c;最右侧列靠右对齐&#xff0c;设置段落如下 &#xff08;2&#xff09;插入域代码 【Word】利用域代码快速实…

OSASIS(One-Shot Structure-Aware Stylized Image Synthesis)

文章目录 摘要abstract论文摘要方法损失函数实验结论 总结 摘要 本周阅读了一篇关于新型图像风格化的论文《One-Shot Structure-Aware Stylized Image Synthesis》&#xff0c;旨在解决现有GAN模型在风格化过程中难以保持输入图像结构的问题。通过分离图像的结构和语义信息&am…

优先队列 priority_queue详解

说到&#xff0c;priority_queue优先队列。必须先要了解啥是堆与运算符重载(我在下方有解释)。 否则只知皮毛&#xff0c;极易忘记寸步难行。 但在开头&#xff0c;还是简单的说下怎么用 首先&#xff0c;你需要调用 #include <queue> 在main函数中&#xff0c;声明…

Matplotlib

一、Matplotlib快速入门 学习目标 了解什么是matplotlib 为什么要学习matplotlib matplotlib简单图形的绘制 1、什么是Matplotlib 是专门用于开发2D图表(包括3D图表) 以渐进、交互式方式实现数据可视化 2、为什么要学习Matplotlib 可视化是在整个数据挖掘的关键辅助工…

【leetcode hot 100 131】分割回文串

解法一&#xff1a;回溯法动态规划法 回溯法&#xff1a; 假设我们当前搜索到字符串的第 i 个字符&#xff0c;且 s[0…i−1] 位置的所有字符已经被分割成若干个回文串&#xff0c;并且分割结果被放入了答案数组 ans 中&#xff0c;那么我们就需要枚举下一个回文串的右边界 j…