个人学习总结__打开摄像头、播放网络视频的以及ffmpeg推流

前言

最近入手了一款非常便宜的usb摄像头(买回来感觉画质很低,没有描述的4k,不过也够用于学习了),想着利用它来开启流媒体相关技术的学习。第一步便是打开摄像头,从而才能够对它进行一系列后续操作,诸如实时编解码,推流摄像头采集的数据等等。

本篇文章记录了如何通过QT、libvlc、ffmpeg三种方式来调用usb摄像头,顺带讲述了如何播放http网络视频流。以及如何搭建一个srs流媒体服务器。如代码有逻辑错误或者可优化,欢迎大家指正!希望和大家共同进步。

VS2022 + QT 调用usb摄像头

vs2022如果还没配置QT可参考博客: https://blog.csdn.net/H0893_888/article/details/129772600

第一步: vs2022新建一个Qt Widgets Application
在这里插入图片描述

第二步: 填写项目名称和项目位置,大家随意

第三步: qt向导中进行如下勾选(这里没选全,后续也可再更改)
在这里插入图片描述

主要代码

void Qt_Camera::openCamera(void)
{
    //获取可用摄像头列表信息
    QList<QCameraInfo> cameras = QCameraInfo::availableCameras();
    for(auto camera: cameras)
    {
        qDebug() << camera;
    }
    
    /* 创建摄像头对象
     * QCamera *camera = new QCamera;
     * 这里使用QCameraInfo::availableCameras().at(1)是因为0为电脑自带的摄像头,1为usb摄像头
     */
    QCamera *camera = new QCamera(QCameraInfo::availableCameras().at(1));
    
    // 创建摄像头取景器对象
    QCameraViewfinder *finder = new QCameraViewfinder;
    
    // 设置取景器为摄像头的视图
    camera->setViewfinder(finder);
    camera->setCaptureMode(QCamera::CaptureVideo);
    
    //创建图像捕获对象
    QCameraImageCapture *imageCapture = new QCameraImageCapture(camera);
    
    //设置图片保存路径
    imageCapture->setCaptureDestination(QCameraImageCapture::CaptureToFile);
    
    // 创建布局管理器
    QVBoxLayout *layout = new QVBoxLayout;
    layout->addWidget(finder);

    // 创建拍照按钮
    QPushButton *captureButton = new QPushButton("Capture");
    layout->addWidget(captureButton);

    //信号与槽连接
    connect(imageCapture, &QCameraImageCapture::imageCaptured, this, &MainWindow::takePhoto);
    
    // 连接拍照按钮的点击事件到图像捕获对象的拍照槽函数
    connect(captureButton, &QPushButton::clicked, [=](){
        imageCapture->capture();
    });

    // 创建主窗口
    QWidget *window = new QWidget;

    window->setLayout(layout);
    window->show();
    // 启动摄像头
    camera->start();
}

/* 这里的 id 和 image 参数 由 QCameraImageCapture::imageCaptured 这个信号传递过来 */
void Qt_Camera::takePhoto(int id, const QImage &image)
{
    //使用系统时间来命名图片的名称,时间是唯一的,图片名也是唯一的
    QDateTime dateTime(QDateTime::currentDateTime());
    QString time = dateTime.toString("yyyy-MM-dd-hh-mm-ss");
    
    //创建图片保存路径名
    QString filename = QString("D:/%1.jpg").arg(time);
    
    //保存一帧数据
    image.save(filename);
    
    //提示获取到了一帧数据
    QMessageBox::information(this, "提示:", "获取到一帧图片");
}

效果图
在这里插入图片描述

VS2022 + libvlc 调用usb摄像头/网络视频/本地视频

libvlc官网下载: https://download.videolan.org/pub/videolan/vlc/ (32/64位自选)

第一步: 创建空项目
在这里插入图片描述

第二步: 填写项目名称/路径,大家随意

第三步: 新建一个main.cpp

第四步: 拷贝libvlc至项目路径下
在这里插入图片描述

第五步: 拷贝libvlc下的所有内容至项目路径下(plugins、libvlc.dll、libvlccore.dll)
注意: 如果忘记拷贝 plugins 文件夹,无法通过 libvlc_new 得到 libvlc_instance_t* 类型的一个实例。

第六步: 获取usb摄像头名称,libvlc中需要先获得usb摄像头的名称

  • 1 打开电脑中计算机管理
  • 2 点击设备管理器
  • 3 点击照相机,下方即为电脑摄像头设备名称

在这里插入图片描述

main.cpp代码(这里使用C++代码,相对清爽一些)

#include <iostream>

#include "vlc/vlc.h"

using namespace std;

void setMedia(const char* url)
{
	//判断url是否为空
	if (!url)
	{
		cout << "url is nullptr!" << endl;
		return;
	}

	libvlc_instance_t* vlcInstance = libvlc_new(0, nullptr);
	//判断vlc实例是否为空
	if (!vlcInstance)
	{
		cout << "vlcInstance is nullptr!" << endl;
		return;
	}

	//创建媒体
	//libvlc_media_t *vlcMedia= libvlc_media_new_path(vlcInstance,url); //播放本地视频文件
	//libvlc_media_t* vlcMedia = libvlc_media_new_location(vlcInstance, "http://sovv.qianpailive.com/a455359ee41b684baaf0e4a094ee34c4/1714302042/b740/20240427/e5eba6250b87047662500bd5a3356465?a=ylu7kvm4yc47&t=1714302042023730569&u=el2KNaf9FEzbwLuS6FKdUaqObdUwp2i5Q7qqeWI3&vid=Vjkz13DanVMG"); //播放网络视频文件
	libvlc_media_t* vlcMedia = libvlc_media_new_location(vlcInstance, "dshow://DV20 USB CAMERA");   //打开usb摄像头

	if (!vlcMedia)
	{
		cout << "vlcMedia is nullptr!" << endl;
		return;
	}

	//创建媒体播放器
	libvlc_media_player_t* vlcMediaPlayer = libvlc_media_player_new_from_media(vlcMedia);
	if (!vlcMediaPlayer)
	{
		cout << "vlcMediaPlayer is nullptr!" << endl;
		return;
	}

	libvlc_media_player_play(vlcMediaPlayer);
	getchar();

	//释放媒体播放器
	if (vlcMediaPlayer)
	{
		libvlc_media_player_release(vlcMediaPlayer);
	}

	//释放媒体
	if (vlcMedia)
	{
		libvlc_media_release(vlcMedia);
	}

	//释放vlc实例
	if (vlcInstance)
	{
		libvlc_release(vlcInstance);
	}

}

int main(void)
{
	setMedia("D:\\3.flv");    //传递播放媒体url
	cout << "hello vlc" << endl;
	getchar();
	return 0;
}

效果图:

  • 本地视频
    在这里插入图片描述

  • 网络视频
    在这里插入图片描述

  • 摄像头采集一帧画面(感觉不是很清晰)
    在这里插入图片描述

VS2022 + ffmpeg + sdl 摄像头采集数据

不了解 ffmpeg 和 sdl 可参考我的上一篇博客: https://blog.csdn.net/m0_73431159/article/details/138195924

由于上一篇已经讲过 ffmpeg + sdl 在 vs2022 中的环境配置,这里就不再赘述了。
ffmpeg可以直接用命令行查看摄像头设备名
可先使用chcp 65001 临时改变 cmd 窗口编码格式为 utf-8

ffmpeg -list_devices true -f dshow -i dummy

在这里插入图片描述

代码

#pragma warning(disable:4996)

#include <stdio.h>

extern "C"  // ffmpeg有C语言编写,这里为cpp文件
{
#include "libavformat/avformat.h"
#include "libavcodec/avcodec.h"
#include "libswscale/swscale.h"
#include "libavdevice/avdevice.h"
#include "SDL/SDL.h"
#include "SDL/SDL_thread.h"
}

#undef main   // sdl中已有main的相关定义

#define REFRESH_EVENT  (SDL_USEREVENT + 1)  // 自定义事件

int thread_exit = 0;    //线程循环状态变量

int refresh_thread(void* opaque)
{
    while (thread_exit == 0) {
        SDL_Event event;
        event.type = REFRESH_EVENT; // 将事件类型定为REFRESH_EVENT
        SDL_PushEvent(&event);  // 送入事件队列中
        SDL_Delay(40);   // 如果是打开摄像头,可注释该行。如果是播放视频,该行表示每秒25帧
    }
    return 0;
}**加粗样式**

int main(void)
{
    //-----------ffmpeg------------
    AVFormatContext* pFormatContext = NULL;     //封装格式上下文
    AVDictionary* opts = NULL;  // 字典
    const char* url = "http://sovv.qianpailive.com/6ddf66db8dc4449123e9f93259db899b/1714201703/cf05/20231002/c36e0216c67cdfb009dcd1467ac4075f?a=ylu7kvm4yc47&t=1714201703527245094&u=lEqwQq9pxNSGX4uxOLgaVBmDh9FrvJwoKTdAX6t2&vid=8jLl7AGQLxjA";    //网络视频地址
    int videoIndex = -1;    //视频流索引号
    int i = 0;  // 循环变量
    AVCodecContext* pCodecContext = NULL;   // 编解码上下文
    AVCodec* pCodec = NULL;     // 编解码器
    AVPacket* packet = NULL;    // 解码前一帧视频数据
    AVFrame* pFrame = NULL;     // 解码后一帧数据
    AVFrame* pFrameYUV = NULL;  // 裁剪后一帧数据
    struct SwsContext* img_convert_ctx = NULL;  //像素格式转换等

    //-------------SDL-------------
    SDL_Surface* screen;    //画布
    int screen_w = 0, screen_h = 0;
    SDL_Overlay* bmp;   //涂层叠层
    SDL_Rect rect;  //绘图区域
    int ret, got_picture;   
    SDL_Thread* video_tid;  //线程
    SDL_Event event;    //事件

    av_register_all();  // 注册所有组件
    avformat_network_init();    //网络初始化
    avdevice_register_all();    //注册所有设备

#if 0   //如果想要播放网络流视频,将其置 1j
    /*  加上一些限制条件 */
    av_dict_set(&opts, "http_transport", "tcp", 0);
    av_dict_set(&opts, "max_delay", "500", 0);

    pFormatContext = avformat_alloc_context();
    /*  打开网络视频 */
    if (avformat_open_input(&pFormatContext, url, NULL, &opts) != 0)
    {
        printf("Can't open input !\n");
        return -1;
    }
#else
    pFormatContext = avformat_alloc_context();

    /* DShow是DirectShow的简称,它是一种用于Windows平台的多媒体框架 */
    pFormatContext->iformat = av_find_input_format("dshow");
    // pFormatContext->iformat = av_find_input_format("vfwcap");
    /*  打开摄像头作为输入 */
    if (avformat_open_input(&pFormatContext, "video=DV20 USB CAMERA", pFormatContext->iformat, NULL) != 0)
    {
        printf("Can't open input !\n");
        return -1;
    }
#endif
    /*  获取流信息 */
    if (avformat_find_stream_info(pFormatContext, NULL) < 0)
    {
        printf("Couldn't find stream information.\n");
        return -1;
    }

    /* 寻找视频流 */
    for (int i = 0; i < pFormatContext->nb_streams; i++)
    {
        if (pFormatContext->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
        {
            videoIndex = i;
            break;
        }
    }
    
    /*  判断是否找到视频流 */
    if (videoIndex == -1)
    {
        printf("Can't find video stream !\n");
        return -1;
    }

    pCodecContext = pFormatContext->streams[videoIndex]->codec; //获取解码器上下文
    pCodec = avcodec_find_decoder(pCodecContext->codec_id);     //获取解码器
    
    /*  判断是否成功获取解码器  */
    if (pCodec == NULL) 
    {
        printf("Can't find decoder !\n");
        return -1;
    }

    /*  打开解码器是否成功 */
    if (avcodec_open2(pCodecContext, pCodec, NULL) < 0)
    {
        printf("Can't open decoder !\n");
        return -1;
    }

    /*  分配空间  */
    packet = (AVPacket*)av_malloc(sizeof(AVPacket));
    pFrame = avcodec_alloc_frame();
    pFrameYUV = avcodec_alloc_frame();

    /*  初始化SDL子系统 */
    if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) {
        printf("Could not initialize SDL - %s\n", SDL_GetError());
        return -1;
    }

    /*  获取宽、高  */
    screen_w = pCodecContext->width;
    screen_h = pCodecContext->height;

    /*
     * SDL_SetVideoMode是一个用于设置SDL窗口的宽、高度、位深度和标志的函数。
     * @return 返回一个指向SDL_Surface结构的针,该结构表示窗口的表面。
     */
    screen = SDL_SetVideoMode(screen_w, screen_h, 0, 0);

    if (!screen) {
        printf("SDL: could not set video mode - exiting:%s\n", SDL_GetError());
        return -1;
    }

    /*
     * SDL_CreateYUVOverlay函数: SDL库中用于创建YUV覆盖的函数。YUV覆盖是一种用于在屏幕上显示视频的数据结构。
     * SDL_YV12_OVERLAY是SDL库中的一个宏定义,用于创建一个YV12格式的图像叠加层(overlay)。
     * YV12是一种颜色编码格式,常用于视频图像的处理和显示。
     * YV12格式将图像的亮度(Y)和色度(UV)分开存储,可以有效地压缩图像数据并提高图像质量。
     */
    bmp = SDL_CreateYUVOverlay(pCodecContext->width, pCodecContext->height, SDL_YV12_OVERLAY, screen);
    
    rect.x = 0;
    rect.y = 0;
    rect.w = screen_w;
    rect.h = screen_h;
 
    /* 图片格式转换 */
    img_convert_ctx = sws_getContext(pCodecContext->width, pCodecContext->height, pCodecContext->pix_fmt, pCodecContext->width, pCodecContext->height, PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);
    
    /* 创建一个线程 */
    video_tid = SDL_CreateThread(refresh_thread, NULL);
    
    /* SDL_WM_SetCaption函数是SDL库中的一个函数,用于设置显示窗口的标题和图标 */
    SDL_WM_SetCaption("MyCameraTest", NULL);
 
    while(1)
    {
        //等待事件到来
        SDL_WaitEvent(&event);

        /* 判断事件类型是否为REFRESH_EVENT,是则读帧 */
        if (event.type == REFRESH_EVENT) 
        {
            //------------------------------
            if (av_read_frame(pFormatContext, packet) >= 0) 
            {
                //判断是否为视频帧
                if (packet->stream_index == videoIndex) 
                {
                    //解码packet
                    ret = avcodec_decode_video2(pCodecContext, pFrame, &got_picture, packet);
                    if (ret < 0) 
                    {
                        printf("Decode Error.\n");
                        return -1;
                    }
                    
                    //判断是否获得一帧画面
                    if (got_picture)
                    {
                        /* SDL_LockYUVOverlay函数用于锁定YUV覆盖层,以便在其上进行像素操作。 */
                        SDL_LockYUVOverlay(bmp);
                        pFrameYUV->data[0] = bmp->pixels[0];
                        pFrameYUV->data[1] = bmp->pixels[2];
                        pFrameYUV->data[2] = bmp->pixels[1];
                        pFrameYUV->linesize[0] = bmp->pitches[0];
                        pFrameYUV->linesize[1] = bmp->pitches[2];
                        pFrameYUV->linesize[2] = bmp->pitches[1];

                        /*
                         * sws_scale是一个图像缩放函数,用于将输入图像缩放到指定的输出尺寸。
                         * c:SwsContext结构体指针,包含了图像缩放的相关参数。
                         * srcSlice:输入图像数据的指针数组,每个指针指向一个输入图像平面。
                         * srcStride:输入图像数据的步长数组,每个步长对应一个输入图像平面。
                         * srcSliceY:输入图像的起始行数。
                         * srcSliceH:输入图像的高度。
                         * dst:输出图像数据的指针数组,每个指针指向一个输出图像平面。
                         * dstStride:输出图像数据的步长数组,每个步长对应一个输出图像平面。
                         */
                        sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0, pCodecContext->height, pFrameYUV->data, pFrameYUV->linesize);

                        /*
                         * SDL_UnlockYUVOverlay函数: SDL库中用于解锁YUV叠加层的函数。
                         * 它的作用是解锁一个已经锁定的YUV叠加层,以便可以对其进行修改或者渲染操作。
                         * @param overlay 是一个指向SDL_Overlay结构体的指针,它表示要解锁的YUV叠加层。
                         */
                        SDL_UnlockYUVOverlay(bmp);

                        /*
                         * SDL_DisplayYUVOverlay函数: SDL库中用于显示YUV覆盖层的函数。
                         * @param overlay:指向SDL_Overlay结构的指针,表示要显示的YUV覆盖层。
                         * @param dstrect:指向SDL_Rect结构的指针,表示覆盖层在屏幕上的位置和大小。
                         */
                        SDL_DisplayYUVOverlay(bmp, &rect);

                    }
                }

                //free a packet
                av_free_packet(packet);
            }
            else 
            {
                //Exit Thread
                thread_exit = 1;
                break;
            }
        }

        // 事件类型为退出事件则退出循环
        else if (event.type == SDL_QUIT)
        {
            thread_exit = 1;
            break;
        }

    }
    
    /* 关闭释放相关资源 */
    sws_freeContext(img_convert_ctx);
    SDL_Quit();     
    av_free(pFrameYUV);
    avcodec_close(pCodecContext);
    avformat_close_input(&pFormatContext);

    return 0;
}

效果图:
在这里插入图片描述

搭建srs流媒体服务器

srs官⽹:https://github.com/ossrs/srs
码云的源速度快:https://gitee.com/winlinvip/srs.oschina.git
github的源速度慢:https://github.com/ossrs/srs.git

第⼀步,获取SRS

git clone https://gitee.com/winlinvip/srs.oschina.git
cd srs.oschina
git checkout -b 5.0 remotes/origin/5.0release
cd trunk

第二步,编译SRS

./configure && make

第三步,编写SRS配置⽂件
将以下内容保存为⽂件,譬如 conf/rtmp.conf ,服务器启动时指定该配置⽂件(srs的conf⽂件夹有该⽂件)。

# conf/rtmp.conf
listen        1935;
max_connections   1000;
vhost __defaultVhost__ {
}

第四步,启动srs

./objs/srs -c conf/rtmp.conf

第五步,启动推流编码器
视频推流

ffmpeg -re -i 3.flv -vcodec copy -acodec copy -f flv -y rtmp://192.168.72.128/live/livestream

摄像头推流

ffmpeg -f dshow -i video=“Integrated Camera” -c:v libx264 -preset ultrafast -tune zerolatency -f flv rtmp://192.168.72.128/live/livestream

这里需要根据每个人的实际情况进行填写,如: 3.flv 需替换成您电脑的视频地址
rtmp后面的地址也得改成实际的服务器地址

第六步,观看RTMP流。

  • 可以使用ffplay rtmp://192.168.72.128/live/livestream
  • 可以使用vlc播放器进行拉流播放

注意:如果是在虚拟机上进行测试,记得关闭虚拟机防火墙

第五步,启动推流编码器
视频推流

ffmpeg -re -i 3.flv -vcodec copy -acodec copy -f flv -y rtmp://192.168.72.128/live/livestream

摄像头推流

ffmpeg -f dshow -i video=“Integrated Camera” -c:v libx264 -preset ultrafast -tune zerolatency -f flv rtmp://192.168.72.128/live/livestream

这里需要根据每个人的实际情况进行填写,如: 3.flv 需替换成您电脑的视频地址
rtmp后面的地址也得改成实际的服务器地址

第六步,观看RTMP流。

  • 可以使用ffplay rtmp://192.168.72.128/live/livestream
  • 可以使用vlc播放器进行拉流播放

注意:如果是在虚拟机上进行测试,记得关闭虚拟机防火墙

systemctl stop firewalld

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

网动统一通信平台存在任意文件读取漏洞

声明&#xff1a; 本文仅用于技术交流&#xff0c;请勿用于非法用途 由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;文章作者不为此承担任何责任。 简介 网动统一通信平台&#xff08;ActiveUC&#xff09…

AEMTO--一种自适应进化多任务优化框架

AEMTO–一种自适应进化多任务优化框架 title&#xff1a; Evolutionary Multitask Optimization With Adaptive Knowledge Transfer author&#xff1a; Hao Xu, A. K. Qin, and Siyu Xia. journal&#xff1a; IEEE TRANSACTIONS ON EVOLUTIONARY COMPUTATION (TEVC) DOI&…

基于SpringBoot+Vue校园竞赛管理系统的设计与实现

项目介绍&#xff1a; 传统信息的管理大部分依赖于管理人员的手工登记与管理&#xff0c;然而&#xff0c;随着近些年信息技术的迅猛发展&#xff0c;让许多比较老套的信息管理模式进行了更新迭代&#xff0c;竞赛信息因为其管理内容繁杂&#xff0c;管理数量繁多导致手工进行…

B2B商城系统如何搭建?

相较于单个商家的独立商城&#xff0c;B2B商城系统凭借诸多优势成为电商领域中最受关注的一种模式。目前在政府、金融、汽车、跨境等行业领域都有广泛应用。那么&#xff0c;B2B商城系统如何搭建呢&#xff1f;我们从开发语言、功能模块、优势来进行分析。 一、B2B商城系统开发…

对抗攻击新手实战

实战核心思想&#xff1a; 训练x(输入&#xff09;&#xff0c;让第一次训练好的&#xff0c;正确的y去和我们想要误导机器去识别的类别的那个y做一个损失函数【loss torch.mean(y[:, 248])】&#xff0c;不同的是&#xff0c;我们其实希望是一个梯度上升&#xff0c;给图片加…

31 OpenCV 距离变换和分水岭算法

文章目录 距离变换分水岭算法distanceTransform 距离变换watershed 分水岭算法示例 距离变换 分水岭算法 distanceTransform 距离变换 void cv::distanceTransform (InputArray src,OutputArray dst,int distanceType,int maskSize,int dstType CV_32F) src:输入图像&#xf…

一篇关于Cookie的基础知识

目录 一、现有问题 二、简介 三、Cookie原理 四、Cookie应用 4.1 创建并向客户端发送Cookie 4.2 从客户端读取Cookie 4.3 Cookie的生命周期 4.4 Cookie的编码和解码 4.5 优缺点 五、记录上次登录的时间&#xff08;案例&#xff09; 六、Cookie 获取范围有多大&…

Python —— 模块、包

一、模块和包 1. 模块module 模块是 Python 程序架构的一个核心概念。Python中模块就是一个.py文件&#xff0c;模块中可以定义函数&#xff0c;变量&#xff0c;类。模块可以被其他模块引用 1.1. 创建模块文件 创建文件&#xff1a;utils.py # 定义变量 name 张三# 定义函…

Qt绘图与图形视图之场景、视图架构的简单介绍

往期回顾 Qt绘图与图形视图之绘图技术知识点的简单介绍-CSDN博客 Qt绘图与图形视图之常见图形、路径、文字、图片的绘制介绍-CSDN博客 Qt绘图与图形视图之移动鼠标手动绘制任意多边形的简单介绍-CSDN博客 Qt绘图与图形视图之场景、视图架构的简单介绍 一、GraphicsView 1、存…

项目部署总结

1、安装jdk 第一步&#xff1a;上传jdk压缩安装包到服务器 第二步&#xff1a;将压缩安装包解压 tar -xvf jdk-8uXXX-linux-x64.tar.gz 第三步&#xff1a;配置环境变量 编辑/etc/profile文件&#xff0c;在文件末尾添加以下内容&#xff1a; export JAVA_HOME/path/to/j…

12:HAL----I2C

目录 一:I2C通信协议 1:I2C简历 2:硬件电路 3:I2C时序基本单元 A : 开/ 终条件 2:发送一个字节 3:接收一个字节 4:应答机制 4:I2C时序 1:指定地址写 2:当前地址读 3: 指定地址读 二&#xff1a;HAL库 A&#xff1a;轮询方式 B:中断方式 三:案例 A:轮询方式-…

代码随想录算法训练营第12天:滑动窗口和前缀和

代码随想录算法训练营第12天&#xff1a;滑动窗口和前缀和 这里我参考了西法的博客&#xff0c; 467. 环绕字符串中唯一的子字符串(中等)795. 区间子数组个数(中等)904. 水果成篮(中等)992. K 个不同整数的子数组&#xff08;困难&#xff09;1109. 航班预订统计(中等) 前四…

第G9周:ACGAN理论与实战

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 由于ACGAN的原理在上一篇文章中已经很详细的解释过了&#xff0c;这次我们直接上代码 一、代码解读 import argparse import os import numpy as npimport t…

视频批量下载工具

1、功能演示 该工具实现了某个人主页视频批量下载&#xff0c;最多支持一次下载50个视频&#xff0c;这50个选取的是最新发布的50个视频&#xff0c;视频为高清的1080p&#xff0c;并直接将视频保存到本地。 2、软件使用介绍 2.1 解压 拿到工具软件后&#xff0c;首先是对软件…

什么是外汇爆仓?怎样避免?

外汇爆仓是指当交易者的保证金低于特定比例时&#xff0c;经纪商会自动平仓一个或所有的开仓头寸。避免外汇爆仓的关键在于合理配置资金、设置止损、适度交易、顺势而为以及调整心态。 外汇爆仓是外汇交易中的一种风险控制机制。当交易者的账户净值低于已用保证金的特定比例时&…

AI图书推荐:《企业AI转型:如何在企业中部署ChatGPT?》

Jay R. Enterprise AI in the Cloud. A Practical Guide...ChatGPT Solutions &#xff08;《企业AI转型&#xff1a;如何在企业中部署ChatGPT&#xff1f;》&#xff09;是一本由Rabi Jay撰写、于2024年由John Wiley & Sons出版的书籍&#xff0c;主要为企业提供实施AI转型…

【网络安全】00后程序员,找 Bug 赚了 6,700,000元!他是怎么做到的?

1. 漏洞赏金计划&#xff08;Bug Bounty Programs&#xff09; 2. 安全咨询服务 3. 安全培训和教育 4. 写作和发表研究 5. 参与安全竞赛&#xff08;CTFs&#xff09; 6. 开发和销售安全工具 在网络安全领域&#xff0c;通过合法的方式利用漏洞赚钱主要涉及以下几种方法。…

【服务器部署篇】Linux下Tomcat安装和配置

作者介绍&#xff1a;本人笔名姑苏老陈&#xff0c;从事JAVA开发工作十多年了&#xff0c;带过刚毕业的实习生&#xff0c;也带过技术团队。最近有个朋友的表弟&#xff0c;马上要大学毕业了&#xff0c;想从事JAVA开发工作&#xff0c;但不知道从何处入手。于是&#xff0c;产…

记录一次 vue3 + ele pls 改写 饿了么主题色实践

一、改写 element 主题色 在 main.ts 中引入需要改写的 scss 文件 main.ts: import ./styles/element-plus.scss在自定义的 element-plus.scss 文件中改写 ele pls 的变量 element-plus.scss&#xff1a; /** * 更改主题色 */ :root {--el-color-primary: #285fbb; // 主…

python使用opencv对图像的基本操作(3)

17.颜色空间的转换 17.1.rgb图像转gray图像 from skimage import io,color img io.imread(lbxx.jpg) img_gray color.rgb2gray(img) #将rgb图像转换成gray图像 io.imshow(img_gray)运行结果&#xff1a; 17.2.rgb图像转hsv图像 from skimage import io,color img io.im…