yuv420p转rgb
时间: 2025-08-08 21:14:53 浏览: 6
### YUV420P 转换为 RGB 格式的方法
YUV420P 是一种常见的图像格式,通常用于视频编码和图像处理领域。它由一个 Y(亮度)平面和两个 U(色度)和 V(色度)平面组成,其中 Y 平面的分辨率为全分辨率,而 U 和 V 平面的分辨率是 Y 平面的一半。将 YUV420P 转换为 RGB 格式需要将 YUV 值转换为 RGB 值,并将数据重新排列为 RGB 格式。
#### 1. 手动实现 YUV420P 到 RGB 的转换
以下是一个手动实现的 C 函数,用于将 YUV420P 数据转换为 RGB 数据。该函数假设输入的 YUV420P 数据是连续存储的,并且输出的 RGB 数据为 24 位(即每个像素包含红、绿、蓝三个通道)。
```c
void yuv420p_to_rgb(unsigned char *yuv420p_data, unsigned char *rgb_data, int width, int height) {
int y_index = 0;
int u_index = width * height;
int v_index = u_index + (width * height / 4);
int rgb_index = 0;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
// 获取 YUV 值
unsigned char y_val = yuv420p_data[y_index++];
unsigned char u_val = yuv420p_data[u_index + (y / 2) * (width / 2) + (x / 2)];
unsigned char v_val = yuv420p_data[v_index + (y / 2) * (width / 2) + (x / 2)];
// 转换为 RGB
int r = y_val + 1.402 * (v_val - 128);
int g = y_val - 0.344 * (u_val - 128) - 0.714 * (v_val - 128);
int b = y_val + 1.772 * (u_val - 128);
// 确保 RGB 值在 0-255 范围内
r = (r < 0) ? 0 : ((r > 255) ? 255 : r);
g = (g < 0) ? 0 : ((g > 255) ? 255 : g);
b = (b < 0) ? 0 : ((b > 255) ? 255 : b);
// 存储 RGB 值
rgb_data[rgb_index++] = (unsigned char)r;
rgb_data[rgb_index++] = (unsigned char)g;
rgb_data[rgb_index++] = (unsigned char)b;
}
}
}
```
#### 2. 使用 OpenCV 进行转换
OpenCV 提供了内置的函数来处理 YUV420P 到 RGB 的转换。以下是一个使用 OpenCV 的示例代码片段:
```cpp
#include <opencv2/opencv.hpp>
void yuv420p_to_rgb_opencv(unsigned char *yuv420p_data, int width, int height, const std::string &output_file) {
// 创建 YUV 图像
cv::Mat yuvImg(height * 3 / 2, width, CV_8UC1, yuv420p_data);
// 创建 RGB 图像
cv::Mat rgbImg;
// 转换为 RGB
cv::cvtColor(yuvImg, rgbImg, cv::COLOR_YUV2BGR_I420);
// 保存图像
cv::imwrite(output_file, rgbImg);
}
```
#### 3. 使用 FFmpeg 进行转换
FFmpeg 是一个强大的多媒体处理库,可以用于图像和视频的格式转换。以下是一个使用 FFmpeg 的示例代码片段:
```c
#include <libswscale/swscale.h>
#include <libavutil/imgutils.h>
void yuv420p_to_rgb_ffmpeg(unsigned char *yuv420p_data, int width, int height, const std::string &output_file) {
// 创建上下文
struct SwsContext *sws_ctx = sws_getContext(width, height, AV_PIX_FMT_YUV420P,
width, height, AV_PIX_FMT_RGB24,
SWS_BILINEAR, NULL, NULL, NULL);
// 分配 AVFrame
AVFrame *frame = av_frame_alloc();
frame->width = width;
frame->height = height;
frame->format = AV_PIX_FMT_YUV420P;
frame->data[0] = yuv420p_data;
frame->data[1] = yuv420p_data + width * height;
frame->data[2] = yuv420p_data + width * height + (width * height / 4);
frame->linesize[0] = width;
frame->linesize[1] = width / 2;
frame->linesize[2] = width / 2;
// 分配输出 AVFrame
AVFrame *rgb_frame = av_frame_alloc();
rgb_frame->width = width;
rgb_frame->height = height;
rgb_frame->format = AV_PIX_FMT_RGB24;
av_image_alloc(rgb_frame->data, rgb_frame->linesize, width, height, AV_PIX_FMT_RGB24, 32);
// 转换
sws_scale(sws_ctx, frame->data, frame->linesize, 0, height, rgb_frame->data, rgb_frame->linesize);
// 保存图像(需要实现保存逻辑)
// ...
// 清理
av_frame_free(&frame);
av_frame_free(&rgb_frame);
sws_freeContext(sws_ctx);
}
```
### 总结
上述方法展示了如何将 YUV420P 格式转换为 RGB 格式。手动实现提供了对转换过程的详细控制,而使用 OpenCV 或 FFmpeg 则可以简化代码并提高开发效率。根据具体需求和环境选择合适的方法即可[^1]。
阅读全文
相关推荐



















