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


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

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

    1. git clone https://github.com/lemenkov/libyuv.git
    2. cd libyuv
    3. mkdir build && cd build
    4. cmake ..
    5. make
    6. sudo make install

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

    1. #include <stdio.h>
    2. #include <stdlib.h>
    3. #include "libyuv/convert_from.h"
    4. #include "libyuv/convert.h"
    5. int main() {
    6. FILE *input_file = fopen("cowboy_girl_1024X1280_yuv420p_i420.yuv", "rb");
    7. if (!input_file) {
    8. printf("Error opening input file.\n");
    9. return 1;
    10. }
    11. int width = 1024;
    12. int height = 1280;
    13. size_t uv_size = (width * height) / 2;
    14. uint8_t *yuv_data = (uint8_t *)malloc(width * height * 3 / 2);
    15. if (!yuv_data) {
    16. printf("Memory allocation error.\n");
    17. fclose(input_file);
    18. return 1;
    19. }
    20. fread(yuv_data, sizeof(uint8_t), width * height * 3 / 2, input_file);
    21. fclose(input_file);
    22. // Convert YUV to RGB24
    23. uint8_t *rgb_data = (uint8_t *)malloc(width * height * 3);
    24. if (!rgb_data) {
    25. printf("Memory allocation error.\n");
    26. free(yuv_data);
    27. return 1;
    28. }
    29. libyuv::I420ToRGB24(yuv_data, width, yuv_data + width * height, width / 2,
    30. yuv_data + width * height * 5 / 4, width / 2,
    31. rgb_data, width * 3, width, height);
    32. /*
    33. libyuv::I420ToRAW(yuv_data, width, yuv_data + width * height, width / 2,
    34. yuv_data + width * height * 5 / 4, width / 2,
    35. rgb_data, width * 3, width, height);
    36. */
    37. // Save RGB image to file
    38. FILE *output_file = fopen("output.rgb", "wb");
    39. if (!output_file) {
    40. printf("Error opening output file.\n");
    41. free(yuv_data);
    42. free(rgb_data);
    43. return 1;
    44. }
    45. fwrite(rgb_data, sizeof(uint8_t), width * height * 3, output_file);
    46. fclose(output_file);
    47. free(yuv_data);
    48. free(rgb_data);
    49. printf("Conversion complete.\n");
    50. return 0;
    51. }

    四、测试运行结果

    1. g++ -o convert_yuv_to_rgb convert_yuv_to_rgb.cpp -lyuv
    2. ./convert_yuv_to_rgb

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

    1. // RGB little endian (bgr in memory) to I420.
    2. LIBYUV_API
    3. int RGB24ToI420(const uint8_t* src_rgb24,
    4. int src_stride_rgb24,
    5. uint8_t* dst_y,
    6. int dst_stride_y,
    7. uint8_t* dst_u,
    8. int dst_stride_u,
    9. uint8_t* dst_v,
    10. int dst_stride_v,
    11. int width,
    12. int height);

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

    1. 编辑配置文件并使新安装的库生效:
    2. sudo vi /etc/ld.so.conf
    3. 在末尾加入如下行:
    4. include /usr/local/lib
    5. sudo ldconfig

  • 相关阅读:
    typescript46-函数之间的类型兼容性
    12uec++多人游戏【自定义碰撞通道+头部暴击+连续开火】
    【光电工程实训】几何光学 小孔成像 光的反射 光的折射 透镜成像
    力扣刷题day47|392判断子序列、115不同的子序列
    WebGPU 中的缓冲映射机制
    Vue3 学习笔记
    前端面试知识整理:vue的钩子函数
    U盘格式化后 容量变小如何解决
    动手学深度学习(Pytorch版)代码实践 -卷积神经网络-15参数管理
    react下自定义Table
  • 原文地址:https://blog.csdn.net/qq_37858386/article/details/138653421