YUV格式转换RGB(基于opencv)
在编写代码将需要处理YUV格从每个视频帧中提取,然后将其保存为图片。有两种常见的方法在线,第一种是通过opencv自带cvCvtColor,可是这样的方法有bug。得到的图片会泛白。另外一种方法是公式法。
法一:opencv自带cvCvtColor
说明:这样的方法会出现图片“泛白”。详细原因网上是说cvCvtColor这个函数左右协议不同,不太懂。
代码:
void FileWriteFrames(){
char *filename = "E:\\openCV\\zhang\\yuvSource\\football_cif.yuv";
ifstream readMe(filename, ios::in | ios::binary); // 打开并读yuv数据
IplImage *image, *rgbimg, *yimg, *uimg, *vimg, *uuimg, *vvimg;
cvNamedWindow("yuv",CV_WINDOW_AUTOSIZE);
rgbimg = cvCreateImage(cvSize(ISizeX, ISizeY), IPL_DEPTH_8U, 3);
image = cvCreateImage(cvSize(ISizeX, ISizeY), IPL_DEPTH_8U, 3);
yimg = cvCreateImageHeader(cvSize(ISizeX, ISizeY), IPL_DEPTH_8U, 1); // 亮度分量
uimg = cvCreateImageHeader(cvSize(ISizeX/2, ISizeY/2), IPL_DEPTH_8U, 1); // 这两个都是色度分量
vimg = cvCreateImageHeader(cvSize(ISizeX/2, ISizeY/2), IPL_DEPTH_8U, 1);
uuimg = cvCreateImage(cvSize(ISizeX, ISizeY), IPL_DEPTH_8U, 1);
vvimg = cvCreateImage(cvSize(ISizeX, ISizeY), IPL_DEPTH_8U, 1);
int nframes;
for(nframes = 0; nframes < FCount; nframes ++){
char nframesstr[20];
readMe.read((char*)Y[nframes],ISizeX*ISizeY);
//readMe.seekg(-ISizeX*ISizeY, ios::cur);
//readMe.read((char*)buf[nframes],ISizeX*ISizeY+ISizeX/2*ISizeY/2+ISizeX/2*ISizeY/2);
readMe.read((char*)buf[nframes],ISizeX/2*ISizeY/2);
readMe.read((char*)buf2[nframes],ISizeX/2*ISizeY/2);
cvSetData(yimg,Y[nframes],ISizeX);
//cvSetData(uimg,buf[nframes] + ISizeX*ISizeY, ISizeX/2);
cvSetData(uimg,buf[nframes], ISizeX/2);
cvSetData(vimg,buf2[nframes], ISizeX/2);
cvResize(uimg,uuimg, CV_INTER_LINEAR);
cvResize(vimg,vvimg, CV_INTER_LINEAR);
cvMerge(yimg,uuimg,vvimg,NULL,image); // 合并单通道为三通道
cvCvtColor(image,rgbimg,CV_YUV2BGR);
stringstream ss; // 类型转换统一转换为char* 类型
ss << nframes;
ss << ".jpg" ;
ss >> nframesstr;
cvShowImage("yuv", rgbimg);
cvSaveImage(nframesstr,rgbimg);
int c = cvWaitKey(30);
if((char)c == 27)
{
break;
}
}
readMe.close();
cvReleaseImage(&uuimg);
cvReleaseImage(&vvimg);
cvReleaseImageHeader(&yimg);
cvReleaseImageHeader(&uimg);
cvReleaseImageHeader(&vimg);
cvReleaseImage(&image);
cvDestroyWindow("yuv");
}
法二:公式法
代码:
bool YUV420_To_BGR24(unsigned char *puc_y, unsigned char *puc_u, unsigned char *puc_v, unsigned char *puc_rgb, int width_y, int height_y)
{
if (!puc_y || !puc_u || !puc_v || !puc_rgb)
{
return false;
} //初始化变量
int baseSize = width_y * height_y;
int rgbSize = baseSize * 3; BYTE* rgbData = new BYTE[rgbSize];
memset(rgbData, 0, rgbSize); /* 变量声明 */
int temp = 0; BYTE* rData = rgbData; //r分量地址
BYTE* gData = rgbData + baseSize; //g分量地址
BYTE* bData = gData + baseSize; //b分量地址 int uvIndex =0, yIndex =0; //YUV->RGB 的转换矩阵
//double Yuv2Rgb[3][3] = {1, 0, 1.4022,
// 1, -0.3456, -0.7145,
// 1, 1.771, 0}; for(int y=0; y < height_y; y++)
{
for(int x=0; x < width_y; x++)
{
uvIndex = (y>>1) * (width_y>>1) + (x>>1);
yIndex = y * width_y + x; /* r分量 */
temp = (int)(puc_y[yIndex] + (puc_v[uvIndex] - 128) * 1.4022);
rData[yIndex] = temp<0 ? 0 : (temp > 255 ? 255 : temp); /* g分量 */
temp = (int)(puc_y[yIndex] + (puc_u[uvIndex] - 128) * (-0.3456) +
(puc_v[uvIndex] - 128) * (-0.7145));
gData[yIndex] = temp < 0 ? 0 : (temp > 255 ? 255 : temp); /* b分量 */
temp = (int)(puc_y[yIndex] + (puc_u[uvIndex] - 128) * 1.771);
bData[yIndex] = temp < 0 ? 0 : (temp > 255 ? 255 : temp);
}
} //将R,G,B三个分量赋给img_data
int widthStep = width_y*3;
for (int y = 0; y < height_y; y++)
{
for (int x = 0; x < width_y; x++)
{
puc_rgb[y * widthStep + x * 3 + 2] = rData[y * width_y + x]; //R
puc_rgb[y * widthStep + x * 3 + 1] = gData[y * width_y + x]; //G
puc_rgb[y * widthStep + x * 3 + 0] = bData[y * width_y + x]; //B
}
} if (!puc_rgb)
{
return false;
}
delete [] rgbData;
return true;
} IplImage* YUV420_To_IplImage(unsigned char* pYUV420, int width, int height)
{
if (!pYUV420)
{
return NULL;
} //初始化变量
int baseSize = width*height;
int imgSize = baseSize*3;
BYTE* pRGB24 = new BYTE[imgSize];
memset(pRGB24, 0, imgSize); /* 变量声明 */
int temp = 0; BYTE* yData = pYUV420; //y分量地址
BYTE* uData = pYUV420 + baseSize; //u分量地址
BYTE* vData = uData + (baseSize>>2); //v分量地址 if(YUV420_To_BGR24(yData, uData, vData, pRGB24, width, height) == false || !pRGB24)
{
return NULL;
} IplImage *image = cvCreateImage(cvSize(width, height), 8,3);
memcpy(image->imageData, pRGB24, imgSize); if (!image)
{
return NULL;
} delete [] pRGB24;
return image;
} void FileWriteFrames(){
char *filename = "E:\\openCV\\zhang\\yuvSource\\FOOTBALL_352x288_30_orig_01.yuv";
ifstream readMe(filename, ios::in | ios::binary); // 打开并读yuv数据
int nframes;
for(nframes = 0; nframes < FCount; nframes ++){
char nframesstr[20];
readMe.read((char*)Y[nframes],ISizeX*ISizeY);
readMe.seekg(-ISizeX*ISizeY, ios::cur);
readMe.read((char*)buf[nframes],ISizeX*ISizeY+ISizeX/2*ISizeY/2+ISizeX/2*ISizeY/2);
IplImage *rgbimg = YUV420_To_IplImage(buf[nframes], ISizeX, ISizeY);
stringstream ss; // 类型转换统一转换为char* 类型
ss << nframes;
ss << ".jpg" ;
ss >> nframesstr;
cvShowImage("yuv", rgbimg);
cvSaveImage(nframesstr,rgbimg);
int c = cvWaitKey(30);
if((char)c == 27)
{
break;
}
}
readMe.close();
}
完整代码见:http://download.csdn.net/detail/lu597203933/7362687
參见blog:http://blog.csdn.net/dreamd1987/article/details/7259479#
版权声明:本文博客原创文章,博客,未经同意,不得转载。
YUV格式转换RGB(基于opencv)的更多相关文章
- Android 音视频编解码——RGB与YUV格式转换
一.RGB模型与YUV模型 1.RGB模型 我们知道物理三基色分别是红(Red).绿(Green).蓝(Blue).现代的显示器技术就是通过组合不同强度的红绿蓝三原色,来达成几乎任何一种可见光的颜色. ...
- 音视频编解码——RGB与YUV格式转换
一.RGB模型与YUV模型 1.RGB模型 我们知道物理三基色分别是红(Red).绿(Green).蓝(Blue).现代的显示器技术就是通过组合不同强度的红绿蓝三原色,来达成几乎任何一种可见光的颜色. ...
- YUV格式与RGB格式
YUV420介绍: YUV420格式是指,每个像素都保留一个Y(亮度)分量,而在水平方向上,不是每行都取U和V分量,而是一行只取U分量,则其接着一行就只取V分量,以此重复(即4:2:0, 4:0:2, ...
- 非交织YUV格式转换
本文为自己写的从非交织yuv420转换出yuv444,yuv422h,yuv422v和手动裁剪422h,422v图片的代码 #include <fcntl.h> #include < ...
- 【视频处理】YUV与RGB格式转换
YUV格式具有亮度信息和色彩信息分离的特点,但大多数图像处理操作都是基于RGB格式. 因此当要对图像进行后期处理显示时,需要把YUV格式转换成RGB格式. RGB与YUV的变换公式如下: YUV(25 ...
- YUV与RGB格式转换
YUV格式具有亮度信息和色彩信息分离的特点,但大多数图像处理操作都是基于RGB格式. 因此当要对图像进行后期处理显示时,需要把YUV格式转换成RGB格式. RGB与YUV的变换公式如下: YUV(25 ...
- 【图像处理与医学图像处理】YUV与RGB格式转换速度几种方法对比
[视频处理]YUV与RGB格式转换 YUV格式具有亮度信息和色彩信息分离的特点,但大多数图像处理操作都是基于RGB格式. 因此当要对图像进行后期处理显示时,需要把YUV格式转换成RGB格式. RGB与 ...
- 【DSP开发】【VS开发】YUV与RGB格式转换
[视频处理]YUV与RGB格式转换 YUV格式具有亮度信息和色彩信息分离的特点,但大多数图像处理操作都是基于RGB格式. 因此当要对图像进行后期处理显示时,需要把YUV格式转换成RGB格式. RGB与 ...
- YUV格式分析
转自:http://www.cnblogs.com/armlinux/archive/2012/02/15/2396763.html Andrew Huang <bluedrum@163.com ...
随机推荐
- 数据结构(C达到)------- 双链表
双链表中的每个节点包含两个指针域,指针域包含其后继节点的内存地址,还有一个指针所存储的存储器地址其领域前驱节点. 双向链表结点的类型描写叙述: //双向链表的类型描写叙述 typedef int El ...
- matlab练习程序(PCA<SVD>)
clear all;close all;clc;img1=imread('Corner.png');img2=imread('Corner1.png');img3=imread('Corner2.pn ...
- (大数据工程师学习路径)第三步 Git Community Book----中级技能(下)
一.追踪分支 1.追踪分支 在Git中‘追踪分支’是用于联系本地分支和远程分支的. 如果你在’追踪分支'(Tracking Branches)上执行推送(push)或拉取(pull)时,它会自动推送( ...
- a^b%c 的三种形式
求a^b%c,(1 <= a,b <= 2^62, 1 <= c <= 10^9) 最主要的高速幂 _LL mod_exp(_LL a, _LL b, int c) { _L ...
- angularjs从零开始(一)
简介 AngularJS是为了克服HTML在构建应用上的不足而设计的.HTML是一门很好的为静态文本展示设计的声明式语言,但要构建WEB应用的话它就显得乏力了.所以我做了一些工作(你也可以觉得是小 ...
- 乘法逆元...Orz
最近打的几场比赛,都出现了有关逆元的题目,今天就整理了一下... 求乘法逆元的几种方法:http://www.cnblogs.com/james47/p/3871782.html 博文转载链接:htt ...
- iOS ... NS_REQUIRES_NIL_TERMINATION
看到官方的一个样例不错,这里留记. #import <Cocoa/Cocoa.h> @interface NSMutableArray (variadicMethodExample) - ...
- 毕业后的第二份工作:进入国外 在新加坡工作 每月一次18K
--訪传智播客成都校区12.26就业班学员 杨洋 姓名:杨洋 毕业院校:重庆科技学院 专业:电子信息技术与project 就职公司:新电科技 岗位:Javaproject师 月薪:18K 上午.他刚去 ...
- printf 对齐
printf关于对其的问题(参考有关博客加上自己的一些总结) 1.关于左对齐或右对齐问题, 默认的如果%后没有“-”是右对齐的,如果%后跟“0”,不足的个数用0来填充, 例如:printf(&qu ...
- mysql_常用命令
1: 以指定编码创建数据库 CREATE DATABASE `search_data` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci