2024-05-10 Ubuntu上面使用libyuv,用于转换、缩放、旋转和其他操作YUV图像数据,测试实例使用I420ToRGB24

一、简介:libyuv 最初是由Google开发的,主要是为了支持WebRTC项目中的视频处理需求。用于处理YUV格式图像数据的开源库。它提供了一系列的函数,用于转换、缩放、旋转和其他操作YUV图像数据。

二、执行下面的命令下载和安装libyuv。

复制代码
git clone https://github.com/lemenkov/libyuv.git
cd libyuv
mkdir build && cd build
cmake ..
make
sudo make install

三、测试实例convert_yuv_to_rgb.cpp,使用c编译的时候,I420ToRGB24前面就不要有libyuv::。

复制代码
#include <stdio.h>
#include <stdlib.h>
#include "libyuv/convert_from.h"
#include "libyuv/convert.h"

int main() {
    FILE *input_file = fopen("cowboy_girl_1024X1280_yuv420p_i420.yuv", "rb");
    if (!input_file) {
        printf("Error opening input file.\n");
        return 1;
    }

    int width = 1024;
    int height = 1280;
    size_t uv_size = (width * height) / 2;

    uint8_t *yuv_data = (uint8_t *)malloc(width * height * 3 / 2);
    if (!yuv_data) {
        printf("Memory allocation error.\n");
        fclose(input_file);
        return 1;
    }

    fread(yuv_data, sizeof(uint8_t), width * height * 3 / 2, input_file);
    fclose(input_file);

    // Convert YUV to RGB24
    uint8_t *rgb_data = (uint8_t *)malloc(width * height * 3);
    if (!rgb_data) {
        printf("Memory allocation error.\n");
        free(yuv_data);
        return 1;
    }

    libyuv::I420ToRGB24(yuv_data, width, yuv_data + width * height, width / 2,
                        yuv_data + width * height * 5 / 4, width / 2,
                        rgb_data, width * 3, width, height);
/*
    libyuv::I420ToRAW(yuv_data, width, yuv_data + width * height, width / 2,
                        yuv_data + width * height * 5 / 4, width / 2,
                        rgb_data, width * 3, width, height);
*/
    // Save RGB image to file
    FILE *output_file = fopen("output.rgb", "wb");
    if (!output_file) {
        printf("Error opening output file.\n");
        free(yuv_data);
        free(rgb_data);
        return 1;
    }

    fwrite(rgb_data, sizeof(uint8_t), width * height * 3, output_file);
    fclose(output_file);

    free(yuv_data);
    free(rgb_data);

    printf("Conversion complete.\n");

    return 0;
}

四、测试运行结果

复制代码
g++ -o convert_yuv_to_rgb convert_yuv_to_rgb.cpp -lyuv
./convert_yuv_to_rgb

五、上面的测试得出的yuv文件显示出来的效果有点异常,R和B对换了,为啥呢?这个问题困扰了我许久。直到我看到我看到libyuv/include/libyuv/convert.h里面有这一段才豁然开朗,因为RGB24ToI420也是存在这个问题,解决方法是使用I420ToRAW、RAWToI420对换。

复制代码
// RGB little endian (bgr in memory) to I420.
LIBYUV_API
int RGB24ToI420(const uint8_t* src_rgb24,
                int src_stride_rgb24,
                uint8_t* dst_y,
                int dst_stride_y,
                uint8_t* dst_u,
                int dst_stride_u,
                uint8_t* dst_v,
                int dst_stride_v,
                int width,
                int height);

六、如果运行的时候提示找不到libyuv.so库,按照下面的方法运行sudo ldconfig更新动态链接库缓存。也可以直接用gcc -o yuv yuv.c /usr/local/lib/libyuv.so这种编译形式。

复制代码
编辑配置文件并使新安装的库生效:
sudo vi /etc/ld.so.conf
在末尾加入如下行:
include /usr/local/lib

sudo ldconfig
相关推荐
ai小陈7 小时前
GPU服务器租用存储验收:检查点写入与磁盘吞吐实战
运维·服务器·人工智能·ai·ssh·gpu算力
Ivanqhz8 小时前
激活函数在 Transformer 中的作用及各种变体简述
java·linux·数据库·人工智能·深度学习
有毒的教程9 小时前
VMware仅主机模式:物理机 ↔ 虚拟机 文件共享
运维
殷色玫瑰11 小时前
C/C++ 内存管理详解:从内存分布到 new/delete 底层原理
java·linux·c语言·c++
山岚的运维笔记11 小时前
ComfyUI NVIDIA安装教程:官方便携版下载+run_nvidia_gpu.bat启动,8G显存Windows实操
运维·服务器·windows·笔记·prompt·aigc·comfyui
海宇大数据12 小时前
零信任架构实战:基于海宇活体识别V步骤1构建自动化远程公证会话初始化网关
运维·人工智能·架构·自动化
꯭自꯭闭꯭12 小时前
DM7主备升级方案
linux·服务器·数据库
用户41071920132512 小时前
VMware 虚拟机Ubuntu 环境linux远程连接失败
linux
lisanmengmeng12 小时前
Nagios邮件报警的配置
linux·运维·服务器
Ruiery13 小时前
Linux 6.6内核 CPU 深度解析(六):cpufreq
linux·运维·服务器