yuv422数据[打包格式YUYV]转opencv的Mat格式

最近遇到一个问题,现在从摄像机取出的图片是yuv[4:2:2]格式的,我需要把它转化为opencv中的mat格式,发现用opencv的cvtColor()函数进行转化时cpu消耗很大,为了减小cpu占用,需要改用公式法来将yuv422格式转化为mat。

查阅很多资料,在yuv422转mat格式的时候,需要注意yuv422的两种打包格式:YUYV和UYVY。

我这里来源数据YUV打包格式是YUYV,但是我找的公式代码好像是UYVY的,于是乎查看存储图片整体是有的,但是颜色只有粉色和绿色,这个代码如下:

void yuv422_to_mat(const unsigned char* yuv422_data, int width, int height, cv::Mat& mat) {
    mat.create(height, width, CV_8UC3);
    int yuv_index = 0;
    for (int y = 0; y < height; y++) {
        for (int x = 0; x < width; x += 2) {
            int u = yuv422_data[yuv_index++];
            int y1 = yuv422_data[yuv_index++];
            int v = yuv422_data[yuv_index++];
            int y2 = yuv422_data[yuv_index++];

            int r1 = y1 + 1.402 * (v - 128);
            int g1 = y1 - 0.34414 * (u - 128) - 0.71414 * (v - 128);
            int b1 = y1 + 1.772 * (u - 128);

            int r2 = y2 + 1.402 * (v - 128);
            int g2 = y2 - 0.34414 * (u - 128) - 0.71414 * (v - 128);
            int b2 = y2 + 1.772 * (u - 128);

            mat.at<cv::Vec3b>(y, x)[0] = cv::saturate_cast<unsigned char>(b1);
            mat.at<cv::Vec3b>(y, x)[1] = cv::saturate_cast<unsigned char>(g1);
            mat.at<cv::Vec3b>(y, x)[2] = cv::saturate_cast<unsigned char>(r1);

            mat.at<cv::Vec3b>(y, x + 1)[0] = cv::saturate_cast<unsigned char>(b2);
            mat.at<cv::Vec3b>(y, x + 1)[1] = cv::saturate_cast<unsigned char>(g2);
            mat.at<cv::Vec3b>(y, x + 1)[2] = cv::saturate_cast<unsigned char>(r2);
        }
    }
}

发现这个图片不对劲后,我又继续开始找代码,以下代码可以正确的将yuv422数据[打包格式YUVY]转化为opencv的mat格式:

void yuyv422_to_mat(const unsigned char* yuyv_data, int width, int height, cv::Mat& mat) {
    mat.create(height, width, CV_8UC3);
    int yuyv_index = 0;
    for (int y = 0; y < height; y++) {
        for (int x = 0; x < width; x += 2) {
            int y1 = yuyv_data[yuyv_index++];
            int u = yuyv_data[yuyv_index++];
            int y2 = yuyv_data[yuyv_index++];
            int v = yuyv_data[yuyv_index++];

            int r1 = y1 + 1.13983 * (v - 128);
            int g1 = y1 - 0.39465 * (u - 128) - 0.58060 * (v - 128);
            int b1 = y1 + 2.03211 * (u - 128);

            int r2 = y2 + 1.13983 * (v - 128);
            int g2 = y2 - 0.39465 * (u - 128) - 0.58060 * (v - 128);
            int b2 = y2 + 2.03211 * (u - 128);

            mat.at<cv::Vec3b>(y, x)[0] = cv::saturate_cast<unsigned char>(b1);
            mat.at<cv::Vec3b>(y, x)[1] = cv::saturate_cast<unsigned char>(g1);
            mat.at<cv::Vec3b>(y, x)[2] = cv::saturate_cast<unsigned char>(r1);

            mat.at<cv::Vec3b>(y, x + 1)[0] = cv::saturate_cast<unsigned char>(b2);
            mat.at<cv::Vec3b>(y, x + 1)[1] = cv::saturate_cast<unsigned char>(g2);
            mat.at<cv::Vec3b>(y, x + 1)[2] = cv::saturate_cast<unsigned char>(r2);
        }
    }
}
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值