使用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 @ 2022-11-09 23:10  dangxusheng  阅读(1182)  评论(0编辑  收藏  举报