传感器采集的RAW数据通常为10bit,存储RAW数据需要两个Byte,而其中有6个bit位是空着的,这样就有存储空间浪费。MIPI RAW数据充分利用了这个特性,采用5个Byte,共40bit存储4个RAW数据。这里以大端存储方式,给出这样存储的示意图。如下图所示:
从MIPI RAW数据恢复RAW数据的方法:
//b1,b2,b3,b4,b5分别为连续读出的五个uint8类型的数据,p1,p2,p3,p4为四个像素点的像素值,那么
p1 = (b1 << 2) + ((b5 ) & 0x3);
P2 = (b2 << 2) + ((b5 >> 2) & 0x3);
P3 = (b3 << 2) + ((b5 >> 4) & 0x3);
P4 = (b4 << 2) + ((b5 >> 6) & 0x3);
正如网上说的raw图只是一个数据流文件,没有关于文件属性的信息。
所以对手里高通平台出的10bit mipi raw 3264 x 2448的mipi_raw解析数据。
如上所说,完全是数据信息。那么10bit mipi raw连续5个字节40bit可以存4个像素的。3264x2448x5/4byte这是存储这些像素信息所需的存储空间。
转换成MB和照片属性完全对应上。
根据上面猜想,我是否可以用C语言申请一个二维数组,3264x2448这也就可以让我的raw信息完全对应这个二维数组信息了。但是后面发现我数组完全没有存下所有的mipi信息,总是少了一部分。仔细检测发现,实际上我定义的是char型的数组,实际一个数组元素只有8bit。对于10bitmipiraw还是按照之前每行应该实际的数组元素为2448X10/8=4080个。修改代码如下。并验证。
感谢网上提供代码的小伙伴,顺便修改了下。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h> //win头文件#define height 2448
#define width 4080typedef unsigned char BYTE; // 定义BYTE类型,占1个字节
int main()
{
FILE *fp = NULL;
static BYTE B[height][width]; //尤其注意这个static
BYTE *ptr;
char path[256];
char outpath[256];
int i,j;
// 输入源路径并打开raw图像文件
printf("=======raw image process===========\n");
fp = fopen("C:\\Users\\D50_CC_3264_2448.raw", "rb" );
if(NULL == fp)
{
printf("can not open the raw image " );
return 0;
}
else
{
printf("read OK\n");
}
Sleep(1000); /* windows 使用Sleep,参数为毫秒 */
// 分配内存并将图像读到二维数组中
ptr = (BYTE*)malloc( width * height * sizeof(BYTE) );
for( i = 0; i < height; i++ )
{
for( j = 0; j < width ; j ++ )
{
fread( ptr, 1, 1, fp );
B[i][j]= *ptr; // 把图像输入到2维数组中,变成矩阵型式
printf("%d ",B[i][j]);
ptr++;
}
}
fclose(fp);
// 这里可以对二维数组中的图像数据进行处理
// 将处理后的图像数据输出至文件
printf("Input the raw_image path for save: ");
scanf("%s",outpath);
if( ( fp = fopen( outpath, "wb" ) ) == NULL )
{
printf("can not create the raw_image : %s\n", outpath );
return 0;
}
for( i = 0; i < height; i++ )
{
for( j = 0; j < width ; j ++ )
{
fwrite( &B[i][j], 1 , 1, fp );
}
}
fclose(fp);
free(ptr);
return 0;
}
需要注意上的定义数组的时候加了个static。之前不加,无法定义这么大的数组。
在占用内存空间较大的局部数组声明的前面加static将其从堆栈数据段挪到全局数据段即可避开因局部数组大小超过默认堆栈大小1MB造成程序不能正常运行的问题。
输出的数组二进制查看信息结尾处
原始的raw图二进制查看信息:
从上面验证可以得出:
1.mipi_raw完全只是数据信息,没有文件属性信息。从pixel多少算的出的数据量可知。