在MATLAB中读取RAW MAPIR图像

时间:2017-03-27 13:43:23

标签: image matlab image-processing

我有来自 MAPIR NDVI相机的原始图像,想要在MATLAB中加载它并将所需的两个波段(NIR,红色边缘)导出为tif。

根据制造商的说法,NIR数据存储在蓝色通道中,红色通道中的可见光(红色边缘)存储为16位。

我尝试用来自的代码读取文件 " How can I read in a RAW image in MATLAB?"但它创造了这些fragments,我不知道为什么会这样。我读错了文件,或者是因为NIR频道的分辨率较低。

Here是指向使用的RAW图像的链接。

2 个答案:

答案 0 :(得分:1)

看起来“片段”的原因是CFA (color filter array) 像素排列如下拜耳马赛克:

enter image description here

目前尚不清楚什么是CFA排列。

你发布了:

  

根据制造商的说法,NIR数据存储在蓝色通道中,可见光(红色边缘)存储在红色通道中

但拜耳排列有4种可能的组合 在Matlab demosaic function documentation中,组合称为'gbrg''grbg''bggr''rggb'

我不知道最常见的对齐方式是什么 我不能说哪个频道应该是“蓝色频道”,哪个是“红色频道”。 (我们都知道他们是对角线定位的) 我也无法在Google中找到对齐信息。

由于我无法分辨哪个是哪个,我已经提取了所有4个可能的频道:

srcN = 4608; %Raw image width (number of columns).
srcM = 3456; %Raw image height (number of rows).

%Open raw image for reading.
f = fopen('2017_0321_134045_015.RAW', 'r');

%Read raw data into matrix I (use '*uint16' for keeping data in uint16 - no conversion to double).
I = fread(f, [srcN, srcM], '*uint16');

fclose(f);

%Transpose I, because RAW image format is row-major, and Matlab matrix format is column-major.
I = I';


%Assume Bayer mosaic sensor alignment.
%Seperate to mosaic components.
J1 = I(1:2:end, 1:2:end);
J2 = I(1:2:end, 2:2:end);
J3 = I(2:2:end, 1:2:end);
J4 = I(2:2:end, 2:2:end);

figure;imshow(J1);title('J1');
figure;imshow(J2);title('J2');
figure;imshow(J3);title('J3');
figure;imshow(J4);title('J4');

%Save all 4 images as tif
imwrite(J1, 'J1.tif');
imwrite(J2, 'J2.tif');
imwrite(J3, 'J3.tif');
imwrite(J4, 'J4.tif');

这是四张图片(缩小了x4倍):

J1:
enter image description here

J2:
enter image description here

J3:
enter image description here

J4:
enter image description here

更新:

Emotional_Cabbage发布了以下参考图片:
enter image description here

我试图将原始图像作为参考,但我无法做到正确。

我认为CFA的调整是:
J1 - 红色通道。
J2J3 - 单色而不是绿色通道 J4 - NIR颜色通道。

插图:
enter image description here

我使用了以下处理代码:

J = demosaic(I, 'rggb');
J = imadjust(J, [0.02, 0.98], [], 0.45); %Adjust image intensity, and use gamma value of 0.45
J(:,:,2) = J(:,:,2)*0.75; %Reduce the green by factor of 0.75
figure;imshow(J);

结果:
enter image description here

仍然有一些缺少信息才能获得正确的结果......

答案 1 :(得分:1)

虽然你已经接受了另一个答案,但我想在这里保存我的努力结果以防其他人有类似的问题。根据原始问题,此代码在Mac或Linux上运行。

////////////////////////////////////////////////////////////////////////////////
// raw2tif.c
// Mark Setchell
//
// Reads a RAW file from a MAPIR NDVI camera and converts it to a TIF
//
// Usage:
// raw2tif RAWfile result.tif
////////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <string.h>
#include "tiffio.h"

#define WIDTH   4608
#define HEIGHT  3456
#define RAW_BITSPERSAMPLE   8
#define RAW_SAMPLESPERPIXEL 2
#define TIF_BITSPERSAMPLE   8
#define TIF_SAMPLESPERPIXEL 3

int main(int argc,char* argv[])
{
   char ifilename[128];
   char ofilename[128];
   unsigned char inrow[WIDTH*RAW_BITSPERSAMPLE*RAW_SAMPLESPERPIXEL/8];
   FILE* in;

   // Check input and output file names supplied
   if(argc!=3){
      fprintf(stderr,"Usage: raw2tif RAWfile TIFfile");
      exit(EXIT_FAILURE);
   }

   // Pick up arguments - infile (RAW) and outfile (TIF)
   strcpy(ifilename,argv[1]);
   strcpy(ofilename,argv[2]);

   // Open input file
   in=fopen(ifilename,"rb");
   if(in==NULL){
      fprintf(stderr,"ERROR: Unable to open RAW input file");
      exit(EXIT_FAILURE);
   }

   // Open output file
   TIFF *tif= TIFFOpen(ofilename, "w");
   if(tif==NULL){
      fprintf(stderr,"ERROR: Unable to open output file");
      exit(EXIT_FAILURE);
   }

   // Set baseline tags
   TIFFSetField(tif,TIFFTAG_IMAGEWIDTH,WIDTH);
   TIFFSetField(tif,TIFFTAG_IMAGELENGTH,HEIGHT);
   TIFFSetField(tif,TIFFTAG_BITSPERSAMPLE,TIF_BITSPERSAMPLE);
   TIFFSetField(tif,TIFFTAG_SAMPLESPERPIXEL,TIF_SAMPLESPERPIXEL);
   TIFFSetField(tif,TIFFTAG_ORIENTATION,ORIENTATION_TOPLEFT);
   TIFFSetField(tif,TIFFTAG_COMPRESSION,COMPRESSION_LZW);
   TIFFSetField(tif,TIFFTAG_PLANARCONFIG,PLANARCONFIG_CONTIG);
   TIFFSetField(tif,TIFFTAG_PHOTOMETRIC,PHOTOMETRIC_MINISBLACK);

   uint32  rowsPerStrip;
   rowsPerStrip = HEIGHT;
   rowsPerStrip = TIFFDefaultStripSize(tif, rowsPerStrip);
   TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsPerStrip);
   TIFFSetupStrips(tif);

   // Line buffer
   int scanlineSize = TIFFScanlineSize(tif);
   unsigned char* scanline = (unsigned char*) _TIFFmalloc(scanlineSize);

   // Iterate over rows of RAW file writing rows of TIF file
   for(int row=0;row<HEIGHT;row++)
   {
      if(fread(inrow,WIDTH*RAW_BITSPERSAMPLE*RAW_SAMPLESPERPIXEL/8,1,in)!=1){
         fprintf(stderr,"ERROR: Error reading input file at row %d\n",row);
         exit(EXIT_FAILURE);
      }
      // Following few lines need correcting when input file format is known
      unsigned char* ip=inrow;
      unsigned char* op=scanline;
      for(int col=0;col<WIDTH;col++){
         *op++=*ip++;  // Write RAW red to TIF red
         *op++=0;      // Set TIF green to 0
         *op++=*ip++;  // Write RAW NIR to TIF blue
      }
      if(TIFFWriteScanline(tif,scanline,row,0) != 1){
         fprintf(stderr,"ERROR: Error writing output file at row %d\n",row);
         exit(EXIT_FAILURE);
      }
   }

   // Clean up
   _TIFFfree(scanline);
   TIFFClose(tif);
}

合适的Makefile是:

CC=clang -Wall -pedantic
TIF_INC=-I/usr/include -I/usr/local/include
TIF_LIB=-L/usr/lib -L/usr/local/lib -ltiff

raw2tif: raw2tif.c
    $(CC) raw2tif.c $(TIF_INC) $(TIF_LIB) -o raw2tif