yuv格式转为IplImage保存为图片怎么感觉色彩有问题

小村长 2014-03-26 09:22:52
左图为我所使用的yuv格式文件,我用以下代码提取得到每帧图像(右图),怎么发现色彩"偏白了", 坐等大神解答,谢谢


代码:
#include <iostream>
#include <highgui.h>
#include <cv.h>
#include <fstream>
#include <sstream>

using namespace std;
using namespace cv;

#define FCount 10
#define ISizeX 352
#define ISizeY 288

unsigned char Y[FCount][ISizeY][ISizeX];
unsigned char buf[FCount][ISizeX*ISizeY+ISizeX/2*ISizeY/2+ISizeX/2*ISizeY/2+1];


// 将图片文件写入
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);
cvSetData(yimg,Y[nframes],ISizeX);
cvSetData(uimg,buf[nframes] + ISizeX*ISizeY, ISizeX/2);
cvSetData(vimg,buf[nframes] + long(ISizeX*ISizeY*1.25), ISizeX/2);


cvResize(uimg,uuimg, CV_INTER_LINEAR);
cvResize(vimg,vvimg, CV_INTER_LINEAR);
cvMerge(yimg,uuimg,vvimg,NULL,image); // 合并单通道为三通道
cvCvtColor(image,rgbimg,CV_YCrCb2RGB);

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");
}


int main()
{
FileWriteFrames();
return 0;
}


...全文
788 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
loveweifeiyun 2016-04-22
  • 打赏
  • 举报
回复
请问您是怎么解决的,能给个文章链接地址码
小村长 2014-04-02
  • 打赏
  • 举报
回复
虽然大家没有帮上什么忙,但是问题已解决,详细可以见我的blog<过几天贴上>。。。http://blog.csdn.net/lu597203933
小村长 2014-03-29
  • 打赏
  • 举报
回复
[quote=引用 15 楼 qiminixi 的回复:] 直接扔到surface上,然后用RGB格式拷出来 不明白,怎么扔?
小村长 2014-03-29
  • 打赏
  • 举报
回复
引用 14 楼 zhao4zhong1 的回复:
严重怀疑楼主能真的在RGB显示屏上显示YUV格式图片。
是啊 菜鸟一个 没办法~~
小村长 2014-03-28
  • 打赏
  • 举报
回复
是的,另外别听直接保存YUV的图片了,没有图片使用YUV存储的。我表示对此事无语。[/quote] 这样的话,编起来还是得耗些时间的,出错概率也是很大啊~~
__cc__ 2014-03-28
  • 打赏
  • 举报
回复
引用 8 楼 Lu597203933 的回复:
[quote=引用 7 楼 neustar1 的回复:] [quote=引用 5 楼 Lu597203933 的回复:] [quote=引用 4 楼 neustar1 的回复:] [quote=引用 楼主 Lu597203933 的回复:] cvCvtColor(image,rgbimg,CV_YCrCb2RGB); [/code]
问题在这里,YCrCb颜色空间不对,左边应该是BT.709,但是Opencv转的时候用的是BT.601转,所以结果不对。[/quote]请问这个怎么修改呢?着实对这个视频标准不太懂[/quote] 参考公式: [/quote]你的意思是我不能用CvtColor(image,rgbimg,CV_YCrCb2RGB);进行转换,得换成你所对应的公式吗?[/quote] 是的,另外别听直接保存YUV的图片了,没有图片使用YUV存储的。我表示对此事无语。
qiminixi 2014-03-28
  • 打赏
  • 举报
回复
直接扔到surface上,然后用RGB格式拷出来 我怎么觉得右边的图像反倒自然些
赵4老师 2014-03-28
  • 打赏
  • 举报
回复
严重怀疑楼主能真的在RGB显示屏上显示YUV格式图片。
__cc__ 2014-03-28
  • 打赏
  • 举报
回复
引用 12 楼 Lu597203933 的回复:
是的,另外别听直接保存YUV的图片了,没有图片使用YUV存储的。我表示对此事无语。
这样的话,编起来还是得耗些时间的,出错概率也是很大啊~~[/quote] 你不会验证一下我说的对不对啊,对的话,再好好实现这段代码呗。
__cc__ 2014-03-27
  • 打赏
  • 举报
回复
引用 楼主 Lu597203933 的回复:
cvCvtColor(image,rgbimg,CV_YCrCb2RGB); [/code]
问题在这里,YCrCb颜色空间不对,左边应该是BT.701,但是Opencv转的时候用的是BT.609转,所以结果不对。
图灵狗 2014-03-27
  • 打赏
  • 举报
回复
看起来像是颜色转换后的精度损失,你不转RGB直接存YUV的JPEG图片看看。
引用 楼主 Lu597203933 的回复:
左图为我所使用的yuv格式文件,我用以下代码提取得到每帧图像(右图),怎么发现色彩"偏白了", 坐等大神解答,谢谢 代码:
#include <iostream>
#include <highgui.h>
#include <cv.h>
#include <fstream>
#include <sstream>

using namespace std;
using namespace cv;

#define FCount 10
#define ISizeX 352
#define ISizeY 288

unsigned char Y[FCount][ISizeY][ISizeX];   
unsigned char buf[FCount][ISizeX*ISizeY+ISizeX/2*ISizeY/2+ISizeX/2*ISizeY/2+1];	


// 将图片文件写入
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);
		cvSetData(yimg,Y[nframes],ISizeX);
		cvSetData(uimg,buf[nframes] + ISizeX*ISizeY, ISizeX/2);
		cvSetData(vimg,buf[nframes] + long(ISizeX*ISizeY*1.25), ISizeX/2);

		
		cvResize(uimg,uuimg, CV_INTER_LINEAR);
		cvResize(vimg,vvimg, CV_INTER_LINEAR);
		cvMerge(yimg,uuimg,vvimg,NULL,image);   // 合并单通道为三通道
		cvCvtColor(image,rgbimg,CV_YCrCb2RGB);    
		
		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");	
}


int main()
{
	FileWriteFrames();
	return 0;
}


小村长 2014-03-27
  • 打赏
  • 举报
回复
引用 9 楼 turingo 的回复:
cvSaveImage(nframesstr,rgbimg);保存没有转成RGB的image啊。
[/code]
[/quote]请问如何存?[/quote][/quote] 变成这样了
图灵狗 2014-03-27
  • 打赏
  • 举报
回复
cvSaveImage(nframesstr,rgbimg);保存没有转成RGB的image啊。
引用 6 楼 Lu597203933 的回复:
[quote=引用 3 楼 turingo 的回复:] 看起来像是颜色转换后的精度损失,你不转RGB直接存YUV的JPEG图片看看。 [quote=引用 楼主 Lu597203933 的回复:] 左图为我所使用的yuv格式文件,我用以下代码提取得到每帧图像(右图),怎么发现色彩"偏白了", 坐等大神解答,谢谢 代码:
#include <iostream>
#include <highgui.h>
#include <cv.h>
#include <fstream>
#include <sstream>

using namespace std;
using namespace cv;

#define FCount 10
#define ISizeX 352
#define ISizeY 288

unsigned char Y[FCount][ISizeY][ISizeX];   
unsigned char buf[FCount][ISizeX*ISizeY+ISizeX/2*ISizeY/2+ISizeX/2*ISizeY/2+1];	


// 将图片文件写入
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);
		cvSetData(yimg,Y[nframes],ISizeX);
		cvSetData(uimg,buf[nframes] + ISizeX*ISizeY, ISizeX/2);
		cvSetData(vimg,buf[nframes] + long(ISizeX*ISizeY*1.25), ISizeX/2);

		
		cvResize(uimg,uuimg, CV_INTER_LINEAR);
		cvResize(vimg,vvimg, CV_INTER_LINEAR);
		cvMerge(yimg,uuimg,vvimg,NULL,image);   // 合并单通道为三通道
		cvCvtColor(image,rgbimg,CV_YCrCb2RGB);    
		
		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");	
}


int main()
{
	FileWriteFrames();
	return 0;
}


[/quote]请问如何存?[/quote]
小村长 2014-03-27
  • 打赏
  • 举报
回复
引用 7 楼 neustar1 的回复:
[quote=引用 5 楼 Lu597203933 的回复:] [quote=引用 4 楼 neustar1 的回复:] [quote=引用 楼主 Lu597203933 的回复:] cvCvtColor(image,rgbimg,CV_YCrCb2RGB); [/code]
问题在这里,YCrCb颜色空间不对,左边应该是BT.709,但是Opencv转的时候用的是BT.601转,所以结果不对。[/quote]请问这个怎么修改呢?着实对这个视频标准不太懂[/quote] 参考公式: [/quote]你的意思是我不能用CvtColor(image,rgbimg,CV_YCrCb2RGB);进行转换,得换成你所对应的公式吗?
__cc__ 2014-03-27
  • 打赏
  • 举报
回复
引用 5 楼 Lu597203933 的回复:
[quote=引用 4 楼 neustar1 的回复:]
[quote=引用 楼主 Lu597203933 的回复:]
cvCvtColor(image,rgbimg,CV_YCrCb2RGB);
[/code]

问题在这里,YCrCb颜色空间不对,左边应该是BT.709,但是Opencv转的时候用的是BT.601转,所以结果不对。[/quote]请问这个怎么修改呢?着实对这个视频标准不太懂[/quote]
参考公式:
小村长 2014-03-27
  • 打赏
  • 举报
回复
引用 3 楼 turingo 的回复:
看起来像是颜色转换后的精度损失,你不转RGB直接存YUV的JPEG图片看看。 [quote=引用 楼主 Lu597203933 的回复:] 左图为我所使用的yuv格式文件,我用以下代码提取得到每帧图像(右图),怎么发现色彩"偏白了", 坐等大神解答,谢谢 代码:
#include <iostream>
#include <highgui.h>
#include <cv.h>
#include <fstream>
#include <sstream>

using namespace std;
using namespace cv;

#define FCount 10
#define ISizeX 352
#define ISizeY 288

unsigned char Y[FCount][ISizeY][ISizeX];   
unsigned char buf[FCount][ISizeX*ISizeY+ISizeX/2*ISizeY/2+ISizeX/2*ISizeY/2+1];	


// 将图片文件写入
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);
		cvSetData(yimg,Y[nframes],ISizeX);
		cvSetData(uimg,buf[nframes] + ISizeX*ISizeY, ISizeX/2);
		cvSetData(vimg,buf[nframes] + long(ISizeX*ISizeY*1.25), ISizeX/2);

		
		cvResize(uimg,uuimg, CV_INTER_LINEAR);
		cvResize(vimg,vvimg, CV_INTER_LINEAR);
		cvMerge(yimg,uuimg,vvimg,NULL,image);   // 合并单通道为三通道
		cvCvtColor(image,rgbimg,CV_YCrCb2RGB);    
		
		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");	
}


int main()
{
	FileWriteFrames();
	return 0;
}


[/quote]请问如何存?
小村长 2014-03-27
  • 打赏
  • 举报
回复
引用 4 楼 neustar1 的回复:
[quote=引用 楼主 Lu597203933 的回复:] cvCvtColor(image,rgbimg,CV_YCrCb2RGB); [/code]
问题在这里,YCrCb颜色空间不对,左边应该是BT.701,但是Opencv转的时候用的是BT.609转,所以结果不对。[/quote]请问这个怎么修改呢?着实对这个视频标准不太懂
小村长 2014-03-26
  • 打赏
  • 举报
回复
引用 1 楼 hzt19901012 的回复:
 cvShowImage("yuv", rgbimg);
不是YUV格式的吗,是否采用了RGB格式显示?没用过C++处理图像,只玩过Matlab....
是的,就是先转换为RGB格式,貌似出现了错误
Guy_Fwakes 2014-03-26
  • 打赏
  • 举报
回复
 cvShowImage("yuv", rgbimg);
不是YUV格式的吗,是否采用了RGB格式显示?没用过C++处理图像,只玩过Matlab....

3,882

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 其它技术问题
社区管理员
  • 其它技术问题社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧