使用opencv进行RGB--YUV转换 c++版本

复制代码
//
// Created by DangXS on 2022/4/27.
//

#ifndef CPLUSPLUS_PROJECT1_YUV_HELPER_H
#define CPLUSPLUS_PROJECT1_YUV_HELPER_H

#include "opencv2/opencv.hpp"

static void YUVI420_to_YUV_NV12(cv::Mat &src, uchar *dst, int width, int height) {
    /*
    * src: YYYYYYYY UU VV
    * dst: YYYYYYYY UVUV
    * */
    int _size = width * height;
    uchar *src_y = src.data;
    uchar *src_u = src_y + _size;
    uchar *src_v = src_u + _size / 4;

    memcpy(dst, src_y, _size);
    for (int i = 0; i < _size / 2; i += 2) {
        dst[_size + i] = src_u[i / 2];
        dst[_size + i + 1] = src_v[i / 2];
    }
}


static void BGR2YUV420P(const cv::Mat& img, uint8_t *yuv_data, int w, int h) {
    assert(w % 2 == 0 && h % 2 == 0);
    cv::Mat yuv;
    cvtColor(img, yuv, cv::COLOR_BGR2YUV_I420); //CV_BGR2YUV_I420

    cv::Mat Y = yuv(cv::Rect(0, 0, w, h));
    cv::Mat U = yuv(cv::Rect(0, h, w / 2, h / 2));
    cv::Mat V = yuv(cv::Rect(w / 2, h, w / 2, h / 2));

    memcpy_s(yuv_data, w * h, Y.data, h * w);
    for (size_t i = 0; i < h / 2; i++)
    {
        for (size_t j = 0; j < w; j++)
        {
            int index = i * w + j;
            if (j < 2 / w) yuv_data[w*h + index] = U.data[index];
            else yuv_data[w*h + index] = V.data[index - w / 2];
        }
    }
    yuv.release();

}

int TEST_YUVI420_to_YUV_NV12() {
    printf("hello wrold");

    std::string _path = "../1.jpg";
    cv::Mat img = cv::imread(_path);
    int width = img.cols;
    int height = img.rows;
    cv::Mat _yuv420;
    cv::cvtColor(img, _yuv420, CV_BGR2YUV_I420);

    cv::imwrite("../1_yuv420.jpg", _yuv420);

    auto *ptr__yuv420sp_nv12 = new uchar[width * height * 3 / 2];
    YUVI420_to_YUV_NV12(_yuv420, ptr__yuv420sp_nv12, width, height);
    cv::Mat _yuv420sp_nv12 = _yuv420.clone();
    _yuv420sp_nv12.setTo(cv::Scalar(0));
    memcpy(_yuv420sp_nv12.data, ptr__yuv420sp_nv12, width * height * 3 / 2);
    printf("w:%d, h:%d ", _yuv420sp_nv12.cols, _yuv420sp_nv12.rows);
    cv::imwrite("../1_yuv_nv12.jpg", _yuv420sp_nv12);

    cv::Mat _gray;
    cv::cvtColor(_yuv420sp_nv12, _gray, CV_YUV2GRAY_NV12);
    cv::imwrite("../gray.jpg", _gray);

    cv::Mat _img2;
    cv::cvtColor(_yuv420sp_nv12, _img2, CV_YUV2BGR_NV12);
    cv::imwrite("../img2.jpg", _img2);

    delete[] ptr__yuv420sp_nv12;
    return 0;
}

#endif //CPLUSPLUS_PROJECT1_YUV_HELPER_H
复制代码

 

posted @   dangxusheng  阅读(1326)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
历史上的今天:
2018-11-09 mysql-8.0.13在windows上的部署
2018-11-09 爬虫 - 动态分页抓取 游民星空 的资讯 - bs4
2018-11-09 爬虫下载QQ音乐:获取所有歌手-每个歌手的专辑-每个专辑里的歌曲
2018-11-09 爬虫下载校花网美女信息-lxml
点击右上角即可分享
微信分享提示