YUV422转RGB并显示于Qlabel

读取YUV422格式文件,转成Mat类型BGR格式,并显示于Qlabel控件上。

写在前面

从今天起,多看些书吧。要不,就从黄宁然看过的看起。

问题来源

anxue100:[https://bbs.csdn.net/topics/****?spm=1001.2014.3001.**77]
因“当前发帖距今超过3年,不再开放新的回复”,故新建帖子。迟到的回复。

1. 新建类

编写头文件:YUV422.h文件

#ifndef YUV422_H
#define YUV422_H

#define USE_OPENCV 1

#include 

using namespace std;
#if USE_OPENCV
    #include "opencv2/opencv.hpp"
    #include 
    using namespace cv;
#endif

// YUV文件流信息 //
#define MAX_PIC_NUM 4
#define PIC_WIDTH 640
#define PIC_HEIGHT 480

class CYUV422
{


public:
    explicit CYUV422(QWidget *parent = 0 );
    ~CYUV422();
public:
    //读取获取yuv422数据,并存放于自身buffer中//
    uint64_t get_yuv422_data(QString pth);
    //将自身buffer中的yuv422数据转换为Mat类型输出(BGR)
    Mat yuv_2_rgb(int height,int width);
private:
    //缓存buffer,用来读取存放yuv422数据//
   unsigned char yuv_buffer[MAX_PIC_NUM*PIC_WIDTH*PIC_HEIGHT*2];

};

#endif

编写cpp文件:YUV422.cpp文件

#include "YUV422.h"
#include "QDebug"

// 转换方式1:https://www.cnblogs.com/lihaiping/p/4441518.html
#define YUV_2_R(y, v)   ((int)( y + 1.402*(v-128)  ))
#define YUV_2_G(y, u, v)    ((int)( 1.0*y - 0.34414*(u-128) - 0.71414*(v-128)   ))
#define YUV_2_B(y, u)    ((int)( 1.0*y + 1.772*(u-128) ))

/*
//转换方式2:https://github.com/kd40629rtlrtl/yuv422_to_rgb
#define YUV_2_R(y, v)((int)(1.0*y + 1.370705  * (1.0*v - 128)))
#define YUV_2_G(y, u, v)((int)(1.0*y - 0.698001 * (1.0*u - 128) - 0.703125 * (1.0*v - 128)))
#define YUV_2_B(y, u) ((int)(1.0*y + 1.732446 * (1.0*u - 128)))

// 转换方式3:https://blog.csdn.net/qq_29350001/article/details/52032540
#define YUV_2_R(y, v)   ((int)( 1.164*(y-16) + 1.596*(v-128)  ))
#define YUV_2_G(y, u, v)    ((int)( 1.164*(y-16) - 0.813*(v-128) - 0.392*(u-128)   ))
#define YUV_2_B(y, u)    ((int)( 1.164*(y-16) + 2.017*(u-128) ))
*/

#define CONSTRAINT(x) {x=x>255?255:x; x= x<0?0:x;}

CYUV422::CYUV422(QWidget *parent)
{
    parent = parent;
}

CYUV422::~CYUV422()
{

}
/*
读取YUV422格式文件,模拟从设备中获取yuv422数据
*/
uint64_t CYUV422::get_yuv422_data(QString pth)
{
    uint64_t file_size = 0 ;
    FILE *fp = fopen((const char*)pth.toStdString().data(),"rb");
    if(fp!=NULL)
    {
        file_size = fread(yuv_buffer,1, sizeof(yuv_buffer),  fp);//fill in yuv_data
        fclose(fp);
    }
    return file_size;
}

/*
将读取到的yuv422数据转换为Mat类型输出(BRG)
*/
Mat CYUV422::yuv_2_rgb(int height,int width)//假定YUV数据存放格式为:yuyvyuyv
{
    Mat rgb_data =Mat(height, width, CV_8UC3 );
    int row=0,col=0;
    for(row=0;row<height;row++)
    {
        for(col=0;col<width;col++)
        {
            int yIdx = 2*(row*width+col);
            int uIdx = 4*((row*width+col)/2) + 1;
            int vIdx = uIdx+2;
            int r = YUV_2_R(yuv_buffer[yIdx], yuv_buffer[vIdx]);
            int g = YUV_2_G(yuv_buffer[yIdx],  yuv_buffer[uIdx],yuv_buffer[vIdx]);
            int b = YUV_2_B(yuv_buffer[yIdx],  yuv_buffer[uIdx]);
            CONSTRAINT(r);
            CONSTRAINT(g);
            CONSTRAINT(b);
            rgb_data.at<cv::Vec3b>(row,col) = cv::Vec3b(b,g,r);
        }
    }
    //cv::imshow("x",rgb_data);
    return rgb_data.clone();
}

2. MainWindow编写控件显示

在MainWindow的.ui文件中,添加QLabel控件,并且在.cpp中添加将Mat类型图像显示于QLabel控件的实现函数。

void MainWindow::show_mat_on_label(const cv::Mat &imgsrc, QLabel *label)
{
   cv::Mat img_temp = imgsrc.clone();
   QImage::Format format = QImage::Format_RGB888;
   if(img_temp.channels()==1)
   {
       format  = QImage::Format_Grayscale8;
   }
   if(img_temp.channels()==3)
   {
       cv::cvtColor(img_temp,img_temp,CV_BGR2RGB);//opencv 按BGR处理
   }

   if(img_temp.depth()==CV_16U)
   {
       img_temp.convertTo(img_temp,CV_8U,1.0/257.0);
   }
   QPixmap pixmap = QPixmap::fromImage(QImage(img_temp.data,img_temp.cols,img_temp.rows,(int)img_temp.step,format));
   int l_w = label->width();
   int l_h = label->height();
    QPixmap fixpixmap = pixmap.scaled(l_w,l_h,Qt::KeepAspectRatio,Qt::FastTransformation);
    label->setAlignment(Qt::AlignCenter);
    label->setPixmap(fixpixmap);
}

3. MainWindow中调用

mainwindow中,包含头文件

#include "YUV422.h"

在合适位置,添加调用:

Mat rgb_data;
CYUV422 *yuvUtils = new CYUV422(this);
//读取yuv格式文件,模拟从设备获取yuv数据流//
//该文件流信息:图像高度PIC_HEIGHT,图像宽度PIC_WIDTH,图像张数MAX_PIC_NUM,先行后列存储//
yuvUtils->get_yuv422_data("C:\\Users\\wy\\Desktop\\output_test.yuv");
//将yuv格式转换为Mat(BRG)格式//
rgb_data =yuvUtils->yuv_2_rgb(PIC_HEIGHT,PIC_WIDTH*MAX_PIC_NUM);
//显示于主窗口的Qlabel控件(这里将所有图像同时显示于一张图中)//
this->show_mat_on_label(rgb_data,this->ui->label_img);

4. 结果

读取yuv422格式文件–转为Mat–显示于QLabel控件:
YUV422转RGB并显示于Qlabel_第1张图片

你可能感兴趣的:(qt,opencv)