读取YUV422格式文件,转成Mat类型BGR格式,并显示于Qlabel控件上。
从今天起,多看些书吧。要不,就从黄宁然看过的看起。
anxue100:[https://bbs.csdn.net/topics/****?spm=1001.2014.3001.**77]
因“当前发帖距今超过3年,不再开放新的回复”,故新建帖子。迟到的回复。
#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
#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();
}
在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);
}
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);