video_topic

使用qt5,ffmpeg6.0,opencv,os2来实现。qt并非必要,只是用惯了。

步骤是:

1.读取rtsp码流,转换成mat图像

2.发送ros::mat图像

项目结构如下:

videoplayer.h

#ifndef VIDEOPLAYER_H
#define VIDEOPLAYER_H#include <QThread>
#include <QImage>class VlcInstance;
class VlcMedia;
class VlcMediaPlayer;class VideoPlayer : public QThread
{Q_OBJECTpublic:explicit VideoPlayer();~VideoPlayer();void startPlay();void stopPlay();signals:void sig_GetOneFrame(QImage); //每获取到一帧图像 就发送此信号void sig_GetRFrame(QImage);   signals://void SigFinished(void);protected:void run();private:QString mFileName;VlcInstance *_instance;VlcMedia *_media;VlcMediaPlayer *_player;std::string rtspaddr;bool mStopFlag;//是否退出标志
public slots:void setrtsp(std::string addr);
};#endif // VIDEOPLAYER_H

videoplayer.cpp

#include "videoplayer.h"
extern "C"
{#include "libavcodec/avcodec.h"#include "libavformat/avformat.h"#include "libavutil/pixfmt.h"#include "libswscale/swscale.h"#include "libavutil/imgutils.h"}#include <stdio.h>
#include<iostream>
using namespace std;
VideoPlayer::VideoPlayer()
{rtspaddr="rtsp://admin:123456@192.168.123.104:554/stream1";
}VideoPlayer::~VideoPlayer()
{}void VideoPlayer::setrtsp(std::string addr){rtspaddr=addr;
}void VideoPlayer::startPlay()
{///调用 QThread 的start函数 将会自动执行下面的run函数 run函数是一个新的线程this->start();
}void VideoPlayer::stopPlay(){mStopFlag= true;
}void VideoPlayer::run()
{AVFormatContext *pFormatCtx;AVCodecContext *pCodecCtx;const AVCodec *pCodec;AVFrame *pFrame, *pFrameRGB;AVPacket *packet;uint8_t *out_buffer;static struct SwsContext *img_convert_ctx;int videoStream, i, numBytes;int ret, got_picture;avformat_network_init();//Allocate an AVFormatContext.pFormatCtx = avformat_alloc_context();AVDictionary *avdic=NULL;/*char option_key[]="rtsp_transport";char option_value[]="tcp";av_dict_set(&avdic,option_key,option_value,0);char option_key2[]="max_delay";char option_value2[]="100";av_dict_set(&avdic,option_key2,option_value2,0);*/av_dict_set(&avdic, "buffer_size", "1024000", 0); //设置最大缓存,1080可调到最大av_dict_set(&avdic, "rtsp_transport", "udp", 0); //以tcp的方式传送av_dict_set(&avdic, "stimeout", "5000000", 0); //设置超时断开链接时间,单位usav_dict_set(&avdic, "max_delay", "500000", 0); //设置最大时延av_dict_set(&avdic, "framerate", "5", 0);//av_dict_set(&avdic, "video_size","640x40",0);/*AVDictionary* options = NULL;av_dict_set(&options, "buffer_size", "1024000", 0); //设置最大缓存,1080可调到最大av_dict_set(&options, "rtsp_transport", "udp", 0); //以tcp的方式传送av_dict_set(&options, "stimeout", "5000000", 0); //设置超时断开链接时间,单位usav_dict_set(&options, "max_delay", "500000", 0); //设置最大时延av_dict_set(&options, "framerate", "20", 0);*////rtsp地址,可根据实际情况修改/// rtsp://127.0.0.1:8554/stream/// rtsp://admin:123456@192.168.123.104:554/stream1//char * tmp=(char*)rtspaddr.data();//char url[50];//strcpy(url, tmp);//char url[] ="rtsp://admin:123456@192.168.123.104:554/stream1";char url[100];for(int i=0;i<rtspaddr.length();i++){url[i] = rtspaddr[i];}url[rtspaddr.length()]='\0';if (avformat_open_input(&pFormatCtx, url, NULL, &avdic) != 0) {printf("can't open the file. \n");return;}if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {printf("Could't find stream infomation.\n");return;}videoStream = -1;///循环查找视频中包含的流信息,直到找到视频类型的流///便将其记录下来 保存到videoStream变量中///这里我们现在只处理视频流  音频流先不管他for (i = 0; i < pFormatCtx->nb_streams; i++) {if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {videoStream = i;break;}}///如果videoStream为-1 说明没有找到视频流if (videoStream == -1) {printf("Didn't find a video stream.\n");return;}printf("nb_stream:%d videoStream:%d\n",pFormatCtx->nb_streams,videoStream);pCodec = avcodec_find_decoder(pFormatCtx->streams[videoStream]->codecpar->codec_id);pCodecCtx = avcodec_alloc_context3(pCodec);avcodec_parameters_to_context(pCodecCtx, pFormatCtx->streams[videoStream]->codecpar);//printf("pCodecCtx->frame_number:%d\n", pCodecCtx->frame_number);//printf("pCodecCtx->time_base.num:%d\n", pCodecCtx->time_base.num);//printf("pCodecCtx->time_base.den:%d\n", pCodecCtx->time_base.den);//printf("pCodecCtx->bit_rate:%d\n", pCodecCtx->bit_rate);//printf("pCodecCtx->framerate:%d\n", pCodecCtx->framerate);// pCodecCtx->bit_rate =0;   //初始化为0// pCodecCtx->time_base.num=1;  //下面两行:一秒钟25帧// pCodecCtx->time_base.den=10;// pCodecCtx->frame_number=1;  //每包一个视频帧if (pCodec == NULL) {printf("Codec not found.\n");return;}///打开解码器if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) {printf("Could not open codec.\n");return;}pFrame = av_frame_alloc();pFrameRGB = av_frame_alloc();///这里我们改成了 将解码后的YUV数据转换成RGB32img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height,pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height,AV_PIX_FMT_RGBA, SWS_BICUBIC, NULL, NULL, NULL);numBytes = av_image_get_buffer_size(AV_PIX_FMT_RGBA, pCodecCtx->width,pCodecCtx->height,1);out_buffer = (uint8_t *) av_malloc(numBytes * sizeof(uint8_t));av_image_fill_arrays(pFrameRGB->data,pFrameRGB->linesize,out_buffer,AV_PIX_FMT_RGBA,pCodecCtx->width,pCodecCtx->height,1);int y_size = pCodecCtx->width * pCodecCtx->height;packet = (AVPacket *) malloc(sizeof(AVPacket)); //分配一个packetav_new_packet(packet, y_size); //分配packet的数据mStopFlag = false;while (!mStopFlag){if (av_read_frame(pFormatCtx, packet) < 0){continue; //这里认为视频读取完了}if (packet->stream_index == videoStream) {ret = avcodec_send_packet(pCodecCtx,packet);if( 0 != ret){continue;}while (avcodec_receive_frame(pCodecCtx,pFrame) == 0){sws_scale(img_convert_ctx,(uint8_t const * const *) pFrame->data,pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data,pFrameRGB->linesize);//把这个RGB数据 用QImage加载QImage tmpImg((uchar *)out_buffer,pCodecCtx->width,pCodecCtx->height,QImage::Format_RGBA8888);//QImage tmpImg((uchar *)out_buffer,pCodecCtx->width,pCodecCtx->height,QImage::Format_RGB888);QImage image = tmpImg.copy(); //把图像复制一份 传递给界面显示emit sig_GetOneFrame(image);  //发送信号/*printf("pCodecCtx->width:%d\n", pCodecCtx->width);printf("pCodecCtx->height:%d\n", pCodecCtx->height);printf("pCodecCtx->frame_number:%d\n", pCodecCtx->frame_number);printf("pCodecCtx->time_base.num:%d\n", pCodecCtx->time_base.num);printf("pCodecCtx->time_base.den:%d\n", pCodecCtx->time_base.den);printf("pCodecCtx->bit_rate:%d\n", pCodecCtx->bit_rate);printf("pCodecCtx->framerate:%d\n", pCodecCtx->framerate);printf("pCodecCtx->frame_size:%d\n", pCodecCtx->frame_size);*/}}av_packet_unref(packet); //释放资源,否则内存会一直上升msleep(0.02); //停一停  不然放的太快了}av_free(out_buffer);av_free(pFrameRGB);avcodec_close(pCodecCtx);avformat_close_input(&pFormatCtx);//emit SigFinished();
}

widget.h

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QLineEdit>
#include <QDir>
#include <QSettings>
#include <QDebug>
#include <QPushButton>
#include <QPainter>
#include <QInputDialog>
#include <QtMath>
#include <iostream>#include "videoplayer.h"
#include <iostream>
#include <csignal>
#include <opencv4/opencv2/opencv.hpp>#include <iostream>
#include <iomanip>
#include <ctime>
#include <opencv2/opencv.hpp>#include<algorithm>
#include<vector>
#include<iostream>#include "rclcpp/rclcpp.hpp"
#include "std_msgs/msg/string.hpp"#include <QTimer>#include <cv_bridge/cv_bridge.h>
#include <sensor_msgs/msg/image.hpp>
#include <std_msgs/msg/string.hpp>
using namespace std::chrono_literals;QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();
signals:void sig_fame(QImage img);private:Ui::Widget *ui;
private:void readconfig();QString rtspaddr;void initWidget();void initconnect();
private slots:void slot_open_or_close();protected://void paintEvent(QPaintEvent *event);private:VideoPlayer *mPlayer; //播放线程QImage mImage; //记录当前的图像QString url;//QImage initimage;cv::Mat QImage2Mat(QImage image);QImage Mat2QImage(const cv::Mat &mat);//void readvideo();//std::vector<cv::Vec3b> colors(32);//cv::VideoWriter outputVideo;//int encode_type ;//= VideoWriter::fourcc('M', 'J', 'P', 'G');//std::vector<cv::Vec3b> colors;//cv::VideoWriter outputVideo;private slots:void slotGetOneFrame(QImage img);private:cv::Mat tempmat;// -------------------------------------// ros// -------------------------------------// noderclcpp::Node::SharedPtr node_;// pubrclcpp::Publisher<sensor_msgs::msg::CompressedImage>::SharedPtr publisher_;// sub//rclcpp::Subscription<std_msgs::msg::String>::SharedPtr subscriber_;// spinrclcpp::TimerBase::SharedPtr timer_;void initSpin(void);QTimer spin_timer_;void timer_callback();};
#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{mPlayer = new VideoPlayer;ui->setupUi(this);readconfig();initWidget();initconnect();// -------------------------------------/*// create topic pubthis->publisher_ = this->node_->create_publisher<std_msgs::msg::String>("pub_topic", 10);// create topic subthis->subscriber_ = node_->create_subscription<std_msgs::msg::String>("sub_topic", 10,[&](const std_msgs::msg::String::SharedPtr msg){// 處理訂閱到的消息QString receivedMsg = QString::fromStdString(msg->data);std::cout << msg->data << std::endl;//ui->textBrowser->append(receivedMsg);});this->initSpin();*/rclcpp::init(0, nullptr);// create nodethis->node_ = rclcpp::Node::make_shared("video");this->publisher_ = this->node_->create_publisher<sensor_msgs::msg::CompressedImage>("pubImageTopic", 10);this->timer_ = this->node_->create_wall_timer(33ms, std::bind(&Widget::timer_callback, this));this->initSpin();}Widget::~Widget()
{delete ui;// -------------------------------------// ROS 釋放// -------------------------------------this->spin_timer_.stop();rclcpp::shutdown();// -------------------------------------}void Widget::initSpin(void)
{this->spin_timer_.setInterval(1); // 1 msQObject::connect(&this->spin_timer_, &QTimer::timeout, [&](){ rclcpp::spin_some(node_); });this->spin_timer_.start();
}void Widget::timer_callback(){try{//ros_img_ = cv_bridge::CvImage(std_msgs::msg::Header(), "bgr8", tempmat).toImageMsg();//sensor_msgs::msg::Image::SharedPtr ros_img_ = cv_bridge::CvImage(std_msgs::msg::Header(), "bgr8", tempmat).toImageMsg();if(!tempmat.empty()){//rclcpp::Publisher<sensor_msgs::msg::CompressedImage>::SharedPtr video_compressed_publisher_;cv::Mat des1080;cv::resize(tempmat, des1080, cv::Size(1080, 720), 0, 0, cv::INTER_NEAREST);sensor_msgs::msg::CompressedImage::SharedPtr ros_img_compressed_ = cv_bridge::CvImage(std_msgs::msg::Header(), "bgr8", des1080).toCompressedImageMsg();//video_compressed_publisher_->publish(*ros_img_compressed_);this->publisher_ ->publish(*ros_img_compressed_);qDebug()<<"publisher";}else{qDebug()<<"empty image";}//RCLCPP_WARN(this->get_logger(), "empty image");// video_publisher_->publish(*ros_img_);}catch (cv_bridge::Exception &e){//RCLCPP_ERROR(this->get_logger(),ros_img_->encoding.c_str());qDebug()<<"Exception";}}void Widget::readconfig(){QSettings settingsread("./src/video_topic/conf/config.ini",QSettings::IniFormat);rtspaddr = settingsread.value("SetUpOption/camerartsp").toString();mPlayer->setrtsp(rtspaddr.toStdString());
}void Widget::initWidget(){qDebug()<<rtspaddr;ui->le_rtstspaddr->setText(rtspaddr);
}void Widget::slot_open_or_close(){if(ui->btn_openorclose->text()=="open"){ui->btn_openorclose->setText("close");mPlayer->startPlay();// ROS 初始化// -------------------------------------/*rclcpp::init(0, nullptr);// create nodethis->node_ = rclcpp::Node::make_shared("video");this->publisher_ = this->node_->create_publisher<sensor_msgs::msg::CompressedImage>("pubImageTopic", 10);this->timer_ = this->node_->create_wall_timer(500ms, std::bind(&Widget::timer_callback, this));//pub_img = this->create_publisher<sensor_msgs::msg::Image>("res_img", 10);rclcpp::spin(this->node_);*///readvideo();}else{ui->btn_openorclose->setText("open");mPlayer->stopPlay();}
}void Widget::initconnect(){connect(ui->btn_openorclose,&QPushButton::clicked,this,&Widget::slot_open_or_close);connect(mPlayer,SIGNAL(sig_GetOneFrame(QImage)),this,SLOT(slotGetOneFrame(QImage)));connect(this,&Widget::sig_fame,this,&Widget::slotGetOneFrame);//connect(mPlayer,&VideoPlayer::SigFinished, mPlayer,&VideoPlayer::deleteLater);//自动释放
}void Widget::slotGetOneFrame(QImage img)
{//cv::Mat tempmat = QImage2Mat(img);tempmat = QImage2Mat(img);if (tempmat.empty()) {printf("null img\n");}else {QImage outimg = Mat2QImage(tempmat);//printf("get img\n");mImage = outimg;QImage imageScale = mImage.scaled(QSize(ui->label->width(), ui->label->height()));QPixmap pixmap = QPixmap::fromImage(imageScale);ui->label->setPixmap(pixmap);}}cv::Mat Widget::QImage2Mat(QImage image)
{cv::Mat mat = cv::Mat::zeros(image.height(), image.width(),image.format()); //初始化Matswitch(image.format()) //判断image的类型{case QImage::QImage::Format_Grayscale8:  //灰度图mat = cv::Mat(image.height(), image.width(),CV_8UC1,(void*)image.constBits(),image.bytesPerLine());break;case QImage::Format_RGB888: //3通道彩色mat = cv::Mat(image.height(), image.width(),CV_8UC3,(void*)image.constBits(),image.bytesPerLine());break;case QImage::Format_ARGB32: //4通道彩色mat = cv::Mat(image.height(), image.width(),CV_8UC4,(void*)image.constBits(),image.bytesPerLine());break;case QImage::Format_RGBA8888:mat = cv::Mat(image.height(), image.width(),CV_8UC4,(void*)image.constBits(),image.bytesPerLine());break;default:return mat;}cv::cvtColor(mat, mat, cv::COLOR_BGR2RGB);return mat;}QImage Widget::Mat2QImage(const cv::Mat &mat)
{if(mat.type()==CV_8UC1 || mat.type()==CV_8U){QImage image((const uchar *)mat.data, mat.cols, mat.rows, mat.step, QImage::Format_Grayscale8);return image;}else if(mat.type()==CV_8UC3){QImage image((const uchar *)mat.data, mat.cols, mat.rows, mat.step, QImage::Format_RGB888);return image.rgbSwapped();  //r与b调换}
}

widget.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"><class>Widget</class><widget class="QWidget" name="Widget"><property name="geometry"><rect><x>0</x><y>0</y><width>645</width><height>461</height></rect></property><property name="windowTitle"><string>Widget</string></property><layout class="QVBoxLayout" name="verticalLayout"><item><widget class="QStackedWidget" name="stackedWidget"><widget class="QWidget" name="page"><layout class="QVBoxLayout" name="verticalLayout_2"><item><widget class="QLabel" name="label"><property name="text"><string>TextLabel</string></property></widget></item><item><layout class="QHBoxLayout" name="horizontalLayout"><item><widget class="QLineEdit" name="le_rtstspaddr"><property name="readOnly"><bool>true</bool></property></widget></item><item><widget class="QPushButton" name="btn_openorclose"><property name="text"><string>open</string></property></widget></item></layout></item></layout></widget><widget class="QWidget" name="page_2"/></widget></item></layout></widget><resources/><connections/>
</ui>

main.cpp

#include "widget.h"#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);Widget w;w.show();//w.showMaximized();return a.exec();
}

package.xml

<?xml version="1.0"?>
<?xml-model href="http://download.ros.org/schema/package_format3.xsd" schematypens="http://www.w3.org/2001/XMLSchema"?>
<package format="3"><name>video_topic</name><version>0.0.0</version><description>TODO: Package description</description><maintainer email="cl@todo.todo">cl</maintainer><license>TODO: License declaration</license><buildtool_depend>ament_cmake</buildtool_depend><buildtool_depend>cv_bridge</buildtool_depend><depend>rclcpp</depend><depend>std_msgs</depend><depend>cv_bridge</depend><test_depend>ament_lint_auto</test_depend><test_depend>ament_lint_common</test_depend><export><build_type>ament_cmake</build_type></export>
</package>

CMakeLists.txt

cmake_minimum_required(VERSION 3.5)
project(video_topic)# Default to C++14
if(NOT CMAKE_CXX_STANDARD)set(CMAKE_CXX_STANDARD 14)
endif()if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")add_compile_options(-Wall -Wextra -Wpedantic)
endif()# find dependencies
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(std_msgs REQUIRED)
# qt
find_package(Qt5 REQUIRED COMPONENTS Core Gui Widgets)
find_package(cv_bridge REQUIRED)
find_package(image_transport)
find_package(sensor_msgs REQUIRED)add_executable(videosrc/main.cppsrc/videoplayer.hsrc/videoplayer.cppsrc/widget.hsrc/widget.cppsrc/widget.ui
)#set(FFMPEG_LIBS_DIR /usr/local/ffmpeg/lib)
#set(FFMPEG_HEADERS_DIR /usr/local/ffmpeg/include)set(FFMPEG_LIBS_DIR /usr/lib/aarch64-linux-gnu)
set(FFMPEG_HEADERS_DIR /usr/include/aarch64-linux-gnu)
include_directories(${FFMPEG_HEADERS_DIR})
#link_directories(${FFMPEG_LIBS_DIR})
#set(FFMPEG_LIBS libavutil.so libavcodec.so libavdevice.so libavformat.so libavfilter.so libswresample.so libswscale.so  libavutil.so)
set(FFMPEG_LIBS libavcodec.so libavformat.so libswscale.so libavutil.so)find_package(OpenCV REQUIRED)
include_directories( ${OpenCV_INCLUDE_DIRS})
target_link_libraries(video ${OpenCV_LIBS})# ros
target_link_libraries(video${rclcpp_LIBRARIES} 
)
# qt
target_link_libraries(video Qt5::Core Qt5::GuiQt5::Widgets
)
#ffmpegtarget_link_libraries(video ${FFMPEG_LIBS})ament_target_dependencies(videorclcppstd_msgssensor_msgs cv_bridge OpenCV image_transport
)# ------------------------------------------
# 設置自動MOC、UIC和RCC (與QT相關)
# ------------------------------------------
set_target_properties(video PROPERTIES AUTOMOC ON)
set_target_properties(video PROPERTIES AUTOUIC ON)
set_target_properties(video PROPERTIES AUTORCC ON)
# ------------------------------------------# 安装可执行文件
install(TARGETS videoDESTINATION lib/${PROJECT_NAME}
)ament_package()

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

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

相关文章

机器学习笔记 - 车道检测的几种深度学习方法

一、简述 人们在打造自动驾驶汽车时首先想到的就是实现车道检测。这是 Tesla 和 mobileye 所说的“强制性”任务,也是 Sebastian Thrun(自动驾驶汽车教父)在接受采访时所说的首要任务。 这个方向有很多传统的 OpenCV 算法,这些算法由不再使用的非常旧的函数组成。目前全部都…

LabVIEW玩转魔方

LabVIEW玩转魔方 使用LabVIEW创建一个3D魔方&#xff0c;并找出解谜题的秘密&#xff0c;给朋友留下深刻深刻的印象。游戏中内置的机制使每张脸都能独立转动&#xff0c;从而混合颜色。要解决难题&#xff0c;每个面必须是相同的纯色 魔方的奥秘在于它的简单性和不可解性。这是…

基于springboot实现音乐网站与分享平台项目【项目源码+论文说明】

摘要 本论文主要论述了如何使用JAVA语言开发一个音乐网站与分享平台 &#xff0c;本系统将严格按照软件开发流程进行各个阶段的工作&#xff0c;采用B/S架构&#xff0c;面向对象编程思想进行项目开发。在引言中&#xff0c;作者将论述音乐网站与分享平台的当前背景以及系统开…

Python 人工智能 Machine Learning 机器学习基础知识点详细教程(更新中)

Artificial Intelligence 人工智能基本介绍 人工智能&#xff08;Artificial Intelligence&#xff0c;AI&#xff09;是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门新的技术科学。它试图了解智能的实质&#xff0c;并生产出一种新的能以人类智…

VMware使用ubuntu安装增强功能实现自动缩放

VMware使用ubuntu安装增强功能实现自动缩放 1.下载 VMware Tools2.安装tool 1.下载 VMware Tools 1.需要先弹出DVD 2.虚拟机-安装VMware Tools 进入终端 3.把media下的VMware压缩包拷贝到home/下 4.去home下解压 2.安装tool 进入vmware-tools-distrib sudo ./vmware-ins…

微信小程序备案内容常见问题汇总

一、备案时间点 自2023年09月01日起,新的微信小程序,必须备案后才能上架; 在2024年03月31日前,所有小程序都必须完成备案; 于2024年04月01日起,对未备案小程序进行清退处理。 微信小程序备案系统已于9月4日上线。 二、备案流程 [找备案入口]–[填主体信息]–[填小程…

QE01/QA11/QA02屏幕增强

1、业务需求 需要对来料检验增加“合格数量”和“不合格数量”字段&#xff0c;涉及三个增强开发 2、QE01\QE02\QE03\QE51N屏幕增强 增强表 增强点BADI&#xff1a;QEEM_SUBSCREEN_5000 创建程序&#xff0c;包含子屏幕&#xff0c;在增强点中调用 在程序屏幕中绘制字段 在输…

asp.net售后维修管理系统VS开发sqlserver数据库web结构c#编程Microsoft Visual Studio

一、源码特点 asp.net 售后维修管理系统 是一套完善的web设计管理系统&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为vs2010&#xff0c;数据库为sqlserver2008&#xff0c;使用c#语 言开发 asp.net售后维修管理系统1 二、…

python openai playground使用教程

文章目录 playground介绍Playground特点模型设置和参数选择四种语言模型介绍 playground应用构建自己的playground应用playground python使用 playground介绍 OpenAI Playground是一个基于Web的工具&#xff0c;旨在帮助开发人员测试和尝试OpenAI的语言模型&#xff0c;如GPT-…

【大数据】Apache Hive数仓(学习笔记)

一、数据仓库基础概念 1、数仓概述 数据仓库&#xff08;数仓、DW&#xff09;&#xff1a;一个用于存储、分析、报告的数据系统。 OLAP&#xff08;联机分析处理&#xff09;系统&#xff1a;面向分析、支持分析的系统。 数据仓库的目的&#xff1a;构建面向分析的集成化数据…

9、Docker 安装 Redis

1、下载镜像 docker pull redis:3.2.10 2、本机创建redis目录并修改配置文件 1&#xff09;创建目录 mkdir /usr/local/redis 2&#xff09;进入redis目录 cd /usr/local/redis 3&#xff09;创建data目录 mkdir data 4&#xff09;创建redis.conf文件 vi redis.conf 5&a…

网站的搭建与应用|企业APP软件定制开发|小程序

网站的搭建与应用|企业APP软件定制开发|小程序 网站是一种数字化媒体&#xff0c;它可以将我们的信息传递给全球的用户&#xff0c;让更多的人了解我们、了解我们的产品和服务。那么&#xff0c;如何搭建一个网站呢&#xff1f;下面&#xff0c;我将为大家介绍一下网站的建设步…

NIO基础-ByteBuffer,Channel

文章目录 1. 三大组件1.1 Channel1.2 Buffer1.2 Selector 2.ByteBuffer2.1 ByteBuffer 正确使用姿势2.2 ByteBuffer 结构2.3 ByteBuffer 常见方法分配空间向 buffer 写入数据从 buffer 读取数据mark 和 reset字符串与 ByteBuffer 互转分散度集中写byteBuffer黏包半包 3. 文件编…

Vulnhub系列靶机-Raven2

文章目录 Raven2 渗透测试1. 信息收集1.1 主机探测1.2 端口扫描1.3 目录爆破 2. 漏洞探测3. 漏洞利用3.1 msfconsole3.2 交互式shell 4. 权限提升 Raven2 渗透测试 1. 信息收集 1.1 主机探测 arp-scan -l1.2 端口扫描 nmap -p- -A 192.168.188.213通过nmap工具进行端口扫描…

当想为SLB申请公网域名时,缩写是什么意思

SLB的缩写是Server Load Balancer&#xff0c;即服务器负载均衡器。 是一种内网吗? 不&#xff0c;SLB&#xff08;Server Load Balancer&#xff09;是一种位于应用程序和网络之间的设备或服务&#xff0c;用于在多个服务器之间分发流量、负载均衡以及提供高可用性。它通常…

2核4G游戏服务器推荐(阿里云/腾讯云/华为云)

2核4G游戏服务器推荐&#xff0c;首选腾讯云2核4G5M带宽轻量应用服务器218元一年、阿里云2核4G4M带宽轻量应用服务器297元一年&#xff0c;华为云2核2G3M云耀L服务器95元一年&#xff0c;阿腾云来详细说下2核4G游戏服务器推荐配置大全&#xff1a; 目录 2核4G游戏服务器推荐 …

Qt应用开发(基础篇)——树结构视图 QTreeView

一、前言 QTreeView类继承于QAbstractItemView类&#xff0c;提供了一个树结构视图的模型。 视图基类 QAbstractItemView QTreeView默认为Model/View实现&#xff0c;下面是一个使用QFileSystemModel和QTreeView的结合&#xff0c;显示系统文件结构的实例。 QFileSystemModel …

pycharm中快速对比两个.py文件

在学习一个算法的时候&#xff0c;就想着自己再敲一遍代码&#xff0c;结果最后出现了一个莫名其妙的错误&#xff0c;想跟源文件对比一下到底是在哪除了错&#xff0c;之前我都是大致定位一个一个对比&#xff0c;想起来matlab可以快速查找出两个脚本文件(.m文件)的区别&#…

大语言模型迎来重大突破!找到解释神经网络行为方法

前不久&#xff0c;获得亚马逊40亿美元投资的ChatGPT主要竞争对手Anthropic在官网公布了一篇名为《朝向单义性&#xff1a;通过词典学习分解语言模型》的论文&#xff0c;公布了解释经网络行为的方法。 由于神经网络是基于海量数据训练而成&#xff0c;其开发的AI模型可以生成…

进化算法------代码示例

前言 遗传算法就是在一个解空间上&#xff0c;随机的给定一组解&#xff0c;这组解称为父亲种群&#xff0c;通过这组解的交叉&#xff0c;变异&#xff0c;构建出新的解&#xff0c;称为下一代种群&#xff0c;然后在目前已有的所有解中抽取表现好的解组成新的父亲种群&#…