raw图的存储格式和读取方式

前言

由于在图像处理过程中经常会涉及到对各种raw图的操作,所以本文简单介绍一下经常遇到的几种格式的raw图的存储格式和读取方法。

一、raw格式图

1.存储格式

raw图目前遇到的有2种存储格式,一种是经过压缩的MIPI raw,另一种是未经过压缩的unpacked raw,通常采集的raw图是10bit的,需要用2个字节来存储,两个字节有16个bit位,这样就有6个bit位为空。MIPI raw就充分利用了这6个bit位,每5个字节存储4个像素值,如图1.1所示,每格代表两个bit位,前4个红色的格子存储的是第一个像素的高8位,接着4个黄色的格子存储的是第二个像素的高8位,接着4个绿色的格子存储的是第三个像素的高8位,接着4个蓝色的格子存储的第四个像素的高8位,接着1个蓝色的格子存储的是第4个像素的低2位,接着一个绿色的格子存储的是第3个像素的低2位,接着一个个黄色的格子存储的是第2个像素的低2位,最后一个红色的格子存储的是第1个像素的低2位。
图1.1 MIPI raw图存储方式
图1.1 MIPI raw的存储方式

unpacked raw的存储格式如图1.2所示,每个格子代表1个bit,绿色格子代表低10位被占用,白色格子表示高6位为空。
图1.2 unacked raw的存储方式
图1.2 unpacked raw的存储方式

2.读取方式

unpacked raw的读取

#include
#include
#include

int main()
{
	FILE *pfRaw;
	char acRawName[256];
	sprintf(acRawName,"1.raw");
	pfRaw = fopen(acRawName,"r");
	int iHeight = 1080;
	int iWidth = 1920;
	unsigned short *pusRawdata = (unsigned short *)malloc(iHeight * iWidth * sizeof(unsigned short));
	if(NULL == pfRaw)
	{
		printf("open raw file error!\n");
		return -1;
	}
	fread(pusRawdata, iWidth*iHeight*sizeof(unsigned short),1,pfRaw); //读取raw图
	fclose(pfRaw);
	return 0;
}

MIPI raw的读取和转为unpacked raw

#include
#include
#include

int main()
{
	int iWidth = 6528int iHeight = 4896int iImageSize = iWidth * iHeight * 5 / 4;
	int iRawLow2Bites = 0;
	
	unsigned char *pusRawdata = (unsigned char *)malloc(iImageSize * sizeof(unsigned char));
	unsigned short *pusRawdataOut = (unsigned short *)malloc(iWidth * iHeight * sizeof(unsigned short));
	unsigned short *pusRawdataTmp = (unsigned short *)malloc(iWidth * iHeight * sizeof(unsigned short));
	//读取MIPI raw
	FILE *pfRaw;
	char acRawName[256];
	sprintf(acRawName,"test.raw");
	pfRaw = fopen(acRawName,"rb");
	if(NULL == pfRaw)
	{
		printf("open raw file error!\n");
		return -1;
	}
	fread(pusRawdata, iImageSize * sizeof(unsigned char), 1, pfRaw);
	fclose(pfRaw);
	//MIPI raw 转化为unpacked raw
	int iTmp = 0;
	for(int i = 0;i < iImageSize; i+=5)
	{
		pusRawdataTmp[iTmp] = pusRawdata[i];
		pusRawdataTmp[iTmp + 1] = pusRawdata[i + 1];
		pusRawdataTmp[iTmp + 2] = pusRawdata[i + 2];
		pusRawdataTmp[iTmp + 3] = pusRawdata[i + 3];
		iRawLow2Bites = pusRawdata[i + 4];
		pusRawdataOut[iTmp] = ((iRawLow2Bites >> 0) & 0x03) + (pusRawdataTmp[iTmp] << 2);
		pusRawdataOut[iTmp + 1] = ((iRawLow2Bites >> 2) & 0x03) + (pusRawdataTmp[iTmp + 1] << 2);
		pusRawdataOut[iTmp + 2] = ((iRawLow2Bites >> 4) & 0x03) + (pusRawdataTmp[iTmp + 2] << 2);
		pusRawdataOut[iTmp + 3] = ((iRawLow2Bites >> 6) & 0x03) + (pusRawdataTmp[iTmp + 3] << 2);
		iTmp += 4;
	}
	//保存unpacked raw图
	char acOutName[256];
	sprintf(acOutName,"1.raw");
	FILE *pfOutRaw;
	pfOutRaw = fopen(acOutName, "wb");
	if(NULL == pfOutRaw)
	{
		printf("open outPut raw error!\n")
		return -1;
	}
	fwrite(pusRawdataOut, iWidth * iHeight * sizeof(unsigned short), 1, pfOutRaw);
	fclose(pfOutRaw);
	return 0;
}

二、pgm格式图

1.存储格式

PGM(portable graymap file format)便携式灰度图像,分为两类,即P2和P5,每种类型都是由两部分组成,文件头部分和数据部分。
文件头部分包含的信息:
(1)PGM文件的格式类型
(2)图像的宽和高
(3)图像灰度值可能的最大值
以P5类型的PGM图为例,用记事本打开图像,如图2.1所示:
raw图的存储格式和读取方式_第1张图片
图2.1 PGM图的文件头信息
P5类型的图像数据部分是从左到右从上到下的方式以二进制形式连续存储的。

2.数据处理

由于pgm格式的raw图不常用,所以通常会涉及pgm转unpacked raw的问题,如下分别是用MTALB代码和C代码实现的pgm格式raw图的读取和转化为unpacked raw的代码。

image_name = test.pgm;
%raw图的读取
im1 = imread(image_name);
%raw图的存储
image_out_name = unpacked.raw;
fid = fopen(image_out_name,'w');
fwrite(fid,im1','uint16');
fclose(fid);
#include
#include
#include

int main()
{
	int iWidth = 1280;
	int iHeight = 800;
//读取pgm图
	FILE *pfRaw;
	char acRawName[256];
	sprintf(acRawName,"test.pgm");
	pfRaw = fopen(acRawName,"rb");
	if(NULL == pfRaw)
	{
		printf("open raw file error!\n");
		return -1;
	}
	char ch[] = {0};
	for(int i = 0;i < 8;i++) //读出pgm图的8行文件头信息
	{
		fgets(ch , 256 , pfRaw);
		printf("%s\n",ch);
	}
	unsigned short *pusRawdata = (unsigned short *)malloc(iHeight * iWidth * sizeof(unsigned short));
	fread(pusRawdata , 1 , iHeight * iWidth * sizeof(unsigned short) , pfRaw);
	fclose(pfRaw);
	//保存raw图
	char acOutName[256];
	sprintf(acOutName,"1.raw");
	FILE *pfOutRaw;
	pfOutRaw = fopen(acOutName,"wb");
	if(NULL == pfOutRaw)
	{
		printf("open outPut raw error\n");
		return -1;
	}
	fwrite(pusRawdata , iHeight * iWidth * sizeof(unsigned short),pfOutRaw);
	fclose(pfOutRaw);
	return 0;
}

总结

以上是对目前遇到的raw图的总结,后续遇到新的raw图格式,会继续补上。

你可能感兴趣的:(图像处理,c++,算法,c语言,图像处理)