当前位置: 首页 > news >正文

1. 视频基础知识

1. 图像基础概念

  • 像素:像素是一个图片的基本单位,pix是英语单词picture,加上英语单词“元素element”,就得到了pixel,简称px。所以“像素”有“图像元素”之意。
  • 分辨率:指的是图像的大小或者尺寸。比如 1920x1080 。
  • 位深:指在记录数字图像的颜色时,计算机实际上是用每个像素需要的位深来表示的。比如红色分量使用 8bit 。
  • 帧率:在一秒钟时间内传输图片的帧数(张数),也可以理解为图形处理器每秒钟能够刷新几次。例如:25fps 表示一秒有 25 张图片。
  • 码率:视频文件在单位时间内使用的数据流量。例如 1Mbps 。
  • Stride:指在内存中每行像素所占的空间。为了实现内存对齐,每行像素在内存中所占的空间并不一定是图像的宽度。

1.1. 像素

像素是一个图片的基本单位pix是英语单词picture,加上英语单词“元素element”,就得到了pixel,简称px。所以“像素”有“图像元素”之意。

例如 2500x2000 的照片就是指横向有 2500 个像素点,竖向有 2000 个像素点,总共是 500 万个像素,也俗称为 500 万像素照片。

将这个图片放大,可以发现是由一块一块的小方块组成的,每一个小方块就是一个像素点。

1.2. 分辨率

图像(视频)的分辨率指的是图像的大小或尺寸。我们通常用像素来表示图像的尺寸。

例如分辨率为 2500x2000 的照片就是指的 横向(宽)有 2500 个像素点,竖向(高)有 2000 个像素点。

常见的分辨率:

360P(640x360)、720P(1280x720)、1080P(1920x1080)、4K(3840x2160)、8K(7680x4320)


常说的 1080P720P 其实指的是分辨率的垂直像素,一般情况下我们都是按照 16:9 (宽:高)来计算分辨率。

那么 720P 的分辨率计算流程如下:

  1. 720P 代表垂直(高)像素有 720 个像素点
  2. 由于图片的比例为 16:9 ,那么水平(宽)的像素点数量为 720 ÷ 9 × 16 = 1280
  3. 故 720P 的分辨率为 1280x720

像素越多视频就越清晰,1080P 的像素点总共有 1920x1080 约等于 200 万个像素,720p 的像素点总共有 1080x720 约等于 92 万个像素。1080p 的像素点数量比 720p 的像素点数量多两倍多,故 1080p 比 720p 更清晰。图像的分辨率越高,图像就越清晰。

低分辨率下只能看到一个大概的轮廓,而高分辨率能看到更多的细节,故更加清晰。

1.3. 位深

我们看到的彩色图片,都有三个通道,分别为红(R),绿(G),蓝(B)通道。(如果需要透明度则还有 alpha 分量)。

通常每个通道用 8bit 表示,8bit 能表示 256 种颜色,所以可以组成 256*256*256=16,777,216=1677万种颜色。这里的 8bit 就是我们讲的位深。

每个通道的位深越大,能够表示的颜色值也就越大。比如现在高端电视说的是 10bit 色彩,即每个通道用 10bit 表示,10bit 能表示 1024 种颜色,故可以组成 1024*1024*1024 约等于 10亿种颜色,是 8bit 的 64 倍。

常见的颜色还是 8bit 居多。

1.4. 帧率

帧率即 FPS(每秒有多少帧画面)。经常玩游戏的小伙伴应该很熟,我们玩游戏时,FPS 越高就代表游戏画面越流畅,越低则越卡顿。

由于视觉图像在视网膜的暂时停留,一般图像帧率能达到 24 帧,我们就认为图像是连续动态的。

  • 电影帧率一般是 24fps
  • 电视剧一般是 25fps
  • 监控行业一般是 25fps
  • 音视频通话一般是 25fps

帧率越高,画面越流畅,需要的设备性能也越高。

1.5. 码率

  • 码率指的是视频文件在单位时间内使用的数据流量。比如 1Mbps 。
  • 大多数情况下码率越高,分辨率越高,也就越清晰。但本身就模糊的视频文件码率也可以很大,分辨率小的视频文件也可能比分辨率大的视频文件清晰。【比如光线不好的时候录制的视频】
  • 对于同一个原始图像源的时候,同样的编码算法,码率越高,图像的失真就会越小,视频画面就会越清晰。【可见后面的h264编码,当采用低码率,那么在编码的时候就会设置更高的QStep】
  • 码率是一个统计的指标,并不是一个实际的功能。

1.6. Stride

设计到计算机底层对于内存的利用,不影响理解,只是开发时使用,这里不做介绍。

2. RGB、YUV深入讲解

  • RGB:红R、绿G、蓝B三种基色。
  • YUV:”Y“ 表示明亮度(Luma),也就是灰阶值,”U“ 和 ”V“ 表示的是色度(Chroma)。

2.1. RGB

  • 我们前面已经讲过 RGB 色彩表示,这里我们重点讲 RGB 的排列。通常的图像像素是按 RGB 顺序进行排列的,但有些图像处理要转换为转成其他顺序,比如 OpenCV 经常要转换为 BGR 的排列方式


常见的一些排列方式:

2.2. YUV

2.2.1. 基础介绍

  • 与我们熟知的 RGB 类似,YUV 也是一种颜色编码方法,它是指将亮度参量和色度参量分开进行表示的像素编码格式。
  • 这样分开的好处就是不但可以避免互相干扰,没有 UV 信息一样可以显示完整的图像(因而解决了彩色电视与黑白电视的兼容问题),还可以降低色度的采样率而不会对图像质量影响太大,降低了视频信号传输时对频宽(宽度)的要求。


  • YUV 是一个比较笼统的说法,针对它的具体排列方式,可以分为很多种具体的格式,但基础两个格式如下:
    • 打包(packed)格式:将每个像素点的Y、U、V分量交叉排列并以像素点为单元连续的存放在同一个数组中,通常几个相邻的像素组成一个宏像素(macro-pixel)。
    • 平面(planar)格式:使用三个数组分开连续的存放Y、U、V三个分量,即Y、U、V分别存放在各种的数组中。

2.2.2. 采样表示法

  • YUV 采用 A:B:C 表示法来描述 Y,U,V 采用频率比例,下图中黑点表示采样像素 Y 分量,空心圆表示采用像素的 UV 分量。主要分为 YUV 4:4:4、YUV 4:2:2、YUV 4:2:0 这三种常用的类型

  • 4:4:4 表示色度频道没有下采样,即每一个 Y 分量对应 一个 UV 分量。
  • 4:2:2 表示 2:1 的水平下采样,没有垂直下采样,即每两个 Y 分量共享 一个 UV 分量。
  • 4:2:0 表示 2:1 的水平下采样,2:1 的垂直下采样,即每四个 Y 分量共享 一个 UV 分量。

YUV4:4 : 4,不是说4个Y,4个V,4个U,而是说 Y 和 UV的比例关系。

同理 YUV4:2:0,也不是说4个Y,2个Y,0个U,也是说的 Y 和 UV 的比例关系。

2.2.3. YUV数据存储方式

下面以每个分量的采用数据为位深 8bit 为例描述YUV的数据存储方式

  1. 4:4:4 格式
  2. 4:2:2 格式
  3. 4:2:0 格式
2.2.3.1. YUV 4:4:4 格式

比如 I444(YUV444P)格式

  • 对应 FFmpeg 像素表示 AV_PIX_FMT_YUV444P
  • 该类型为 平面(planar)格式
  • 一个宏素块 24bit,即 3 个字节

2.2.3.2. YUV 4:2:2 格式

比如 I422(YUV422P)格式

  • 对应 FFmpeg 像素表示 AV_PIX_FMT_YUV422P
  • 该类型为 平面(planar)格式
  • 一个宏素块 16bit,即 2 个字节

2.2.3.3. YUV 4:2:0 格式【最常用】

比如 I420(YUV420P)格式

  • 对应 FFmpeg 像素表示 AV_PIX_FMT_YUV420P
  • 该类型为 平面(planar)格式
  • 一个宏素块 12bit,即 1.5 个字节

2.2.3.4. YUV 4:2:0 格式 - NV12

比如 NV12 格式

  • 对应 FFmpeg 像素表示 AV_PIX_FMT_NV12
  • 该类型为 YUV420P 的变种,对 Y 分量采用平面模式,对 UV 采用打包模式
  • 一个宏素块 12bit,即 1.5 个字节

2.2.3.5. YUV 4:2:0 格式 - 各种变种格式参考

2.3. RGB和YUV的转换

  • 通常情况下 RGB 和 YUV 直接的互相转换都是调用接口实现,比如 FFmpeg 的 swscale 或者 libyuv 等库。
  • 主要转换标准是 BT601 和 BT709。
    • TV range 的分量范围: 16-235(Y)、16-240(UV),故叫做 Limited Range
    • PC range 的分量范围: 0-255(Y、UV),故叫做 Full Range
    • 而对于 RGB 来说没有分量范围之分,全是 0-255
  • BT601 TV Range 转换公式

RGB 转换为 YUV:

Y = 0.299 * R + 0.587 * G + 0.114 * B;

U = -0.169 * R - 0.331 * G + 0.5 * B;

V = 0.5 * R - 0.419 * G - 0.081 * B;

YUV 转换为 RGB:

R = Y + 1.402 * (Y - 128)

G = Y +0.34414 * (U - 128) - 0.71414 * (U - 128)

B = Y + 1.772 * (V - 128)

  • 从 YUV 转换到 RGB ,如果值小于 0 要取 0,值大于 255 要取 255。

2.4. RGB和YUV的转换——为什么解码出错会出现绿屏

当解码时,从 packet 中解析 frame,由于解码失败,导致得到YUV的都为0,再根据公式转换为 RGB

R = 1.402 * (-128) = -126.598

G = -0.34414 * (-128) - 0.71414 * (-128) = 135.45984

B = 1.722 * (-128) = -126.228

由于 RGB 值范围是 [0,255],所以最终的值为:

R = 0

G = 135

B = 0

此时只有 G 分量有值,故全屏是绿色。

2.5. YUV Stride对齐问题

设计到计算机底层对于内存的利用,不影响理解,只是开发时使用,这里不做介绍。

3. 视频的主要概念

3.1. 基础名词

3.2. I帧

3.3. P、B帧

3.4. 常用视频压缩算法

4. 补充知识点

4.1. 常用分辨率

标号

视频类型

格式尺寸

类型

比例

1

4K

4096*2160

4K

16:9

2

2K

2560*1440

2K

16:9

3

全高清

1920*1080

1080p

16:9

4

高清

1280*720

720p

16:9

5

标清

720*480

480p

3:2

6

标清

640*480

480p

4:3

7

流畅

320*240

240p

4:3

补充说明:

多数情况下4k特指4096 * 2160分辨率。而根据使用范围的不同,4K分辨率也有各种各样的衍生分辨率,例如Full Aperture 4K的4096 * 3112、Academy 4K的3656 * 2664以及UHDTV标准的3840 * 2160等,都属于4K分辨率的范畴。

原文链接:4K、2K、1080p、720p、480p、240p常见视频清晰度-CSDN博客

4.2. 位深

如果不是8bit,而是1bit,那么就只会有八种颜色了,全红、全绿、全蓝、全黑、全白...。因为每个通道只能显示两种颜色,红、非红;绿,非绿;蓝,非蓝。

4.3. 码率

每一秒传输的帧数是固定的,比如一秒传输10帧,每帧大小1MB,那么码率就是10MBps,但是如果降低码率了,降低为5Mbps,由于每秒传输的帧数不应该发生变化,所以每帧的大小只能传输0.5MB了,所以就会造成数据丢失(压缩的结果),回显就会出现不清晰,或者马赛克了。


4.3.1. 核心概念

  1. 帧率(FPS)与码率的关系
    • 帧率(FPS)是每秒显示的帧数(如20FPS=20帧/秒),由视频的时序特性决定,与码率无关
    • 码率(比特率)是每秒传输的数据量(如200Mbps),决定了每帧能分配到的平均数据量
    • 关键结论
      • 当帧率固定时(如20FPS),降低码率会迫使编码器压缩每帧的数据量(减少每帧的比特数),而非减少帧数。
      • 提高码率则允许每帧保留更多数据,从而提升画质。
  1. 为什么压缩每帧会影响清晰度?
    • 视频编码(如H.264/H.265)的本质是用尽可能少的数据表示图像。编码器会通过以下手段压缩每帧:
      • 空间压缩:合并相似区域、舍弃高频细节(如纹理)。
      • 时间压缩:通过运动预测(帧间编码)减少冗余。
    • 码率降低时:编码器必须更激进地压缩每帧,导致:
      • 量化步长增大 → 更多细节被丢弃 → 画面模糊或出现块效应。
      • 运动预测精度下降 → 残差数据更粗糙 → 动态画面出现拖影。

4.3.2. 你的例子修正

  • 假设条件
    • 原始视频:10秒,20FPS → 共200帧,原始每帧1MB(未压缩)。
    • 编码后目标码率:
      • 200Mbps(25MB/s):每秒分配25MB数据,平均每帧 25MB/20帧=1.25MB/帧
      • 100Mbps(12.5MB/s):每秒分配12.5MB数据,平均每帧 12.5MB/20帧=0.625MB/帧
  • 关键区别
    • 高码率(1.25MB/帧)时,编码器可以保留更多细节(接近原始1MB/帧的未压缩质量)。
    • 低码率(0.625MB/帧)时,编码器必须将每帧压缩到更小的体积,导致画质下降。

4.3.3. 类比说明

  • 把视频想象成一本书
    • 帧率:每秒翻多少页(固定20页/秒)。
    • 码率:每页允许写的字数。
      • 高码率 → 每页字数多(细节丰富,清晰)。
      • 低码率 → 每页字数少(必须缩写或删减内容,信息丢失)。

4.3.4. 常见误区澄清

  1. “码率降低是否会导致丢帧?”
    • 不会!帧率(FPS)是编码前确定的参数(如20FPS),编码器会优先保证帧数,转而压缩每帧质量。
    • 只有极端情况下(如网络传输拥塞),可能主动丢帧,但这属于实时传输问题,而非编码本身的特性。
  1. “为什么不能直接降低分辨率?”
    • 降低分辨率(如1080p→720p)确实可以减少数据量,但这是另一种压缩手段。
    • 固定分辨率下,码率降低是通过压缩算法(如量化、预测)实现的,而非改变分辨率。

4.3.5. 总结

  • 帧率(FPS):决定视频的流畅度,编码时固定不变。
  • 码率:决定每帧的画质,码率越低,每帧被压缩得越狠,清晰度越低。
  • 编码器的任务:在固定帧率和目标码率下,智能分配每帧的数据量,平衡压缩率与画质。

4.4. 像素排列

常规理解来说一个像素不是一个字节,可以理解为一个对象。【这里指的位深为 8bit 】

比如不是说 char a[1280*720], a[0]是一个像素,应该理解为:

struct pixel
{char r;char g;char b;
}
pixel a[1280*720];
a[0] 是一个像素。

当然,写代码肯定是按照char来理解的,那么就是 char a[1280*720*3],a[0]、a[1]、a[2] 三个组合是一个像素;a[3]、a[4]、a[5] 三个组合起来是一个像素。其中a[0]、a[1]、a[2]谁是R,谁是G,谁是B,就看排列规则了。

4.5. 花屏

  • 如果页面完全看不出来轮廓,代表分辨率选错了
  • 如果能看出来轮廓,但是花屏,那么分辨率没问题,数据格式选错了

4.6. YUV444和YUV420的命名

YUV444 代表4个Y,4个U,4个V。

YUV420 代表4个Y,1个U,一个V。

但是看名字不应该是4个Y,2个U,0个V吗,按道理4个Y,1个U,一个V不应该叫做 YUV411 吗?


但其实它的命名源于历史约定采样网格的排列方式,而非严格的数学比例。下面详细解释:

4.6.1. 1. YUV 4:2:0 的采样结构

YUV 4:2:0 的色度(UV)采样方式如下:

  • 每4个Y(亮度)像素共享1个U和1个V(色度)值。
  • 但色度采样在垂直方向也进行了减半,即每隔一行才保留一组UV值。

实际存储示例(以2×2像素块为例):

Y1 Y2   → 亮度(Y)全采样
Y3 Y4U1 V1   → 色度(UV)在水平和垂直方向均减半
  • 4个Y对应 1个U和1个V(水平和垂直方向均共享)。

4.6.2. 2. 为什么叫4:2:0而不是4:1:1?

  • 4:2:0的命名逻辑
    • 第一个数字(4):参考基准(通常表示亮度的横向采样数)。
    • 第二个数字(2):色度(U/V)在水平方向的采样比例(相对于亮度的一半)。
    • 第三个数字(0):色度在垂直方向的采样比例(0表示垂直方向再减半)。
      • 即色度在水平和垂直方向均为亮度的一半,最终等效于“4个Y对应1个UV”。
  • 对比其他格式
    • 4:4:4:色度无降采样(每个Y对应一个UV)。
    • 4:2:2:色度水平减半,垂直全采样(每行保留UV)。
    • 4:1:1:色度水平降为1/4,垂直全采样(常见于DV视频)。
  • 关键区别
    4:2:0的“0”强调垂直方向也减半,而4:1:1的色度在垂直方向未减半。

4.6.3. 3. 命名背后的历史原因

  • 4:2:0的“0”是约定俗成
    早期工程师用数字表示色度采样相对于亮度的比例,垂直减半被标记为“0”(类似占位符),而非数学上的严格除法。
  • 与4:1:1的对比
    4:1:1是水平方向更激进的降采样(每4个Y共享1个UV,但垂直方向不降采样),而4:2:0是水平和垂直均减半。

4.6.4. 4. 直观图示

以8×8像素块为例:

  • Y(亮度):全采样(64个值)。
  • U/V(色度)
    • 水平方向:每隔1个像素采样(4:2:0 → 水平减半 → 每行4个UV)。
    • 垂直方向:每隔1行采样(4:2:0 → 垂直减半 → 共4行UV)。
    • 最终UV数据量:4×4=16个U和16个V,相当于64个Y对应16个UV → 4:1的比例

4.6.5. 5. 为什么不是4:1:1?

  • 4:1:1的色度采样
    • 水平方向:每4个Y共享1个UV。
    • 垂直方向:每行都保留UV(不降采样)。
    • 示例:8×8像素块中,UV数据量为2×8=16个(每行2个UV,共8行)。
    • 相当于64个Y对应16个UV → 4:1的比例,但垂直方向未减半。
  • 4:2:0的色度采样
    • 水平和垂直均减半 → 最终UV数据量是4:1:1的一半(更节省带宽)。

4.6.6. 总结

  • YUV 4:2:0的命名反映的是色度在水平和垂直方向的减半采样(“0”代表垂直减半),而实际存储比例是4个Y对应1个UV。
  • 4:1:1则是水平方向更激进的降采样,但垂直方向未减半。
  • 这种命名是历史惯例,数字更多表示“采样网格的分布方式”,而非严格的数学比例。

如果需要记忆,可以简单理解为:

  • 4:2:0 = 色度在两个方向都减半(最终4Y:1UV)。
  • 4:1:1 = 色度仅在水平方向减半(垂直方向全采样)。

4.7. 生成BMP图片文件

#include <iostream>
#include <fstream>
#include <vector>// BMP 文件头
#pragma pack(push, 1) // 确保结构体没有字节填充
struct BMPFileHeader {uint16_t bfType;      // 文件类型,必须是 'BM'uint32_t bfSize;      // 文件大小uint16_t bfReserved1; // 保留,必须为 0uint16_t bfReserved2; // 保留,必须为 0uint32_t bfOffBits;   // 从文件头到像素数据的偏移
};// DIB 头(BITMAPINFOHEADER)
struct BMPInfoHeader {uint32_t biSize;          // 此结构的大小(40 字节)int32_t  biWidth;         // 图像宽度int32_t  biHeight;        // 图像高度uint16_t biPlanes;        // 颜色平面数,必须为 1uint16_t biBitCount;      // 每像素位数(24 表示 RGB)uint32_t biCompression;   // 压缩类型(0 表示不压缩)uint32_t biSizeImage;     // 图像大小(可以为 0,如果不压缩)int32_t  biXPelsPerMeter; // 水平分辨率int32_t  biYPelsPerMeter; // 垂直分辨率uint32_t biClrUsed;       // 使用的颜色数(0 表示所有)uint32_t biClrImportant;  // 重要颜色数(0 表示所有)
};
#pragma pack(pop)void createRedBMP(const char* filename) {int width = 640;int height = 480;/** 这里 width * 3,是因为一个像素点有RGB3个点,故实际上一个像素点有三个点,刚好与下面的 infoHeader.biBitCount 对应。* 而且也一定要和下面的 infoHeader.biBitCount 对应,因为这里是计算的是总字节大小,这里 *3,就代表一个像素点3字节,那么每个RGB对应1个字节,那么 infoHeader.biBitCount 就该是24位,即3个字节,* 否则图形的总字节大小算下来就不对。 * +3 & (~3) 就是对齐四个字节的操作,先+3,向上填充直最近4的倍数,然后在 &(~3),把余数给去掉,(3 = 011, ~3 = 100,即最后两位一定会被去掉)*/// 计算图像数据大小int row_padded = (width * 3 + 3) & (~3); // 每行 4 字节对齐int dataSize = row_padded * height;// 创建文件头和信息头BMPFileHeader fileHeader = {};BMPInfoHeader infoHeader = {};fileHeader.bfType = 0x4D42; // 'BM'fileHeader.bfSize = sizeof(BMPFileHeader) + sizeof(BMPInfoHeader) + dataSize;fileHeader.bfOffBits = sizeof(BMPFileHeader) + sizeof(BMPInfoHeader);infoHeader.biSize = sizeof(BMPInfoHeader);infoHeader.biWidth = width;infoHeader.biHeight = height;infoHeader.biPlanes = 1;infoHeader.biBitCount = 24; // RGB。 24 / 3 = 8位 = 1个字节。0~255。为什么要除3,因为一个像素要包含RGB3个点,故一位像素点,要切分成三份来使用。与上面的row_padded对应infoHeader.biCompression = 0; // 不压缩// 打开文件std::ofstream file(filename, std::ios::binary);if (!file) {std::cerr << "无法创建文件: " << filename << std::endl;return;}// 写入文件头和信息头file.write(reinterpret_cast<const char*>(&fileHeader), sizeof(fileHeader));file.write(reinterpret_cast<const char*>(&infoHeader), sizeof(infoHeader));// 写入像素数据(红色)std::vector<uint8_t> row(row_padded, 0); // 用于存储每行的数据for (int y = 0; y < height; ++y) {for (int x = 0; x < width; ++x) {row[x * 3 + 0] = 0;   // Brow[x * 3 + 1] = 0;   // Grow[x * 3 + 2] = 255; // R}file.write(reinterpret_cast<const char*>(row.data()), row_padded);}file.close();
}int main() {createRedBMP("red_image.bmp");std::cout << "红色 BMP 图像已创建: red_image.bmp" << std::endl;return 0;
}

4.8. 生成YUV图片文件

#include <iostream>
#include <fstream>void generateRedYUVImage(const char* filename, int width, int height) {// 分配内存int size = width * height * 3;  // YUV444: 每个像素3个字节unsigned char* yuvData = new unsigned char[size];// 填充数据(全红)for (int y = 0; y < height; ++y) {for (int x = 0; x < width; ++x) {int index = (y * width + x) * 3;yuvData[index + 0] = 255;  // YyuvData[index + 1] = 255;  // UyuvData[index + 2] = 255; // V}}// 保存数据到文件std::ofstream outFile(filename, std::ios::binary);if (outFile.is_open()) {outFile.write(reinterpret_cast<const char*>(yuvData), size);outFile.close();std::cout << "Image saved to " << filename << std::endl;}else {std::cerr << "Unable to open file for writing" << std::endl;}// 释放内存delete[] yuvData;
}int main() {int width = 640;  // 图像宽度int height = 480; // 图像高度const char* filename = "red_image.yuv";generateRedYUVImage(filename, width, height);return 0;
}

使用ffplay播放:

ffplay -f rawvideo -pixel_format yuv444p -video_size 640x480 red_image.yuv

相关文章:

1. 视频基础知识

1. 图像基础概念 像素&#xff1a;像素是一个图片的基本单位&#xff0c;pix是英语单词picture&#xff0c;加上英语单词“元素element”&#xff0c;就得到了pixel&#xff0c;简称px。所以“像素”有“图像元素”之意。分辨率&#xff1a;指的是图像的大小或者尺寸。比如 19…...

docker + K3S + Jenkins + Harbor自动化部署

最近公司在研究自动化部署的一套流程&#xff0c;下面记录一下配置流程 需要提前准备好Jenkins Harbor Git(其他管理工具也可以) 我这里的打包编译流程是Jenkins上配置打包任务-->自动到git目录下找打包文件---->项目编译后打镜像包------>打完镜像包将镜像上传到…...

【算法专题十】哈希表

文章目录 0.哈希表简介1. 两数之和1.1 题目1.2 思路1.3 代码 2.判断是否为字符重排2.1 题目2.2 思路2.3 代码 3. leetcode.217.存在重复元素3.1 题目3.2 思路3.3 代码 4. leetcode.219.存在重复的元素Ⅱ4.1 题目4.2 思路4.3 代码 5. leetcode.49.字母异位词分组5.1 题目5.2 思路…...

鸿蒙系统被抹黑的深层解析:技术、商业与地缘政治的复杂博弈-优雅草卓伊凡

鸿蒙系统被抹黑的深层解析&#xff1a;技术、商业与地缘政治的复杂博弈-优雅草卓伊凡 一、技术过渡期的必然误解 1.1 兼容性设计的双刃剑效应 鸿蒙系统早期版本的兼容性策略为后续争议埋下了伏笔。2019年华为被列入实体清单后&#xff0c;面临着生死存亡的技术断供危机。在这…...

Nginx 安全防护与 HTTPS 安全部署

目录 Nginx 安全防护与 HTTPS 安全部署 一、引言 二、Nginx 安全防护措施 2.1 关闭不必要的服务和端口 2.2 限制访问频率 2.3 防止 SQL 注入和 XSS 攻击 2.4 隐藏 Nginx 版本信息 三、HTTPS 安全部署 3.1 HTTPS 简介 3.2 申请 SSL/TLS 证书 3.3 配置 Nginx 启用 HTTP…...

告别异步复杂性?JDK 21 虚拟线程让高并发编程重回简单

长期以来&#xff0c;Java 的并发编程主要围绕平台线程&#xff08;Platform Threads&#xff09;构建。然而&#xff0c;在现代应用对海量并发的巨大需求面前&#xff0c;传统模型面临着可伸缩性的挑战。JDK 21 引入了一项突破性的特性——虚拟线程&#xff08;Virtual Thread…...

Marin说PCB之POC电路layout设计仿真案例---08

Layers –stackup: RX1_96724F_FAKRA_1仿真原理图信息如下&#xff0c;设计中采用了6Gbps/187Mbps的速率配置&#xff1a; IL的limited&#xff1a; RL的limited&#xff1a; RX1_96724F_FAKRA_1--Return Loss:结果显示&#xff0c;板级设计裕量不是很充足,很接近限值曲线了。 …...

【Python系列】Python 中的 HTTP 请求处理

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

【BUG】mmdetection ValueError: need at least one array to concatenate

问题&#xff1a; 使用mmdetection框架使用COCO格式训练自定义数据集时出现如下错误&#xff1a; ValueError: need at least one array to concatenate 解决方法&#xff1a; 修改mmdet/datasets/coco.py文件&#xff0c;将CocoDataset类中的METAINFO修改为自己数据集的类别信…...

GLIBC:GLIBCXX not found

更多内容&#xff1a;XiaoJ的知识星球 目录 1. GLIBCXX not found2.解决方法&#xff1a;&#xff08;使用预编译库&#xff09;2.1 获取预编译libstdc库2.2 获取预编译libc库 注意&#xff1a;涉及到修改GLIBC库是个危险操作&#xff0c;可能会影响到系统。请谨慎操作&#xf…...

初步认识java

目录 1. java语言概述 1.1 java是什么 1.2 Java语言重要性 1.2.1 语言广泛使用程度 1.2.2 使用领域 1.3 Java语言发展简史 1.4 Java语言的特点 2. Java开发环境安装 2.1 什么是JDK 2.2 什么是JRE 2.3 什么是JVM 2.4 JDK、JRE 和 JVM的包含关系 2.5 JDK的安装和环…...

ShardingJdbc-水平分库

ShardingJdbc-水平分库 水平分库 表结构相同、记录不同、所属库不同多个库中表记录数和才是总的记录数通常根据主键ID进行分表&#xff0c;这里采用奇偶策略 案例 建立库 sharding_demo-1、sharding_demo-2每个库建立表 user_1、user_2 表结构相同id 为主键&#xff0c;big…...

模板模式 VS 建造者模式

模板模式和建造者模式是两种不同的设计模式&#xff0c;下面从定义、结构、应用场景等方面介绍它们的区别&#xff0c;并给出 Python 示例代码。 定义 模板模式&#xff1a;定义了一个操作中的算法骨架&#xff0c;将一些步骤的实现延迟到子类中。这样&#xff0c;子类可以在…...

模态编码器

1.CLIP的textEncoder能输入多少个单词? CLIP 模型中的 context_length 设置为 77&#xff0c;表示每个输入句子会被 tokenized 成最多 77 个token。这个 77 并不是直接对应到 77 个单词&#xff0c; 因为一个单词可能会被拆分成多个 token&#xff0c;特别是对于较长的或不常…...

Python-map从基础到进阶

无论你是打打算法比赛还是做项目map函数肯定都是你必学内置函数&#xff0c;这篇文章小白也能轻松掌握map函数&#xff0c;学习map&#xff0c;理解map&#xff0c;进阶用法map 描述 map() 函数会根据提供的函数对指定序列做映射。 第一个参数 function 以参数序列中的每一个…...

大数据产品销售数据分析:基于Python机器学习产品销售数据爬虫可视化分析预测系统设计与实现

文章目录 大数据产品销售数据分析&#xff1a;基于Python机器学习产品销售数据爬虫可视化分析预测系统设计与实现一、项目概述二、项目说明三、研究意义四、系统总体架构设计总体框架技术架构数据可视化模块设计图后台管理模块设计数据库设计 五、开发技术介绍Flask框架Python爬…...

「Mac畅玩AIGC与多模态21」开发篇17 - 多字段判断与多路径分支工作流示例

一、概述 本篇在结构化输出字段控制流程的基础上&#xff0c;进一步引入多字段联合判断与多路径分支控制。通过综合分析用户输入的情绪类型和紧急程度&#xff0c;实现三分支路径执行逻辑&#xff0c;开发人员将掌握复杂流程中多条件判断节点的配置技巧。 二、环境准备 macO…...

网页截图指南

截取网页截图看似是一项简单的任务&#xff0c;但当你真正动手去做的时候&#xff0c;就会发现事情远没有那么容易。我在尝试截取一篇很长的 Reddit 帖子时就深有体会。一开始我以为只要调用 browser.TakeImage() 就万事大吉&#xff0c;结果却陷入了浏览器视口、动态内容加载、…...

作为主动唤醒的节点,ECU上电如何请求通讯

一个ECU如果作为主动唤醒的节点&#xff0c;ECU上电时可以通过以下方式请求通信 如上图所示&#xff0c;ECU在上电后&#xff0c;在OS起来后&#xff0c;可以通过在BSWM模块中完成NvM_ReadAll和相关BSW 模块初始化以及Rte_Start后&#xff0c;这个时候周期性Task已经可以正常调…...

应用服务器Tomcat

启动两给tomcat apache-tomcat-9.0.60\bin——> 启动tomcat startup.bat (Windows) / startup.sh&#xff08;Linux&#xff09; 关闭tomcat shutdown.bat&#xff08;Windows&#xff09;/shutdown.sh &#xff08;Linux&#xff09; 复制一个Tomcat为2&#xff0c;先启…...

【安全】端口保护技术--端口敲门和单包授权

【安全】端口保护技术--端口敲门和单包授权 备注一、端口保护二、端口敲门三、单包授权 备注 2025/05/06 星期二 最近学习了端口保护技术总结一下 一、端口保护 为了保护联网设备的安全&#xff0c;一般会尽量减小暴露的攻击面&#xff0c;开放的端口就是最常见的攻击面&…...

金升阳科技:配套AC/DC砖类电源的高性能滤波器

金升阳推出的FC-L15HB是为我司AC砖类电源配套使用的EMC辅助器。将FC-L15HB加装在金升阳AC/DC砖类电源的前端&#xff0c;可以提高电源产品IEC/EN61000—4系列及CISPR32/EN55032标准的EMC性能。 01 产品优势 &#xff08;1&#xff09;高共差模插入损耗 ①DM&CM&#xff1…...

浅谈 - GPTQ为啥按列量化

前言 曾在游戏世界挥洒创意&#xff0c;也曾在前端和后端的浪潮间穿梭&#xff0c;如今&#xff0c;而立的我仰望AI的璀璨星空&#xff0c;心潮澎湃&#xff0c;步履不停&#xff01;愿你我皆乘风破浪&#xff0c;逐梦星辰&#xff01; 先说结论 GPTQ 按列量化 W&#xff0c;…...

引用第三方自定义组件——微信小程序学习笔记

1. 使用 npm 安装第三方包 1.1 下载安装Node.js 工具 下载地址&#xff1a;Node.js — Download Node.js 1.2 安装 npm 包 在项目空白处右键弹出菜单&#xff0c;选择“在外部终端窗口打开”&#xff0c;打开命令行工具&#xff0c;输入以下指令&#xff1a; 1> 初始化:…...

解决android studio 中gradle 出现task list not built

点击 file 选择settings...

UE5 材质淡入淡出

混合模式选择半透明,灯光照明模式选择Surface TranslucencyVolume...

如何用Java读取PDF

在本文中&#xff0c;我将向您展示如何使用JPedal&#xff08;一个用于转换、打印、查看PDF文件的Java库&#xff09;在Java中读取PDF。 如何在Java中读取PDF文件 • 将JPedal添加到您的类或模块路径中&#xff08;下载试用版jar包&#xff09;。 • 使用JPedal库中的&q…...

tinyrenderer笔记(中)

tinyrenderer个人代码仓库&#xff1a;tinyrenderer个人练习代码 前言 原教程的第 4 课与第 5 课主要介绍了坐标变换的一些知识点&#xff0c;但这一篇文章的内容主要是手动构建 MVP 矩阵&#xff0c;LookAt 矩阵以及原教程涉及到的一些知识点&#xff0c;不是从一个图形学小白…...

人工智能对人类的影响

人工智能对人类的影响 近年来&#xff0c;人工智能&#xff08;AI&#xff09;技术以惊人的速度发展&#xff0c;深刻改变了人类社会的方方面面。从医疗、教育到交通、制造业&#xff0c;AI的应用正在重塑我们的生活方式。然而&#xff0c;这一技术革命也带来了机遇与挑战并存…...

LeetCode 220 存在重复元素 III 题解

LeetCode 220 存在重复元素 III 题解 题目描述 给定一个整数数组 nums 和两个整数 k 和 t&#xff0c;请判断数组中是否存在两个不同的索引 i 和 j&#xff0c;使得&#xff1a; abs(nums[i] - nums[j]) < tabs(i - j) < k 方法思路&#xff1a;桶排序 滑动窗口 核…...

0506--01-DA

36. 单选题 在娱乐方式多元化的今天&#xff0c;“ ”是不少人&#xff08;特别是中青年群体&#xff09;对待戏曲的态度。这里面固然存在 的偏见、难以静下心来欣赏戏曲之美等因素&#xff0c;却也有另一个无法回避的原因&#xff1a;一些戏曲虽然与观众…...

单应性估计

单应性估计是计算机视觉中的核心技术&#xff0c;主要用于描述同一平面在不同视角下的投影变换关系。以下从定义、数学原理、估计方法及应用场景等方面进行综合解析&#xff1a; 一、单应性的定义与核心特性 单应性&#xff08;Homography&#xff09;是射影几何中的概念&…...

Missashe考研日记-day33

Missashe考研日记-day33 1 专业课408 学习时间&#xff1a;2h30min学习内容&#xff1a; 今天开始学习OS最后一章I/O管理的内容&#xff0c;听了第一小节的内容&#xff0c;然后把课后习题也做了。知识点回顾&#xff1a; 1.I/O设备分类&#xff1a;按信息交换单位、按设备传…...

YOLO8之学习指南

一、引言 在计算机视觉领域,目标检测是一项核心任务,其应用范围广泛,涵盖安防监控、自动驾驶、智能医疗等众多领域。YOLO(You Only Look Once)系列算法凭借其高效、快速的特点,在目标检测领域占据重要地位。YOLO8 作为 YOLO 系列的最新版本,进一步提升了检测精度和速度…...

中达瑞和便携式高光谱相机:珠宝鉴定领域的“光谱之眼”

在珠宝行业中&#xff0c;真伪鉴定始终是核心需求。随着合成技术与优化处理手段的日益精进&#xff0c;传统鉴定方法逐渐面临挑战。中达瑞和推出的便携式高光谱相机&#xff0c;凭借其独特的“图谱合一”技术&#xff0c;为珠宝真假鉴定提供了科学、高效且无损的解决方案&#…...

C++自动重连机制设计与实现指南

一、为什么需要自动重连 在网络通信场景中&#xff0c;连接中断是不可避免的常见问题&#xff1a; 网络波动&#xff08;移动网络切换、WiFi信号不稳&#xff09; 服务端维护/重启 中间设备故障&#xff08;路由器、负载均衡器&#xff09; 操作系统资源限制 长时间空闲断…...

昇腾Atlas 200I DK A2 开发者套件无法上网问题的解决

目录 引言 USB WiFi网卡 USB以太网卡 结语 引言 今年通过华为的智能基座项目得到了三个Atlas 200I DK A2 开发者套件&#xff0c;很不幸其中有一块是坏的&#xff0c;其上网部分不能使用&#xff1a;2个RJ45的口在Linux系统内都无法识别&#xff0c;而USB口虽然能够识别&a…...

私有仓库 Harbor、GitLab

gitlab 部署资料 Harbor...

极狐GitLab 如何将项目共享给群组?

极狐GitLab 是 GitLab 在中国的发行版&#xff0c;关于中文参考文档和资料有&#xff1a; 极狐GitLab 中文文档极狐GitLab 中文论坛极狐GitLab 官网 共享项目和群组 (BASIC ALL) 在极狐GitLab 16.10 中&#xff0c;更改为在成员页面的成员选项卡上显示被邀请群组成员&#xf…...

QGIS分割平行四边形

需求&#xff1a;四个点确定的平行四边形的范围&#xff0c;我想把他们均分成20份&#xff0c;然后取质心。 解决方案&#xff1a;找了好几个插件&#xff0c;Polygon Divider、Split Polygon发现不好用&#xff0c;不能满足需求。最终找到了Equalyzer&#xff0c;就是比较麻烦…...

NestJS 的核心构建块有哪些?请简要描述它们的作用(例如,Modules, Controllers, Providers)

NestJS 核心构建块解析&#xff08;Modules、Controllers、Providers&#xff09; NestJS 是一个基于 TypeScript 的渐进式 Node.js 框架&#xff0c;核心设计借鉴了 Angular 的模块化思想。下面从实际开发角度解析它的三大核心构建块&#xff0c;并附代码示例和避坑指南。 一…...

Nginx 安全防护与Https 部署实战

目录 一、核心安全配置 1. 编译安装 Nginx 2. 隐藏版本号 3. 限制危险请求方法 4. 请求限制&#xff08;CC 攻击防御&#xff09; &#xff08;1&#xff09;使用 Nginx 的 limit_req 模块限制请求速率 &#xff08;2&#xff09;压力测试验证 5. 防盗链 二、高级防护 …...

电商双十一美妆数据分析

1. 数据读取与基础查看 库导入&#xff1a;使用 import numpy as np 和 import pandas as pd 导入常用数据分析库。数据读取&#xff1a; df pd.read_csv(双十一_淘宝美妆数据.csv) 读取数据文件。数据查看&#xff1a;通过 df.head() 查看数据前几行&#xff1b; df.info() 了…...

高等数学第六章---定积分(§6.1元素法6.2定积分在几何上的应用1)

本文是关于定积分应用的系列讲解的第一讲&#xff0c;主要介绍元素法的基本思想&#xff0c;并重点讲解如何运用定积分计算平面图形的面积&#xff0c;包括直角坐标系和极坐标系下的情况。 6.1 元素法 曲边梯形的面积回顾 我们首先回顾曲边梯形的面积。设函数 f ( x ) ≥ 0 …...

十分钟了解 @MapperScan

MapperScan 是 MyBatis 和 MyBatis-Plus 提供的一个 Spring Boot 注解&#xff0c;用于自动扫描并注册 Mapper 接口&#xff0c;使其能够被 Spring 容器管理&#xff0c;并与对应的 XML 或注解 SQL 绑定。它的核心作用是简化 MyBatis Mapper 接口的配置&#xff0c;避免手动逐个…...

爬虫程序中如何添加异常处理?

在爬虫程序中添加异常处理是确保程序稳定性和可靠性的关键步骤。异常处理可以帮助你在遇到错误时捕获问题、记录日志&#xff0c;并采取适当的措施&#xff0c;而不是让程序直接崩溃。以下是一些常见的异常处理方法和示例&#xff0c;帮助你在爬虫程序中实现健壮的错误处理机制…...

[250506] Auto-cpufreq 2.6 版本发布:带来增强的 TUI 监控及多项改进

目录 Auto-cpufreq 2.6 版本发布&#xff1a;带来增强的 TUI 监控及多项改进 Auto-cpufreq 2.6 版本发布&#xff1a;带来增强的 TUI 监控及多项改进 Auto-cpufreq&#xff0c;一款适用于 Linux 的免费开源自动 CPU 速度与功耗优化器&#xff0c;已发布其最新版本 2.6。该工具…...

探索Hello Robot开源移动操作机器人Stretch 3的技术亮点与市场定位

Hello Robot 推出的 Stretch 3 机器人凭借其前沿技术和多功能性在众多产品中占据优势。Stretch 3 机器人采用开源设计&#xff0c;为开发者提供了灵活的定制空间&#xff0c;能够满足各种不同的需求。其配备的灵活手腕组件和 Intel Realsense D405 摄像头&#xff0c;显著增强了…...

【Harbor v2.13.0 详细安装步骤 安装证书启用 HTTPS】

Harbor v2.13.0 详细安装步骤&#xff08;启用 HTTPS&#xff09; 1. 环境准备 系统要求&#xff1a;至少 4GB 内存&#xff0c;100GB 磁盘空间。 已安装组件&#xff1a; Docker&#xff08;版本 ≥ 20.10&#xff09;Docker Compose&#xff08;版本 ≥ v2.0&#xff09; 域…...

码蹄集——直角坐标到极坐标的转换、射线、线段

目录 MT1052 直角坐标到极坐标的转换 MT1066 射线 MT1067 线段 MT1052 直角坐标到极坐标的转换 思路&#xff1a; arctan()在c中是atan()&#xff0c;结果是弧度要转换为度&#xff0c;即乘与180/PI 拓展&#xff1a;cos()、sin()在c代码中表示方式不变 #include<bits/…...