我是新手阅读tiff图像,我试图通过使用LibTiff从tiff Map 获取高程地形值 . 我需要解码的 Map 是瓷砖组织的 . 根据图书馆文档和网络研究,我正在使用的代码片段下面获取这些值:
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对我不起作用,因为我需要解码的 Map 是有组织的图块,而且这种方法不适合处理这些图像(根据BitMiracle.LibTiff文档) . 方法Tiff.ReadRGBATile也无效,因为tiff图像不是RGB . 我可以用Matlab读取这些值,但我的项目需要用C#构建,所以我可以将预期的结果与我的比较 . 作为参考(我认为它可能会有所帮助),这些是使用LibTiff标签读取方法从其中一个tiff文件中提取的一些数据:
-
ImageWidth:2001
-
ImageLength:2001
-
BitsPerSample:32
-
压缩:PackBits(又名Macintosh RLE)
-
光度学:MinIsBlack
-
SamplesPerPixel:1
-
PlanarConfig:Contig
-
TileWidth:208
-
TileLength:208
-
SampleFormat:3
在此之前,感谢您的帮助!
2 回答
这是一个改进的代码,适用于非方形图块:
好的,最后我找到了解决方案:我的错误是函数Tiff.ReadEncodedTile(tile,buffer,offset,count)中的参数“count” . Tiff.RawTileSize(int)函数返回tile的压缩字节大小(每个tile的格式不同,具体取决于压缩算法),但Tiff.ReadEncodedTile返回解压缩的字节(所有tile都更大且常量) . 这就是为什么并非所有信息都已正确保存,而只是一部分数据 . 在具有地形高程矩阵的正确代码下方(需要优化但它有效,我认为它可能有帮助)
问候!