【发布时间】:2016-05-25 13:05:11
【问题描述】:
我是阅读 tiff 图像的新手,我正在尝试使用 LibTiff 从 tiff 地图中获取海拔地形值。我需要解码的地图是平铺的。根据库文档和网络研究,下面是我目前用来获取这些值的代码片段:
private void getBytes()
{
int numBytes = bitsPerSample / 8; //Number of bytes depending the tiff map
int stride = numBytes * height;
byte[] bufferTiff = new byte[stride * height]; // this is the buffer with the tiles data
int offset = 0;
for (int i = 0; i < tif.NumberOfTiles() - 1; i++)
{
int rawTileSize = (int)tif.RawTileSize(i);
offset += tif.ReadEncodedTile(i, bufferTiff, offset, rawTileSize);
}
values = new double[height, width]; // this is the matrix to save the heigth values in meters
int ptr = 0; // pointer for saving the each data bytes
int m = 0;
int n = 0;
byte[] byteValues = new byte[numBytes]; // bytes of each height data
for (int i = 0; i < bufferTiff.Length; i++)
{
byteValues[ptr] = bufferTiff[i];
ptr++;
if (ptr % numBytes == 0)
{
ptr = 0;
if (n == height) // tiff map Y pixels
{
n = 0;
m++;
if (m == width) // tiff map X pixels
{
m = 0;
}
}
values[m, n] = BitConverter.ToDouble(byteValues, 0); // Converts each byte data to the height value in meters. If the map is 32 bps the method I use is BitConverter.ToFloat
if (n == height - 1 && m == width - 1)
break;
n++;
}
}
SaveArrayAsCSV(values, "values.txt");
}
//Only to show results in a cvs file:
public void SaveArrayAsCSV(double[,] arrayToSave, string fileName) // source: http://stackoverflow.com/questions/8666518/how-can-i-write-a-general-array-to-csv-file
{
using (StreamWriter file = new StreamWriter(fileName))
{
WriteItemsToFile(arrayToSave, file);
}
}
//Only to show results in a cvs file:
private void WriteItemsToFile(Array items, TextWriter file) // source: http://stackoverflow.com/questions/8666518/how-can-i-write-a-general-array-to-csv-file
{
int cont = 0;
foreach (object item in items)
{
if (item is Array)
{
WriteItemsToFile(item as Array, file);
file.Write(Environment.NewLine);
}
else {
file.Write(item + " | ");
cont++;
if(cont == width)
{
file.Write("\n");
cont = 0;
}
}
}
}
我一直在测试两个不同的映射(每个样本 32 位和 64 位),结果相似:一开始,数据似乎是一致的,但有一点是所有其他值都损坏了(在数据结果的末尾甚至为零)。我推断有一些字节需要忽略,但我不知道如何识别它们以净化我的代码。 Tiff.ReadScanline 方法对我不起作用,因为我需要解码的地图是有组织的图块,并且此方法不适用于处理此类图像(根据 BitMiracle.LibTiff 文档)。 Tiff.ReadRGBATile 方法也无效,因为 tiff 图像不是 RGB。我可以用 Matlab 读取这些值,但是我的项目需要用 C# 构建,所以我可以将预期结果与我的进行比较。作为参考(我认为它可能会有所帮助),这些是从具有 LibTiff 标签读取方法的 tiff 文件之一中提取的一些数据:
- 图像宽度:2001
- 图像长度:2001
- BitsPerSample:32
- 压缩:PackBits(又名 Macintosh RLE)
- 光度学:MinIsBlack
- SamplesPerPixel:1
- PlanarConfig:Contig
- 平铺宽度:208
- 平铺长度:208
- 样本格式:3
提前感谢你们的帮助!
【问题讨论】:
-
我对这种格式一无所知,但简单的数学表明 2001 不能被 208 整除。2001 x 2001 图像中 208 x 208 的图块是如何组织的?
-
Here (Open Tiff Toolkit on sourceforge)你可以找到一个c++源码解码tiff瓦片。也许你通过检查找到答案。
-
感谢@OlivierJacot-Descombes 的回答。对,就是这样。使用 RGB tiff 文件工作和绘图时,我注意到发生了同样的事情:最后一列和最后一行的图块有一个“空白区域”,其中没有图像。我不是该主题的专家,但图像位于此图块内,其像素数量比图像本身多。这可能是问题所在,但我不知道如何系统地忽略没有图像的字节,或者 LibTiff 是否有办法做到这一点
标签: c# tile libtiff geotiff heightmap