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位。

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

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

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);
    fclose(pfRaw);
    return 0;
}

MIPI raw的读取和转为unpacked raw

#include
#include
#include

int main()
{
    int iWidth = 6528;
    int iHeight = 4896;
    int 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));

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

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

    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图的存储格式和读取方式
图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;

    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++)
    {
        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);

    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图格式,会继续补上。

Original: https://blog.csdn.net/qq_41320406/article/details/125989865
Author: 会动的果子
Title: raw图的存储格式和读取方式

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/632651/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球