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

ARM Linux摄像头传感器数据处理全景视野:从板端编码视频到高级应用

ARM Linux摄像头传感器数据处理全景视野:从板端编码视频到高级应用

  • 1. 摄像头传感器与数据采集(Camera Sensor and Data Acquisition)
    • 1.1 数字摄像头传感器基础(Basics of Digital Camera Sensors)
      • 1.1.1 传感器类型(Sensor Types)
      • 1.1.2 传感器尺寸(Sensor Size)
      • 1.1.3 像素数量(Pixel Count)
      • 1.1.4 帧率(Frame Rate)
    • 1.2 ARM Linux下的数据采集(Data Acquisition on ARM Linux)
      • 1.2.1 打开设备(Opening the Device)
      • 1.2.2 查询设备信息(Querying Device Information)
      • 1.2.3 设置输入/输出格式(Setting Input/Output Format)
      • 1.2.4 请求并映射缓冲区(Requesting and Mapping Buffers)
      • 1.2.5 读取数据(Reading Data)
    • 1.3 常见问题和解决方案(Common Problems and Solutions)
      • 1.3.1 无法打开设备(Cannot Open Device)
      • 1.3.2 设置的格式不支持(Unsupported Format)
      • 1.3.3 缓冲区溢出(Buffer Overflow)
  • 2. 从板端编码视频(Video Encoding at the Board End)
    • 2.1 视频编码基础知识(Basics of Video Encoding)
      • 编码过程
      • 编码标准
    • 2.2 ARM Linux环境下的视频编码实践(Video Encoding Practice on ARM Linux)
      • 硬件和软件环境
      • 视频编码过程
    • 2.3 提升视频编码效率的策略(Strategies to Improve Video Encoding Efficiency)
      • 使用更高效的编码标准
      • 调整编码参数
      • 利用硬件加速
      • 并行编码
  • 3. Qt在视频处理中的应用(Application of Qt in Video Processing)
    • 3.1 Qt视频处理框架简介(Introduction to Qt Video Processing Framework)
      • (1) QtMultimedia模块
      • (2) QtAV模块
    • 3.2 使用Qt进行视频播放和处理的实践(Practice of Video Playback and Processing with Qt)
      • (1) 视频播放
      • (2) 视频滤镜处理
  • 3.3 Qt的音视频同步处理技术(Qt's Audio and Video Synchronization Processing Technology)
  • 4. C++11、14、17、20在视频处理中的运用(Application of C++11, 14, 17, 20 in Video Processing)
    • 4.1 C++新特性在视频处理中的应用(Application of New C++ Features in Video Processing)
      • 1. 自动类型推断(auto)
      • 2. 范围for循环(Range-based for loop)
      • 3. 智能指针(Smart Pointers)
      • 4. 并行算法(Parallel Algorithms)
      • 5. 概念(Concepts)
    • 4.2 用C++构建高效的视频处理框架(Building an Efficient Video Processing Framework with C++)
      • 1. 使用RAII管理资源
      • 2. 使用模板实现泛型编程
      • 3. 使用STL处理数据
      • 4. 使用多线程提高处理速度
    • 4.3 C++在音视频处理中的最佳实践(Best Practices of C++ in Audio and Video Processing)
      • 1. 坚持使用RAII管理资源
      • 2. 避免过度优化
      • 3. 利用现代C++特性
      • 4. 尽量减少数据拷贝
  • 5. 摄像头采集的数据格式与处理(Data Format and Processing of Camera Acquisition)
    • 5.1 摄像头数据格式概述(Overview of Camera Data Format)
      • RAW格式
      • YUV格式
    • 5.2 从摄像头数据到常用视频格式(From Camera Data to Common Video Formats)
      • YUV到H.264
      • YUV到H.265
    • 5.3 与YUV, RGB数据格式的关系(Relation with YUV, RGB Data Formats)
      • YUV与RGB
      • YUV与TS流
  • 6. 视频流处理和转换(Video Stream Processing and Conversion)
    • 6.1 TS流和其它常用视频流介绍(Introduction to TS Stream and Other Common Video Streams)
    • 6.2 视频流格式的转换过程(Conversion Process of Video Stream Formats)
    • 6.3 实现流处理的关键技术(Key Technologies to Implement Stream Processing)
  • 7. FFmpeg在视频处理中的应用(Application of FFmpeg in Video Processing)
    • 7.1 FFmpeg简介及其作用(Introduction and Role of FFmpeg)
    • 7.2 FFmpeg的编程应用实例(Programming Application Examples of FFmpeg)
      • 1. 读取媒体文件的元数据
      • 2. 转码媒体文件
    • 7.3 FFmpeg的高级应用与优化(Advanced Applications and Optimization of FFmpeg)
      • 1. 利用滤镜进行音视频特效处理
      • 2. 利用硬件加速进行编解码优化
      • 3. 使用多线程技术提高处理速度
  • 结语

1. 摄像头传感器与数据采集(Camera Sensor and Data Acquisition)

1.1 数字摄像头传感器基础(Basics of Digital Camera Sensors)

摄像头传感器是摄像头中最关键的组件,它直接影响着图像的质量和性能。要理解摄像头传感器如何工作,我们需要从几个关键的概念和参数开始。

1.1.1 传感器类型(Sensor Types)

数字摄像头主要有两种传感器类型:CCD(电荷耦合器件)和CMOS(互补金属氧化物半导体)。CCD传感器在图像质量上通常表现得更好,但其成本较高,耗电量大。而CMOS传感器则更便宜,耗电量小,处理速度快,因此在许多现代的摄像头中更为常见。

传感器类型优点缺点
CCD高图像质量成本高,耗电量大
CMOS便宜,耗电量小,处理速度快图像质量可能较差

1.1.2 传感器尺寸(Sensor Size)

传感器尺寸是影响摄像头图像质量的另一个重要参数。在相同的像素数下,传感器尺寸越大,单个像素的面积就越大,可以收集更多的光线,因此图像质量更好,噪声更小。

1.1.3 像素数量(Pixel Count)

我们常说的摄像头的“百万像素”,实际上是指摄像头传感器上的像素数量。像素数量越多,理论上能捕捉到的图像细节就越多。但是,如果在相同的传感器尺寸下,像素数量过多,单个像素的面积就会变小,可能会导致噪声增加,图像质量反而下降。

1.1.4 帧率(Frame Rate)

帧率是指摄像头在一秒钟内可以捕捉并输出的图像帧数。帧率越高,视频的流畅度就越好,但是也会增加数据的带宽需求和处理压力。

在理解了以上这些概念和参数后,我们就可以更好地理解摄像头传感器如何影响我们的图像和视频质量,从而更好地进行数据采集和处理。

以上就是对数字摄像头传感器基础的介绍,接下来我们将讨论在ARM Linux下如何进行数据采集。

1.2 ARM Linux下的数据采集(Data Acquisition on ARM Linux)

ARM Linux环境下,数据采集主要依赖于一个被称为V4L2(Video for Linux 2)的内核接口。V4L2定义了一套统一的API,为各类视频设备提供了访问和控制的方式。接下来,我们将探讨在ARM Linux下使用V4L2进行数据采集的基本步骤。

1.2.1 打开设备(Opening the Device)

在Linux系统中,设备被表示为文件,通常位于/dev目录下。例如,摄像头设备可能被表示为/dev/video0。我们可以使用open系统调用打开这个设备。

int fd = open("/dev/video0", O_RDWR);
if (fd == -1) {// 打开设备失败,处理错误
}

1.2.2 查询设备信息(Querying Device Information)

我们可以使用VIDIOC_QUERYCAP命令查询设备的能力。

v4l2_capability cap;
if (ioctl(fd, VIDIOC_QUERYCAP, &cap) == -1) {// 查询设备信息失败,处理错误
}

1.2.3 设置输入/输出格式(Setting Input/Output Format)

使用VIDIOC_S_FMT命令设置数据的输入/输出格式,例如分辨率,像素格式等。

v4l2_format fmt;
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt.fmt.pix.width = 640;
fmt.fmt.pix.height = 480;
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
if (ioctl(fd, VIDIOC_S_FMT, &fmt) == -1) {// 设置格式失败,处理错误
}

1.2.4 请求并映射缓冲区(Requesting and Mapping Buffers)

使用VIDIOC_REQBUFS命令请求缓冲区,然后使用mmap系统调用将缓冲区映射到用户空间。

v4l2_requestbuffers req;
req.count = 4;
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = V4L2_MEMORY_MMAP;
if (ioctl(fd, VIDIOC_REQBUFS, &req) == -1) {// 请求缓冲区失败,处理错误
}void* buffer = mmap(NULL, req.size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (buffer == MAP_FAILED) {// 映射缓冲区失败,处理错误
}

1.2.5 读取数据(Reading Data)

在设置好摄像头和缓冲区之后,就可以开始读取数据了。我们可以使用VIDIOC_QBUFVIDIOC_DQBUF命令将缓冲区入队和出队,从而读取到数据。

v4l2_buffer buf;
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = 0;
if (ioctl(fd, VIDIOC_QBUF, &buf) == -1) {// 将缓冲区入队失败,处理错误
}if (ioctl(fd, VIDIOC_DQBUF, &buf) == -1) {// 将缓冲区出队失败,处理错误
}// 现在,buf.bytesused指示了有效数据的长度,我们可以从buffer开始读取数据

以上是在ARM Linux下使用V4L2进行数据采集的基本步骤。在实际使用中,还需要根据具体的硬件和需求进行适当的调整和优化。

1.3 常见问题和解决方案(Common Problems and Solutions)

在进行数据采集时,我们可能会遇到各种问题。以下是一些常见问题及其解决方案。

1.3.1 无法打开设备(Cannot Open Device)

如果无法打开设备,首先要检查设备文件的路径是否正确。如果路径正确,可能是权限问题。在Linux系统中,设备文件的权限默认可能不允许普通用户访问。我们可以使用chmod命令修改设备文件的权限,或者以root用户身份运行程序。

sudo chmod 666 /dev/video0

1.3.2 设置的格式不支持(Unsupported Format)

如果摄像头不支持我们设置的分辨率或像素格式,ioctl调用将返回错误。在这种情况下,我们需要查询摄像头支持的格式,然后选择一个合适的格式。我们可以使用VIDIOC_ENUM_FMT命令查询摄像头支持的所有格式。

v4l2_fmtdesc fmt;
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
for (int i = 0; ; i++) {fmt.index = i;if (ioctl(fd, VIDIOC_ENUM_FMT, &fmt) == -1) {break;  // 查询完所有支持的格式}// 输出或使用fmt.pixelformat
}

1.3.3 缓冲区溢出(Buffer Overflow)

如果我们不及时读取数据,缓冲区可能会溢出,导致数据丢失。为了防止这种情况,我们需要在一个独立的线程中不断地读取数据,保证缓冲区始终有足够的空间。另外,我们也可以尝试增加缓冲区的数量或大小,以便存储更多的数据。

以上是在数据采集过程中可能遇到的一些常见问题及其解决方案。在实际应用中,可能还会有其他问题,需要我们根据具体情况进行分析和处理。

2. 从板端编码视频(Video Encoding at the Board End)

2.1 视频编码基础知识(Basics of Video Encoding)

视频编码是一个复杂而有趣的过程,它涉及到很多不同的概念和技术。这个过程就像我们在打包行李箱一样,我们需要把大量的衣物(在这里类比为视频数据)通过合理的方式放入行李箱,使其占用空间最小,这样我们才能把行李箱(即编码后的视频)轻松地带到我们想要去的地方。

视频编码的目的就是减小视频数据的大小,使其更便于存储和传输,而不会显著地损失视频质量。那么我们应该如何做到这一点呢?让我们来了解一下基本的视频编码过程。

编码过程

视频编码的过程可以分为以下几个步骤:

  1. 预处理(Preprocessing): 这个阶段主要是对原始视频数据进行一些基本的处理,比如去噪、降采样等,为后续的编码过程做准备。
  2. 转换(Transform): 这个阶段会将视频数据从空间域转换到频域,这样可以更好地表示数据的信息,同时也可以方便进行压缩。
  3. 量化(Quantization): 这个阶段是对转换后的数据进行量化,也就是对数据进行取舍,保留更多重要的信息,丢弃一些不那么重要的信息。
  4. 编码(Encoding): 这个阶段会将量化后的数据进行进一步的压缩,比如通过熵编码等方式,将数据编码为二进制序列。

这个过程就像我们在打包行李箱时先选择需要带的衣物,然后把衣物按照一定的方式折叠起来,最后把折叠好的衣物放入行李箱。通过这样的过程,我们可以把大量的衣物放入一个小小的行李箱。

以下是一个视频编码过程的简化版表格:

步骤描述
预处理对原始视频数据进行基本处理
转换将视频数据从空间域转换到频域
量化对转换后的数据进行量化
编码将量化后的数据进行进一步的压缩

编码标准

视频编码有许多不同的标准,比如H.264, H.265(也叫HEVC)等。这些标准定义了

如何进行视频编码,以及如何对编码后的视频进行解码。选择不同的编码标准,可以得到不同的编码效果和性能。

H.264是当前最常用的视频编码标准,它提供了良好的压缩性能和视频质量。H.265是H.264的后继者,它提供了更高的压缩比和更好的视频质量,但是需要更高的计算资源。

在选择编码标准时,我们需要考虑许多因素,比如我们希望得到的视频质量、我们可用的存储空间和传输带宽、以及我们可用的计算资源等。

以上就是视频编码的基础知识。在了解了这些基础知识后,我们就可以更好地理解视频编码的过程和原理,这将对我们进行视频编码的实践工作有很大的帮助。

2.2 ARM Linux环境下的视频编码实践(Video Encoding Practice on ARM Linux)

在了解了视频编码的基础知识后,我们现在将深入探讨在ARM Linux环境下进行视频编码的实践过程。我们的目标是将摄像头采集到的数据进行编码,然后生成H.264或H.265格式的视频文件。

硬件和软件环境

我们将在ARM Linux环境下进行实践,这样的环境通常在嵌入式设备上比较常见。在硬件方面,我们需要一个支持视频输入的ARM板卡,以及一个摄像头模块。在软件方面,我们需要一个Linux操作系统,以及一些视频处理的库,如V4L2、FFmpeg等。

视频编码过程

我们的视频编码过程大致如下:

  1. 捕获摄像头数据: 我们首先需要使用V4L2库来捕获摄像头的数据。V4L2是Video for Linux 2的简称,它是Linux下的一个视频设备驱动框架。通过V4L2,我们可以控制摄像头设备,获取摄像头的视频数据。

  2. 预处理视频数据: 捕获到的摄像头数据通常是原始的YUV格式,我们需要进行一些预处理,比如转换颜色空间、改变分辨率等。

  3. 编码视频数据: 接下来,我们将使用FFmpeg库来进行视频编码。FFmpeg是一个非常强大的音视频处理库,它支持多种编码格式,包括H.264、H.265等。我们可以通过设置FFmpeg的参数,选择合适的编码格式,然后将预处理后的视频数据进行编码。

  4. 存储或传输编码后的视频: 最后,我们将编码后的视频数据存储到文件中,或者通过网络进行传输。如果是存储到文件中,我们可以使用FFmpeg提供的封装功能,将编码后的视频数据封装成MP4或其他格式的文件。如果是通过网络传输,我们可以选择合适的网络协议,如RTSP、RTP等。

下面是视频编码过程的简化版表格:

步骤描述
捕获摄像头数据使用V4L2库来获取摄像头的视频数据
预处理视频数据对摄像头数据进行预处理,如转换颜色空间、改变分辨率等
编码视频数据使用FFmpeg库来进行视频编码
存储或传输视频将编码后的视频数据存储到文件中,或者通过网络进行传输

这就是在ARM Linux环境下进行视频编码的基本过程。在实际的工作中,我们可能还需要根据具体的需求,对这个过程进行一些定制和优化。

2.3 提升视频编码效率的策略(Strategies to Improve Video Encoding Efficiency)

在进行视频编码的过程中,我们总是希望能够达到更高的编码效率,即在保证视频质量的前提下,尽可能地减小编码后的视频大小。下面,我们将介绍几种提升视频编码效率的策略。

使用更高效的编码标准

如上文所述,视频编码标准的选择对编码效率有重要的影响。使用更高效的编码标准,比如从H.264升级到H.265,可以在相同的视频质量下,大幅度地减小编码后的视频大小。

调整编码参数

在进行视频编码的过程中,我们可以通过调整编码参数,来提升编码效率。比如,我们可以调整量化参数(QP),来控制编码过程中的数据损失;我们也可以选择更高级的预测模式,来提高编码效率。

利用硬件加速

很多现代的处理器,都提供了硬件加速的功能,可以显著提升视频编码的速度。如果你的环境中有这样的硬件资源,那么利用硬件加速是一个非常有效的提升编码效率的方法。

并行编码

如果你有多核的处理器,那么你可以通过并行编码,来提高编码效率。并行编码就是同时进行多个视频帧的编码,每个视频帧由一个处理器核心来处理。这样,我们可以大幅度地提高视频编码的速度。

下面是提升视频编码效率的策略的简化版表格:

策略描述
使用更高效的编码标准选择更高效的编码标准,如从H.264升级到H.265
调整编码参数通过调整编码参数,如量化参数(QP)和预测模式,来提高编码效率
利用硬件加速利用处理器提供的硬件加速功能,来提高编码速度
并行编码利用多核处理器,同时进行多个视频帧的编码,以提高编码速度

以上就是我们可以采用的一些提升视频编码效率的策略。希望这些内容对你在进行视频编码时有所帮助。

3. Qt在视频处理中的应用(Application of Qt in Video Processing)

3.1 Qt视频处理框架简介(Introduction to Qt Video Processing Framework)

Qt是一套跨平台的应用程序开发框架,广泛应用于桌面应用、嵌入式设备,甚至是手机应用的开发中。在处理视频数据方面,Qt提供了多个模块来支持我们进行开发,例如:QtMultimedia, QtAV等。

接下来,我会详细的介绍一些这些模块的基本功能和用法。

(1) QtMultimedia模块

QtMultimedia模块为音频,视频,广播和摄像头提供了API。一方面,这个模块让我们能够在Qt程序中播放音频和视频,另一方面,它也让我们可以使用Qt来处理音频数据,进行视频采集等操作。

以下是一个使用QtMultimedia播放视频的简单例子:

#include <QMediaPlayer>
#include <QVideoWidget>// 创建一个媒体播放器和一个视频播放组件
QMediaPlayer *player = new QMediaPlayer;
QVideoWidget *videoWidget = new QVideoWidget;player->setVideoOutput(videoWidget);// 设置要播放的视频的URL
player->setMedia(QUrl("http://example.com/myvideo.mp4"));videoWidget->show();
player->play();

(2) QtAV模块

QtAV模块是另一个基于Qt和FFmpeg开发的音视频处理框架,它提供了许多高级的音视频处理功能,包括但不限于硬件加速,视频特效,滤镜等。

以下是一个使用QtAV播放视频的简单例子:

#include <QtAV/AVPlayer>
#include <QtAV/WidgetRenderer>// 创建一个播放器和一个渲染器
AVPlayer *player = new AVPlayer;
WidgetRenderer *renderer = new WidgetRenderer;player->setRenderer(renderer);// 设置要播放的视频的URL
player->setMedia(QUrl("http://example.com/myvideo.mp4"));renderer->show();
player->play();

这只是Qt视频处理框架的冰山一角,更多的功能等待着我们去探索。通过学习和实践,我们可以使用Qt构建出强大的视频处理应用程序。希望这个简单的介绍能给你在Qt视频处理的道路上提供一些帮助。

3.2 使用Qt进行视频播放和处理的实践(Practice of Video Playback and Processing with Qt)

对于不同的应用场景,我们可以借助Qt的强大功能来进行视频的播放和处理。以下分别以视频播放和视频滤镜为例,简述一下在实践中如何使用Qt。

(1) 视频播放

视频播放是Qt在音视频处理中的基本应用之一,借助QtMultimedia模块,我们可以快速实现一个简单的视频播放器。

首先,我们需要创建一个QMediaPlayer和一个QVideoWidget实例,然后使用setVideoOutput()方法将视频输出设置为QVideoWidget

#include <QMediaPlayer>
#include <QVideoWidget>QMediaPlayer *player = new QMediaPlayer;
QVideoWidget *videoWidget = new QVideoWidget;player->setVideoOutput(videoWidget);

然后,我们可以使用setMedia()方法设置要播放的视频文件或者URL,最后调用play()方法开始播放:

player->setMedia(QUrl("http://example.com/myvideo.mp4"));videoWidget->show();
player->play();

(2) 视频滤镜处理

除了基本的视频播放,我们还可以使用Qt来进行更复杂的视频处理,比如添加视频滤镜。

QtAV模块中的VideoFilter类提供了添加视频滤镜的功能,以下是一个简单的例子,我们创建一个自定义滤镜,并添加到视频播放器中:

#include <QtAV/VideoFilter>
#include <QtAV/AVPlayer>class MyFilter : public QtAV::VideoFilter
{
public:bool isSupported(QtAV::VideoFilterContext &context) override{// 检查当前环境是否支持这个滤镜return context.type() == QtAV::VideoFilterContext::QtPainter;}void process(QList<QtAV::VideoFrame> &frames) override{// 在这里处理每一帧视频for (QtAV::VideoFrame &frame : frames){// 添加滤镜的处理逻辑}}
};AVPlayer *player = new AVPlayer;// 创建一个自定义滤镜并添加到播放器中
MyFilter *filter = new MyFilter;
player->installFilter(filter);

以上就是在实践中如何使用Qt进行视频播放和处理的一些例子,这些只是表面的应用,更深入的使用需要结合实际的需求和具体的项目情况。希望这些例子能为你的学习提供一些参考和启发。

3.3 Qt的音视频同步处理技术(Qt’s Audio and Video Synchronization Processing Technology)

音视频同步是一项在多媒体处理中至关重要的技术。一个好的音视频同步机制能够保证用户享受流畅的观看体验。对于Qt来说,这种同步机制也同样重要,因此,Qt提供了一套有效的机制来处理音视频同步。

音频和视频的同步基于一个简单的概念:时间戳(timestamp)。每个音频和视频帧在被解码之后都会被赋予一个时间戳,该时间戳表示了该帧应该在什么时候被呈现。Qt音视频同步的关键在于确保音频和视频帧在他们的时间戳指定的时间被呈现。

以下是一个简单的Qt音视频同步的示例:

#include <QMediaPlayer>
#include <QVideoWidget>
#include <QAudioOutput>// 创建一个媒体播放器,一个视频播放组件,一个音频输出组件
QMediaPlayer *player = new QMediaPlayer;
QVideoWidget *videoWidget = new QVideoWidget;
QAudioOutput *audioOutput = new QAudioOutput;player->setVideoOutput(videoWidget);// 将音频输出设置为QAudioOutput
player->setAudioOutput(audioOutput);// 设置要播放的媒体的URL
player->setMedia(QUrl("http://example.com/myvideo.mp4"));videoWidget->show();
player->play();

在这个例子中,QMediaPlayer会自动处理音频和视频的同步问题。它会确保在时间戳指定的时间播放对应的音频和视频帧,从而实现音视频同步。

然而,在一些更复杂的情况下,我们可能需要更深入的控制音视频同步。例如,我们可能需要处理网络延迟、缓冲区下溢等情况。在这些情况下,Qt提供了一些更低级别的API,如QAbstractAudioOutputQAbstractVideoOutput,让我们可以更深入地控制音视频同步。

在任何情况下,音视频同步都是一项复杂但至关重要的任务。通过深入理解和妥善应用Qt的音视频同步技术,我们可以创建出更专业、更强大的多媒体应用程序。

4. C++11、14、17、20在视频处理中的运用(Application of C++11, 14, 17, 20 in Video Processing)

4.1 C++新特性在视频处理中的应用(Application of New C++ Features in Video Processing)

在处理视频数据时,我们经常需要处理大量的数据和复杂的数据结构。幸运的是,C++11,14,17,20的一些新特性可以帮助我们更好地处理这些问题。

1. 自动类型推断(auto)

在处理视频数据时,我们可能需要使用很多复杂的数据结构和类型。使用auto关键字,我们可以让编译器自动推断变量的类型,这将大大简化我们的代码,并提高代码的可读性和可维护性。

例如,我们可能需要遍历一个包含视频帧的vector

std::vector<Frame> frames = video.getFrames();
for(auto it = frames.begin(); it != frames.end(); ++it){processFrame(*it);
}

2. 范围for循环(Range-based for loop)

auto关键字结合使用,范围for循环可以让我们更容易地遍历视频数据的集合:

for(auto& frame : frames){processFrame(frame);
}

3. 智能指针(Smart Pointers)

在处理视频数据时,我们常常需要动态分配和释放内存。智能指针可以帮助我们自动管理内存,防止内存泄漏:

std::shared_ptr<Frame> frame = std::make_shared<Frame>();

4. 并行算法(Parallel Algorithms)

C++17引入了一系列并行算法,使得我们可以更容易地并行处理视频数据。例如,我们可以使用std::for_each并行地处理每一帧:

std::for_each(std::execution::par, frames.begin(), frames.end(), processFrame);

5. 概念(Concepts)

C++20引入了概念(Concepts),这是一种表达类型必须满足的接口(即一组必须具有的函数)的方式。这使得我们可以更清晰地表达我们的意图,并编写更健壮的代码:

template<typename T>
concept Frame = requires(T t) {{t.getWidth()} -> std::convertible_to<int>;{t.getHeight()} -> std::convertible_to<int>;{t.getData()} -> std::convertible_to<std::vector<uint8_t>>;
};void processFrame(Frame auto& frame) {//...
}

以上是C++新特性在视频处理中的一些应用实例,通过这些实例,我们可以看到,C++的新特性不仅可以提高代码的效率,而且可以提高代码的可读性和可维护性。

4.2 用C++构建高效的视频处理框架(Building an Efficient Video Processing Framework with C++)

在处理视频数据时,我们需要一个能高效、灵活地处理视频数据的框架。C++的一些特性,如RAII、模板、STL等,使其成为构建此类框架的理想语言。接下来,我们将介绍如何用C++构建一个高效的视频处理框架。

1. 使用RAII管理资源

在处理视频数据时,我们需要管理各种资源,如内存、文件句柄、线程等。RAII(资源获取即初始化)是C++的一个重要特性,可以帮助我们在对象生命周期中自动管理这些资源:

class Frame {
private:uint8_t* data;
public:Frame(size_t size) : data(new uint8_t[size]) {}~Frame() { delete[] data; }// ...
};

2. 使用模板实现泛型编程

模板是C++中实现泛型编程的一种机制,我们可以用模板创建能处理不同类型数据的函数或类,从而提高代码的复用性:

template<typename T>
void process(T& data) {// ...
}Frame frame;
process(frame);

3. 使用STL处理数据

STL(标准模板库)提供了一系列的容器和算法,可以帮助我们更高效地处理数据:

std::vector<Frame> frames = video.getFrames();
std::sort(frames.begin(), frames.end(), [](const Frame& a, const Frame& b) {return a.getTime() < b.getTime();
});

4. 使用多线程提高处理速度

C++11引入了多线程库,我们可以用它来并行处理视频数据,提高处理速度:

std::vector<std::thread> threads;
for(auto& frame : frames) {threads.emplace_back([&]() {processFrame(frame);});
}
for(auto& thread : threads) {thread.join();
}

以上是使用C++构建高效视频处理框架的一些策略。通过这些策略,我们可以创建一个既能处理复杂数据,又能快速执行的视频处理框架。

4.3 C++在音视频处理中的最佳实践(Best Practices of C++ in Audio and Video Processing)

音视频处理是一项复杂且对性能要求极高的任务。在实践中,我们需要充分利用C++的特性来编写高效、可维护的代码。以下是在音视频处理中使用C++的一些最佳实践:

1. 坚持使用RAII管理资源

如前所述,RAII(资源获取即初始化)是C++的一项重要特性,可以帮助我们自动管理资源。我们应尽量使用智能指针而非裸指针,以防止内存泄漏和无效引用:

std::unique_ptr<Frame> frame(new Frame());

2. 避免过度优化

虽然C++提供了许多优化代码的手段,但过度优化会让代码变得难以理解和维护。在大部分情况下,编译器可以很好地优化我们的代码,我们应专注于编写清晰、简洁的代码:

// 不好的做法
for(int i = 0; i < frames.size(); ++i) {// ...
}// 好的做法
for(auto& frame : frames) {// ...
}

3. 利用现代C++特性

现代C++(C++11及以后的版本)引入了许多有用的特性,如自动类型推断、范围for循环、智能指针等。我们应充分利用这些特性来提高代码质量:

// 不好的做法
std::vector<Frame>::iterator it = frames.begin();
for(; it != frames.end(); ++it) {// ...
}// 好的做法
for(auto& frame : frames) {// ...
}

4. 尽量减少数据拷贝

在处理大量音视频数据时,我们应尽量减少数据拷贝,以提高性能:

// 不好的做法
void process(Frame frame) {// ...
}// 好的做法
void process(const Frame& frame) {// ...
}

以上是在音视频处理中使用C++的一些最佳实践。通过遵循这些最佳实践,我们可以编写出高效、可维护的代码。

5. 摄像头采集的数据格式与处理(Data Format and Processing of Camera Acquisition)

5.1 摄像头数据格式概述(Overview of Camera Data Format)

在深入探讨摄像头数据格式之前,让我们先借用一种心理学的隐喻:摄像头可以被视为一个“视觉翻译家”,它的任务是将现实世界的光线信息翻译成我们计算机可以理解的电子数据。它所看到的每一个场景,每一个物体,都会被转化成数值和编码的形式,这就是我们所说的摄像头数据。

现代摄像头采集的数据一般有两种主要类型:RAW格式和YUV格式。它们分别对应了摄像头传感器最初接收到的未经处理的光电信号和经过一定处理后更符合人眼视觉感知的格式。

RAW格式

RAW格式是摄像头传感器原始数据,通常采用Bayer滤波器阵列。Bayer阵列由红、绿、蓝三种颜色滤波器组成,按一定比例(通常绿色滤波器的数量是红色和蓝色的两倍)排列,使得每个像素点只能接收一种颜色的光线。这就形成了一个颜色稀疏的图像,我们需要后续的色彩插值算法才能得到全色图像。

绿色红色绿色红色
蓝色绿色蓝色绿色
绿色红色绿色红色
蓝色绿色蓝色绿色

YUV格式

YUV是一种颜色编码方法,其中Y表示明度(Luma),用来表示黑白影像,U和V则表示色度(Chroma),用来表示色彩和饱和度。YUV格式的优点是能更符合人眼的视觉感知特性,节省数据传输带宽。

让我们将它想象成一种语言,Y就是语言的基础——文字,而U和V则是语言的修饰——语调和语气。这种方式使得我们即使只有Y,也能获取到黑白的基本信息,而有了U和V,我们就能更准确地表达颜色的丰富多彩。

在摄像头中,RAW数据需要经过一系列的图像处理步骤(例如白平衡、色彩插值、降噪等)才能转换成YUV格式。

以上就是摄像头数据格式的基本概述。在接下来的章节中,我们将会深入

了解如何将这些数据转换为常用的视频格式,以及这些数据格式与其他常见的数据格式(如RGB、TS流等)之间的关系。

5.2 从摄像头数据到常用视频格式(From Camera Data to Common Video Formats)

摄像头采集的原始数据(RAW或YUV格式)需要经过一定的处理和转换才能变成我们常见的视频格式,例如H.264和H.265。这个过程就像是把电影剧本变成我们在银幕上看到的电影,不仅需要把原始素材拼接和编辑起来,还需要进行一些特效和后期处理。

YUV到H.264

H.264是一种广泛应用的视频编码格式,它能有效地压缩视频数据,同时保持良好的视频质量。H.264编码过程可以简单地分为三个步骤:预处理、变换编码和熵编码。

  1. 预处理:首先,将YUV格式的数据分割成宏块(Macroblock)。

  2. 变换编码:然后,通过离散余弦变换(Discrete Cosine Transform, DCT)和量化等步骤,将每个宏块的数据进行压缩。

  3. 熵编码:最后,利用CABAC或CAVLC等熵编码方法,对编码后的数据进行进一步的压缩。

预处理变换编码熵编码
YUV分割DCT变换CABAC编码
分割成宏块量化CAVLC编码

YUV到H.265

H.265(又称HEVC,High Efficiency Video Coding)是H.264的升级版本,能提供相同质量的视频,但只需要H.264一半的数据量。这个过程类似于写作,H.265就好像是一个更经济、更精炼的写作风格,能用更少的字词来表达同样的意思。

H.265相较于H.264,引入了一些新的技术和改进,例如更灵活的宏块划分、改进的熵编码算法等,使得编码效率更高。

更灵活的宏块划分改进的熵编码算法
宏块大小可变CABAC编码优化

摄像头数据转换到H.264或H.265的过程涉及大量的图像处理和编码技术,需要一定的时间和计算资源。然而,这个过程对于实时视频处理和传输是至关重要的,因为它能大大降低数据传输带宽的需求,使得我们能够在网络上流畅地观看高清视频。

在接下来的章节中,我们会详细介绍这些视频编码格式与其他常见的数据格式(例如RGB、TS流等)之间的关系,以及如何使用一些常见的工具和库(例如FFmpeg)进行这些转换和处理。

5.3 与YUV, RGB数据格式的关系(Relation with YUV, RGB Data Formats)

处理摄像头数据时,我们经常会遇到各种不同的数据格式。其中,YUV和RGB是两种常见的色彩空间,而TS流则是一种常见的视频流格式。这些不同的数据格式,就好像是不同的方言,它们之间虽然有相似之处,但也有各自的特点和规则。

YUV与RGB

YUV和RGB是两种常见的色彩空间。在RGB色彩空间中,图像中的每个像素都由红、绿、蓝三种颜色的亮度值组成。在YUV色彩空间中,图像的颜色则是由亮度信息(Y)和色度信息(U和V)组成的。可以把RGB看作是一种直观、直接的颜色描述方式,而YUV则是一种更符合人眼视觉感知的颜色描述方式。

YUV与RGB之间可以通过一系列的数学运算进行转换。一般情况下,摄像头采集的数据需要先转换成YUV格式进行处理,然后再根据需要转换成RGB或其他格式。

YUV与TS流

TS流(Transport Stream)是一种常见的视频流格式,主要用于数字电视和流媒体等应用。TS流中的每一帧视频数据,都是由一系列的TS包组成的。这就像是把一整本书分成若干个小章节,每个章节都有自己的编号和索引,这样就可以方便地查找和阅读。

TS流通常包含经过H.264或H.265等编码的YUV数据,因此,从YUV到TS流,主要是通过视频编码和封装等步骤进行的。具体来说,首先需要把YUV数据进行H.264或H.265等编码,然后把编码后的数据封装成TS包,最后把这些TS包组合成TS流。

以上就是摄像头数据格式与YUV, RGB和TS流之间的关系。了解这些关系,不仅有助于我们更好地理解摄像头数据的处理流程,也有助于我们在开发和优化应用时做出合理的选择和决策。在接下来的章节中,我们会更深入地探讨这些主题,并提供一些实际的编程示例和技巧。

6. 视频流处理和转换(Video Stream Processing and Conversion)

6.1 TS流和其它常用视频流介绍(Introduction to TS Stream and Other Common Video Streams)

视频流是连续的图像帧序列,通常通过互联网或其他网络进行传输。了解不同类型的视频流格式对于优化视频处理流程至关重要。本节将重点介绍TS流以及其他常见的视频流格式。

  1. TS流:TS(Transport Stream)是 MPEG-2 的标准,广泛应用于数字电视系统(如DVB, ATSC)和音频/视频封装。TS流被设计成能在错误发生时也能保持同步,并且可以通过多种方式进行传输。TS流中的每个包的大小为188字节,其中包含了PID(Packet ID)来标识各个数据流。

  2. PS流:PS(Program Stream)也是MPEG-2的标准,主要应用于存储介质,如DVD。与TS流相比,PS流不需要考虑传输错误的问题,因此在存储和播放上有优势。

  3. RTP/RTCP流:RTP(Real-time Transport Protocol)是一种网络传输协议,它允许在IP网络上进行实时音频和视频的传输。RTCP(Real-time Transport Control Protocol)是RTP的配套协议,用于为RTP数据传输提供辅助功能。

  4. RTMP流:RTMP(Real Time Messaging Protocol)是一种设计用来进行实时信息传输的协议,广泛应用于流媒体系统中。

以下是一个简单的表格,用以对比各种视频流的特性:

视频流类型应用领域特点
TS流数字电视系统,音视频封装具有较好的容错性,可以通过多种方式传输
PS流存储介质,如DVD不需要考虑传输错误的问题,适合存储和播放
RTP/RTCP流IP网络上的实时音视频传输实时性强,支持多种数据类型传输
RTMP流流媒体系统支持实时信息传输,常用于直播系统

以上内容介绍了TS流及其它常用视频流的基本概念和特性。理解这些概念将有助于我们更好地处理和优化视频流。下一节,我们将详细介绍如何进行视频流格式的转换。

6.2 视频流格式的转换过程(Conversion Process of Video Stream Formats)

视频流格式的转换是音视频处理中一个重要的环节,它涉及到编解码技术、封装格式、网络传输等多个方面。本节我们将介绍一些常见的视频流格式转换技术和步骤。

一般来说,视频流格式的转换包含以下步骤:

  1. 解码:首先,我们需要将源视频流进行解码。解码的目的是将压缩的视频数据转换为未压缩的原始数据,如YUV或RGB格式。

  2. 处理:解码后的数据可以进行一些处理操作,如缩放、裁剪、滤波等。

  3. 编码:处理后的数据需要重新编码,将其转换为目标格式的视频数据。这里可能会涉及到选择合适的编码器,以及配置合适的编码参数。

  4. 封装:最后,将编码后的数据封装到目标格式的容器中。这里需要注意的是,不同的视频流格式可能需要不同的封装方法。

以将H.264编码的TS流转换为H.265编码的MP4格式为例,具体步骤可能如下:

  1. 使用H.264解码器将TS流中的视频数据解码为YUV格式的原始数据。
  2. 对YUV数据进行需要的处理操作。
  3. 使用H.265编码器将处理后的YUV数据编码为H.265格式的视频数据。
  4. 将H.265视频数据封装到MP4容器中。

需要注意的是,不同的视频流格式转换可能需要不同的工具和技术。例如,FFmpeg是一个非常强大的音视频处理工具,它提供了丰富的API接口,可以实现各种复杂的视频流格式转换操作。具体的编程实践将在后面的章节中详细介绍。

希望这个章节能帮助您理解视频流格式转换的基本步骤和原理。在实际的工作中,我们可能需要根据实际需求和环境条件,选择最合适的转换方法和工具。

6.3 实现流处理的关键技术(Key Technologies to Implement Stream Processing)

在处理视频流数据时,需要用到一些关键技术,它们共同保证了视频流的稳定传输和高效处理。这些关键技术包括:

  1. 缓冲管理:在处理视频流数据时,有效的缓冲管理是至关重要的。首先,需要有足够的缓冲区来存储接收或待处理的数据,以防止数据丢失。同时,合理的缓冲管理策略可以降低延迟,提高处理效率。

  2. 数据同步:在多线程或多进程环境下,数据同步是必须要考虑的问题。我们需要保证不同的线程或进程之间可以在正确的时间顺序上共享和处理数据。

  3. 错误处理:在数据传输过程中,可能会出现各种错误,如网络中断、数据丢失、编解码错误等。有效的错误处理策略可以及时发现并处理这些错误,确保视频流的稳定传输。

  4. 网络传输:对于网络视频流,网络传输的稳定性和效率是非常重要的。我们需要选择合适的传输协议,如TCP、UDP、RTMP等,并优化网络参数,以提高视频流的传输效率。

  5. 编解码技术:编解码技术是视频流处理的核心。选择合适的编解码器,以及配置合适的编解码参数,可以显著影响视频流的质量和效率。

7. FFmpeg在视频处理中的应用(Application of FFmpeg in Video Processing)

7.1 FFmpeg简介及其作用(Introduction and Role of FFmpeg)

FFmpeg 是一个开源的音视频处理工具库,它拥有丰富的音视频处理功能,包括采集、编解码、转码、流媒体、滤镜处理等,几乎涵盖了音视频处理的全部流程。由于其强大的功能和优秀的性能,FFmpeg在业界得到了广泛的应用和认可。

接下来,我们可以通过一个表格来进一步理解FFmpeg的主要组成部分及其作用:

组件描述
libavcodecFFmpeg的核心部分之一,提供了丰富的音视频编解码功能。
libavformat主要处理音视频封装格式,能够自动识别和生成多种音视频封装格式。
libavfilter提供了丰富的音视频滤镜功能,例如裁剪、旋转、颜色转换等。
libavdevice主要负责处理设备相关的操作,如音视频的采集和渲染。
libavutil提供了一些公共的工具函数,例如数学运算、字符串处理等。
libswresample用于处理音频重采样。
libswscale主要负责处理视频像素格式转换和图像缩放。

FFmpeg的主要作用是提供了一个全面的、统一的平台,用于处理音视频数据。它的强大之处在于,无论是处理复杂的音视频编码问题,还是进行简单的格式转换,FFmpeg都能够胜任。无论是开发者,还是普通用户,都能够从FFmpeg中找到满足自己需求的解决方案。

7.2 FFmpeg的编程应用实例(Programming Application Examples of FFmpeg)

FFmpeg不仅是一个强大的命令行工具,也是一个为开发者提供的广泛应用的库。通过编程接口,开发者可以在自己的应用程序中利用FFmpeg的功能。以下是一些在编程中使用FFmpeg的实例:

1. 读取媒体文件的元数据

许多应用需要获取媒体文件的基本信息,例如视频的分辨率,视频编码格式,视频长度等。FFmpeg提供了接口可以方便地获取这些信息。例如:

extern "C" {#include <libavformat/avformat.h>
}int main() {avformat_network_init();AVFormatContext *pFormatCtx = avformat_alloc_context();if (avformat_open_input(&pFormatCtx, "input.mp4", NULL, NULL) != 0) {return -1; // Couldn't open file}// Retrieve stream informationif (avformat_find_stream_info(pFormatCtx, NULL) < 0) {return -1; // Couldn't find stream information}// Print detailed information about the input or output formatav_dump_format(pFormatCtx, 0, "input.mp4", 0);avformat_close_input(&pFormatCtx);return 0;
}

上述代码首先打开了一个媒体文件,然后获取并打印了媒体文件的元数据。

2. 转码媒体文件

转码是最常见的媒体文件处理任务之一。FFmpeg提供了一系列的API,开发者可以方便地实现媒体文件的转码。以下是一个基本的转码示例:

extern "C" {#include <libavcodec/avcodec.h>#include <libavformat/avformat.h>
}int main() {// ... initialization and open input file ...// Find the decoder for the video streamAVCodecContext *pCodecCtx = pFormatCtx->streams[videoStream]->codec;AVCodec *pCodec = avcodec_find_decoder(pCodecCtx->codec_id);if(pCodec == NULL) {return -1; // Codec not found}// Open codecif(avcodec_open2(pCodecCtx, pCodec, NULL)<0) {return -1; // Could not open codec}// ... read frames and decode ...// Close the codecavcodec_close(pCodecCtx);// Close the video fileavformat_close_input(&pFormatCtx);return 0;
}

这段代码首先打开输入的媒体文件,然后找到合适的编解码器,对每一帧进行解码和再编码,最后将结果写入输出文件。

FFmpeg提供的接口不仅可以完成这些基本任务,还有许多高级功能,如滤镜效果,音频重采样,图像缩放等。开发者可以通过深入学习FFmpeg,发挥其强大的功能,为用户提供更好的音视频体验。

7.3 FFmpeg的高级应用与优化(Advanced Applications and Optimization of FFmpeg)

在掌握了FFmpeg的基础应用之后,我们可以进一步挖掘它的高级功能以及进行一些优化操作,以便更好地满足我们对音视频处理的需求。以下是一些常见的高级应用和优化方法:

1. 利用滤镜进行音视频特效处理

FFmpeg提供了丰富的音视频滤镜,可以用于实现各种音视频特效。例如,我们可以用“scale”滤镜来改变视频的分辨率,用“atempo”滤镜来改变音频的播放速度。这些滤镜都可以通过编程接口或命令行参数进行调用。

ffmpeg -i input.mp4 -vf "scale=1280:720" output.mp4  # 缩放视频分辨率
ffmpeg -i input.mp3 -af "atempo=0.5" output.mp3  # 降低音频播放速度

2. 利用硬件加速进行编解码优化

在处理大量或高分辨率的音视频数据时,编解码的效率非常重要。FFmpeg提供了硬件加速功能,可以大大提高编解码的速度。例如,我们可以利用NVIDIA的NVENC进行H.264的硬件加速编码。

ffmpeg -i input.mp4 -c:v h264_nvenc output.mp4

3. 使用多线程技术提高处理速度

FFmpeg本身支持多线程,如果你的程序或系统支持多核处理,可以设置线程数量以提高处理速度。这在处理大量数据或进行复杂计算时特别有用。

ffmpeg -i input.mp4 -threads 4 output.mp4

以上是一些FFmpeg的高级应用和优化方法。每一种方法都可以根据你的具体需求进行调整和优化。在实际应用中,我们可以根据项目的具体需求,结合FFmpeg的丰富功能和灵活性,制定最合适的音视频处理策略。

结语

结语:在本文中,我们深入探讨了ARM Linux下摄像头传感器数据处理的全景视野,从底层原理到上层高级应用,以及使用C++和Qt进行编程的技巧。我们了解了摄像头传感器的基础知识,学习了视频编码和格式转换的关键技术,并介绍了FFmpeg在视频处理中的重要作用。

然而,在学习和应用这些知识和技术的过程中,我们常常会面临各种困难和挑战。但是,正是这些困难激发了我们的求知欲和创造力。无论是遇到数据采集问题、视频编码效率低下还是格式转换困扰,我们都要保持积极向上的态度。

学习是一个不断探索和成长的过程。我鼓励你不要害怕挑战,勇敢面对困难。通过阅读本文,你已经迈出了一大步,但还有更多知识等待着你去发现和掌握。将本文收藏起来,不断回顾和深入研究,与作者一起学习,我们可以相互激励、共同进步。

最后,我希望你能从本文中汲取知识的营养,将其应用于实际项目中,创造出令人惊叹的作品。无论你是一名编程专家还是初学者,持续学习和努力进步都是关键。相信自己的能力,相信你能克服任何困难,创造出杰出的成果。

希望这篇文章能给你带来启发和动力,鼓励你在ARM Linux摄像头传感器数据处理领域不断前进。请别忘记点赞和分享这篇文章,让更多人受益。一起成为积极向上的学习者,开创更美好的未来!

感谢你的阅读和支持!

作者

相关文章:

ARM Linux摄像头传感器数据处理全景视野:从板端编码视频到高级应用

ARM Linux摄像头传感器数据处理全景视野&#xff1a;从板端编码视频到高级应用 1. 摄像头传感器与数据采集&#xff08;Camera Sensor and Data Acquisition&#xff09;1.1 数字摄像头传感器基础&#xff08;Basics of Digital Camera Sensors&#xff09;1.1.1 传感器类型&am…...

Fixed Function Shader

Properties 属性 Shader语法不区分大小写 基础的数据类型 如何定义一个属性 属性要在"Properties{}"代码块中定义 Properties{_Color("Main Color",Color) (1,1,1,1)_Shininess("Shininess",range(0,8)) 4_MainTex("MainTex",2D…...

HTML- 标签学习之- 列表、表格

无序列表/有序列表&#xff1a; 标签组成( 无序ul 有序 ol ) -> li 父子级标签&#xff0c; ul只能包含li标签&#xff0c; li标签可以包含任意内容。 自定义列表 dl :自定义列表的整体&#xff0c;用于包裹dt/dd 标签dt:自定义列表主题dd:自定义列表的针对主题的…...

Canal搭建 idea设置及采集数据到kafka

Canal GitHub&#xff1a;https://github.com/alibaba/canal#readme 实时采集工具canal&#xff1a;利用mysql主从复制的原理&#xff0c;slave定期读取master的binarylog对binarylog进行解析。 canal工作原理 canal模拟MySQL slave的交互协议&#xff0c;伪装自己为MySQL slav…...

CentOS7搭建伪分布式Hadoop(全过程2023)

##具体操作目录## 1.配置静态ip2.关闭防火墙3.修改主机名为 *master* &#xff0c;并重启虚拟机vi /etc/hostname 4.修改主机名与ip映射5.设置SSH免密登录6.安装配置java环境----------------------正式Hadoop配置1.移动安装包到合适位置2.解压安装包并重命名3.配置环境变量4.修…...

Linux中文件描述符fd和文件指针filp的理解

简单归纳&#xff1a;fd只是一个整数&#xff0c;在open时产生。起到一个索引的作用&#xff0c;进程通过PCB中的文件描述符表找到该fd所指向的文件指针filp。 文件描述符的操作(如: open)返回的是一个文件描述符,内核会在每个进程空间中维护一个文件描述符表, 所有打开的文件…...

CSS color中常用英文色值

常用颜色英文 red green blue magenta yellow chocolate black aquamarine lime fuchsia brass azure brown bronze deeppink aliceblue gray copper coral feldspar orange orchid pink plum quartz purple aliceblue antiquewith blanchedalmond…...

Springboot idea 中 maven配置问题,找不到依赖:Could not find artifact xxxx

现象&#xff1a;当我们从代码仓拉取新项目时&#xff0c;从该项目的开发同事拿到其maven的settings文件&#xff0c;作为项目的maven配置&#xff0c;为了是能找到工程中所依赖的包&#xff0c;能从远程仓下载下来。 然后本地仓的包&#xff0c;也从同事那边拷贝一份过来&…...

编译原理笔记(一)引论

文章目录 1.什么是编译程序2.编译过程和编译程序的结构2.1.编译过程概述2.2.编译程序的结构2.3.编译阶段的组合 3.解释程序和一些软件工具3.1.解释程序3.2.处理源程序的软件工具 4.PL/0语言编译系统 学习总结&#xff1a;这一部分是编译原理的绪论部分内容&#xff0c;对编译程…...

C++ 类和对象下 [补充]

文章目录 友元内部类内部类是外部类的天生友元 匿名对象匿名对象的特性 拷贝对象时的一些编译器优化函数返回值临时空间的存储位置返回值临时空间具有常性 标题相同和不同类型 需要 临时空间 友元 友元函数 重载operator<< 输出自定义类型 比如日期类的这个重载&#xff…...

[CTF/网络安全] 攻防世界 PHP2 解题详析

[CTF/网络安全] 攻防世界 PHP2 解题详析 index.php.phps扩展名姿势 翻译&#xff1a;你能给这个网站进行身份验证吗&#xff1f; index.php index.php是一个常见的文件名&#xff0c;通常用于Web服务器中的网站根目录下。它是默认的主页文件名&#xff0c;在访问一个网站时&am…...

图神经网络:(节点分类)在Cora数据集上动手实现图神经网络

文章说明&#xff1a; 1)参考资料&#xff1a;PYG官方文档。超链。 2)博主水平不高&#xff0c;如有错误还望批评指正。 3)我在百度网盘上传了这篇文章的jupyter notebook。超链。提取码8888。 文章目录 代码实操1&#xff1a;GCN的复杂实现代码实操2&#xff1a;GCN的简单实现…...

RabbitMQ应用问题——消息补偿机制以及代码示例

RabbitMQ应用问题——消息补偿机制以及代码示例 RabbitMQ应用问题 消息可靠性的保障 消息补偿机制 详细说明 这里使用了简单的代码进行演示&#xff0c;订单的消费者没有写&#xff0c;在订单的消费同时&#xff0c;发送一条增加积分消息到积分队列。 详细流程途中都有注明…...

量化特征贡献度函数:feature_importances_函数/LGBMClassifier/XGBClassifier

feature_importances_是scikit-learn机器学习库中许多模型对象的属性&#xff0c;在训练模型之后调用该属性可以输出各个特征在模型中的重要性。 示例代码&#xff1a; from sklearn.ensemble import RandomForestRegressor from sklearn.datasets import make_regression# 生…...

总结JVM重要知识点

一.类加载和创建对象的过程 1.类加载 1.编译 : 将源码文件(.java)编译成JVM可以解释的.class文件 . 语法分析>语义分析>注解处理 , 生成class文件 2.加载 : 装载 : 字节码本来存储在硬盘上 , 需要运行时 , 有类加载系统负责将类的信息加载到内存中(方法区) , 使用的是类…...

奇技淫巧第8期

学无止境。 下面是对去年11月至今年5月的零散知识点总结。 春节期间好好放松了一两个月&#xff0c;来校后又懒散的度过了一两个月&#xff0c;直到论文评审意见下来&#xff0c;才开启冲刺模式狂干了一两个月。总的来说&#xff0c;这半年来摸的时间比较多。好&#xff0c;不废…...

这个 归并排序详解过程 我能吹一辈子!!!

文章目录 归并排序概念归并排序算法思路归并排序递归实现归并排序非递归实现 归并排序概念 1945年&#xff0c;约翰冯诺依曼&#xff08;John von Neumann&#xff09;发明了归并排序&#xff0c;这是典型的分治算法的应用。 归并排序&#xff08;Merge sort&#xff09;是建立…...

docker版jxTMS使用指南:自动生成代码

本文讲解4.0版jxTMS的自动生成代码功能&#xff0c; 整个系列的文章请查看&#xff1a;docker版jxTMS使用指南&#xff1a;4.0版升级内容 docker版本的使用&#xff0c;请参考&#xff1a;docker版jxTMS使用指南 任何一个管理系统都需要对管理对象进行管理&#xff0c;包括最…...

聚观早报 | 小冰启动GPT克隆人计划;ofo创始人在美创业改做咖啡

今日要闻&#xff1a;小冰启动“GPT克隆人计划”&#xff1b;ofo创始人在美创业改做咖啡&#xff1b;OpenAI正准备新的开源AI模型&#xff1b;青年失业率首破20&#xff05;创新高&#xff1b;微软收购动视暴雪获批 小冰启动“GPT克隆人计划” 5 月 16 日&#xff0c;小冰公司…...

面试造航母,入职拧螺丝,工资离了个大谱...

有粉丝跟我吐槽说&#xff1a;金三银四去面试软件测试岗&#xff0c;真的是面试造航母&#xff0c;入职拧螺丝&#xff0c;工资还低 这种现象很正常&#xff0c;因为找一个测试员&#xff0c;当然希望他能做的业务越多越好&#xff0c;最好像机器猫一样&#xff0c;啥事儿都能…...

进程地址空间(比特课总结)

一、进程地址空间 1. 环境变量 1 &#xff09;⽤户级环境变量与系统级环境变量 全局属性&#xff1a;环境变量具有全局属性&#xff0c;会被⼦进程继承。例如当bash启动⼦进程时&#xff0c;环 境变量会⾃动传递给⼦进程。 本地变量限制&#xff1a;本地变量只在当前进程(ba…...

css实现圆环展示百分比,根据值动态展示所占比例

代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...

Zustand 状态管理库:极简而强大的解决方案

Zustand 是一个轻量级、快速和可扩展的状态管理库&#xff0c;特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...

练习(含atoi的模拟实现,自定义类型等练习)

一、结构体大小的计算及位段 &#xff08;结构体大小计算及位段 详解请看&#xff1a;自定义类型&#xff1a;结构体进阶-CSDN博客&#xff09; 1.在32位系统环境&#xff0c;编译选项为4字节对齐&#xff0c;那么sizeof(A)和sizeof(B)是多少&#xff1f; #pragma pack(4)st…...

pam_env.so模块配置解析

在PAM&#xff08;Pluggable Authentication Modules&#xff09;配置中&#xff0c; /etc/pam.d/su 文件相关配置含义如下&#xff1a; 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块&#xff0c;负责验证用户身份&am…...

STM32F4基本定时器使用和原理详解

STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...

ServerTrust 并非唯一

NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)

在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

css3笔记 (1) 自用

outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size&#xff1a;0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格&#xff…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3

一&#xff0c;概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本&#xff1a;2014.07&#xff1b; Kernel版本&#xff1a;Linux-3.10&#xff1b; 二&#xff0c;Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01)&#xff0c;并让boo…...