简体   繁体   English

读取16位灰度TIFF

[英]reading 16-bit greyscale TIFF

I'm trying to read a 16-bit greyscale TIFF file (BitsPerSample=16) using a small C program to convert into an array of floating point numbers for further analysis. 我正在尝试使用一个小型C程序读取16位灰度TIFF文件(BitsPerSample = 16),以将其转换为浮点数数组,以进行进一步分析。 The pixel data are, according to the header information, in a single strip of 2048x2048 pixels. 根据标题信息,像素数据位于2048x2048像素的单个条带中。 Encoding is little-endian. 编码是小端的。
With that header information, I was expecting to be able to read a single block of 2048x2048x2 bytes and interpret it as 2048x2048 2-byte integers. 有了该标头信息,我期望能够读取一个2048x2048x2字节的块并将其解释为2048x2048 2字节整数。 What I in fact get is a picture split into four quadrants of 1024x1024 pixels each, the lower two of which contain only zeros. 实际上,我得到的是将一张图片分成四个象限 ,每个象限为1024x1024像素,其中下两个仅包含零。 Each of the top two quadrants look like I expected the whole picture to look: alt text http://users.aber.ac.uk/ruw/unlinked/15_inRT_0p457.png 前两个象限中的每个象限都像我期望的那样: 替代文本http://users.aber.ac.uk/ruw/unlinked/15_inRT_0p457.png
If I read the same file into Gimp or Imagemagick, both tell me that they have to reduce to 8-bit (which doesn't help me - I need the full range), but the pixels turn up in the right places: alt text http://users.aber.ac.uk/ruw/unlinked/15_inRT_0p457_gimp.png This would suggest that my idea about how the data are arranged within the one strip is wrong. 如果我将同一文件入Gimp或Imagemagick,两者都告诉我它们必须减小到8位(这对我没有帮助-我需要整个范围),但是像素会在正确的位置出现: alt文本http://users.aber.ac.uk/ruw/unlinked/15_inRT_0p457_gimp.png这表明我关于数据如何在同一条带中排列的想法是错误的。 On the other hand, the file must be correctly formatted in terms of the header information as otherwise Gimp wouldn't get it right. 另一方面,必须根据标题信息正确格式化文件,否则Gimp无法正确处理文件。 Where am I going wrong? 我要去哪里错了?

Output from tiffdump: tiffdump的输出:
15_inRT_0p457.tiff: 15_inRT_0p457.tiff:
Magic: 0x4949 Version: 0x2a 魔术:0x4949版本:0x2a
Directory 0: offset 8 (0x8) next 0 (0) 目录0:偏移量8(0x8)下一个0(0)
ImageWidth (256) LONG (4) 1<2048> 图像宽度(256)长(4)1 <2048>
ImageLength (257) LONG (4) 1<2048> ImageLength(257)长(4)1 <2048>
BitsPerSample (258) SHORT (3) 1<16> BitsPerSample(258)简短(3)1 <16>
Compression (259) SHORT (3) 1<1> 压缩(259)短(3)1 <1>
Photometric (262) SHORT (3) 1<1> 光度(262)短路(3)1 <1>
StripOffsets (273) LONG (4) 1<4096> StripOffsets(273)长(4)1 <4096>
Orientation (274) SHORT (3) 1<1> 方向(274)短(3)1 <1>
RowsPerStrip (278) LONG (4) 1<2048> 行数(278)长(4)1 <2048>
StripByteCounts (279) LONG (4) 1<8388608> StripByteCounts(279)长(4)1 <8388608>
XResolution (282) RATIONAL (5) 1<126.582> XResolution(282)有理(5)1 <126.582>
YResolution (283) RATIONAL (5) 1<126.582> Y分辨率(283)有理(5)1 <126.582>
ResolutionUnit (296) SHORT (3) 1<3> 分辨率单位(296)简短(3)1 <3>
34710 (0x8796) LONG (4) 1<0> 34710(0x8796)长(4)1 <0>
(Tag 34710 is camera information; to make sure this doesn't somehow make any difference, I've zeroed the whole range from the end of the image file directory to the start of data at 0x1000, and that in fact doesn't make any difference.) (标签34710是相机信息;为确保这不会造成任何影响,我将整个范围从图像文件目录的末尾到数据开头的0x1000归零,但实际上并没有有任何区别。)

I've found the problem - it was in my C program... 我发现了问题-它在我的C程序中...

I had allocated memory for an array of longs and used fread() to read in the data: 我已经为一个long数组分配了内存,并使用fread()读取了数据:

#define PPR 2048;
#define BPP 2;
long *pix;
pix=malloc(PPR*PPR*sizeof(long));
fread(pix,BPP,PPR*PPR,in);

But since the data come in 2-byte chunks (BPP=2) but sizeof(long)=4, fread() packs the data densely inside the allocated memory rather than packing them into long-sized parcels. 但是,由于数据以2字节块(BPP = 2)的形式出现,但是sizeof(long)= 4,因此fread()将数据密集地打包在分配的内存中,而不是将它们打包成长大小的数据包。 Thus I end up with two rows packed together into one and the second half of the picture empty. 因此,我最终将两行打包成一幅,而后半部分为空白。

I've changed it to loop over the number of pixels and read two bytes each time and store them in the allocated memory instead: 我将其更改为遍历像素数并每次读取两个字节并将它们存储在分配的内存中:

for (m=0;m<PPR*PPR;m++) {
  b1=fgetc(in);
  b2=fgetc(in);
  *(pix+m)=256*b1+b2;
}

You understand that if StripOffsets is an array, it is an offset to an array of offsets, right? 您了解,如果StripOffsets是一个数组,则它是一个偏移量数组的偏移量,对吗? You might not be doing that dereference properly. 您可能没有正确执行该取消引用。

What's your platform? 您的平台是什么? What are you trying to do? 你想做什么? If you're willing to work in .NET on Windows, my company sells an image processing toolkit that includes a TIFF codec that works on pretty much anything you can throw at it and will return 16 bpp images. 如果您愿意在Windows上的.NET中工作,则我公司出售一种图像处理工具箱 ,其中包含TIFF编解码器,该编解码器几乎可以处理您可以扔到的任何东西,并且将返回16 bpp图像。 We also have many tools that operate natively on 16bpp images. 我们还有许多工具可以在16bpp图像上本地运行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM