我有来自 MAPIR NDVI相机的原始图像,想要在MATLAB中加载它并将所需的两个波段(NIR,红色边缘)导出为tif。
根据制造商的说法,NIR数据存储在蓝色通道中,红色通道中的可见光(红色边缘)存储为16位。
我尝试用来自的代码读取文件 " How can I read in a RAW image in MATLAB?"但它创造了这些fragments,我不知道为什么会这样。我读错了文件,或者是因为NIR频道的分辨率较低。
Here是指向使用的RAW图像的链接。
答案 0 :(得分:1)
看起来“片段”的原因是CFA (color filter array) 像素排列如下拜耳马赛克:
目前尚不清楚什么是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倍):
更新:
我试图将原始图像作为参考,但我无法做到正确。
我认为CFA的调整是:
J1
- 红色通道。
J2
和J3
- 单色而不是绿色通道
J4
- NIR颜色通道。
我使用了以下处理代码:
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);
仍然有一些缺少信息才能获得正确的结果......
答案 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