OpenCV中BGR转NV12

1.opencv代码jpg转换yuv420sp(nv12)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#include <stdio.h>
#include <opencv2/opencv.hpp>
 
int main(int argc, char **argv)
{
    // 检查输入参数
    if(argc != 2){
        std::cout << "Usage: img2yuv <image_path>" << std::endl;
        return -1;
    }
 
    // 读取输入图像
    cv::Mat image = cv::imread(argv[1]);
    int image_h = image.rows;
    int image_w = image.cols;
    int image_c = image.channels();
    cv::imshow("image", image);
    cv::waitKey();
 
    // 转换到I420
    cv::Mat I420;                                      // I420格式图像
    cv::cvtColor(image, I420, cv::COLOR_BGR2YUV_I420); // 转换I420格式
 
    uint8_t *pI420 = I420.ptr<uint8_t>();              // I420数据指针
    int32_t I420_y_s = image_h * image_w;              // I420中 Y长度
    int I420_uv_h = image_h / 2;                       // I420中UV高度
    int I420_uv_w = image_w / 2;                       // I420中UV宽度
 
    // 转换到NV12
    cv::Mat NV12 = cv::Mat(image_h * 3 / 2, image_w, CV_8UC1); // NV12格式图像
    uint8_t *pNV12 = NV12.ptr<uint8_t>();                      // NV12数据指针
    memcpy(pNV12, pI420, I420_y_s); // 拷贝I420中的Y数据到NV12中
 
    uint8_t *pI420_U = pI420 + I420_y_s;                // 移动I420中U分量指针到U数据头部
    uint8_t *pI420_V = pI420_U + I420_uv_h * I420_uv_w; // 移动I420中V分量指针到V数据头部
    pNV12 = pNV12 + I420_y_s;                           // 移动NV12指针到U数据头部
    for(int i = 0; i < I420_uv_h * I420_uv_w; i++){ // 遍历I420中UV分量数据,复制到NV12中
        // 把I420中U数据复制到NV12中U数据对应位置
        *pNV12 = *pI420_U;
        pNV12++;
        pI420_U++;
 
        // 把I420中V数据复制到NV12中V数据对应位置
        *pNV12 = *pI420_V;
        pNV12++;
        pI420_V++;
    }
 
    // 保存转换图像
    FILE *fp = fopen("output/result.yuv", "wb");
    int image_len = image_w * image_h * 3 / 2;
    fwrite(NV12.ptr<uint8_t>(), image_len, 1, fp);
    fclose(fp);
 
    // 读取转换图像
    fp = fopen("output/result.yuv", "rb");
    unsigned char *image_buf = new unsigned char[image_len];
    fread(image_buf, image_len, 1, fp);
    fclose(fp);
 
    // 显示转换图像
    cv::Mat image2 = cv::Mat(image_h * 3 / 2, image_w, CV_8UC1, image_buf);
    cv::cvtColor(image2, image2, cv::COLOR_YUV2BGR_NV12);
    cv::imshow("image2", image2);
    cv::waitKey();
 
    return 0;
}

 

2.ffmpeg jpg转换yuv420sp(nv12)

1
2
3
ffmpeg -i data/1_2688_1520.jpg -pix_fmt nv12 output/1_2688_1520.yuv
 
ffmpeg -y -s 2688x1520 -pix_fmt nv12 -i output/1_2688_1520.yuv output/1_2688_1520.jpg

 

参考地址:

https://blog.csdn.net/nodototao/article/details/120649916

https://www.cnblogs.com/dxscode/p/16196396.html

http://www.javashuo.com/article/p-znuvnhtl-dy.html

https://blog.csdn.net/zfjBIT/article/details/127395512

https://blog.csdn.net/u014613270/article/details/123448481

https://blog.51cto.com/u_15764210/5616675

https://www.fangwenw.com/soft/view-7624.html

https://www.jb51.cc/faq/1292067.html

https://blog.csdn.net/denghp83/article/details/37936643

https://www.cnblogs.com/chenpi/p/5128233.html

 

https://www.cnblogs.com/arthurchn/p/13489815.html

https://www.ancii.com/ay1xlqzn/

https://blog.csdn.net/smilestone_322/article/details/21104871

https://blog.csdn.net/weixin_38427663/article/details/107106092

https://blog.csdn.net/weixin_45736829/article/details/108382920

https://blog.csdn.net/laoyouji/article/details/100051158

 

 

 

posted @   盛夏夜  阅读(1488)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
点击右上角即可分享
微信分享提示