我是处理读取tiff图像的新手,我正试图通过使用LibTiff从tiff地图获取高程地形值。我需要解码的地图是有组织的。根据图书馆文档和网络研究,我目前正在使用的代码片段下面获取这些值:
copy "$(SolutionDir)Program 1.exe" "$(OutDir)Program 1.exe"
我一直在测试两个不同的地图(每个样本32位和64位)并且结果是相似的:在开始时,数据似乎是一致的,但是有一点其中所有其他值都被破坏了(在数据结果结束时甚至为零)。我推断有一些字节需要忽略,但我不知道如何识别它们来淡化我的代码。方法Tiff.ReadScanline对我不起作用,因为我需要解码的地图是有组织的图块,而且这种方法不适用于处理这些类型的图像(根据BitMiracle.LibTiff文档)。方法Tiff.ReadRGBATile也无效,因为tiff图像不是RGB。我可以用Matlab读取这些值,但我的项目需要用C#构建,所以我可以将预期结果与我的比较。作为参考(我认为它可能会有所帮助),这些是使用LibTiff标签读取方法从其中一个tiff文件中提取的一些数据:
先谢谢你们的帮助!
答案 0 :(得分:0)
好的,最后我找到了解决方案:我的错误是参数" count"在函数Tiff.ReadEncodedTile(tile,buffer,offset,count)中。 Tiff.RawTileSize(int)函数返回磁贴的压缩字节大小(每个磁贴不同,具体取决于压缩算法),但Tiff.ReadEncodedTile返回解压缩的字节(所有磁贴的大小和常量)。这就是为什么不能正确保存所有信息,而只是保存数据的一部分。在具有地形高程矩阵的正确代码下方(需要优化,但它有效,我认为它可能会有所帮助)
private void getBytes()
{
int numBytes = bitsPerSample / 8;
int numTiles = tif.NumberOfTiles();
int stride = numBytes * height;
int bufferSize = tileWidth * tileHeight * numBytes * numTiles;
int bytesSavedPerTile = tileWidth * tileHeight * numBytes; //this is the real size of the decompressed bytes
byte[] bufferTiff = new byte[bufferSize];
FieldValue[] value = tif.GetField(TiffTag.TILEWIDTH);
int tilewidth = value[0].ToInt();
value = tif.GetField(TiffTag.TILELENGTH);
int tileHeigth = value[0].ToInt();
int matrixSide = (int)Math.Sqrt(numTiles); // this works for a square image (for example a tiles organized tiff image)
int bytesWidth = matrixSide * tilewidth;
int bytesHeigth = matrixSide * tileHeigth;
int offset = 0;
for (int j = 0; j < numTiles; j++)
{
offset += tif.ReadEncodedTile(j, bufferTiff, offset, bytesSavedPerTile); //Here was the mistake. Now it works!
}
double[,] aux = new double[bytesHeigth, bytesWidth]; //Double for a 64 bps tiff image. This matrix will save the alldata, including the transparency (the "blank zone" I was talking before)
terrainElevation = new double[height, width]; // Double for a 64 bps tiff image. This matrix will save only the elevation values, without transparency
int ptr = 0;
int m = 0;
int n = -1;
int contNumTile = 1;
int contBytesPerTile = 0;
int i = 0;
int tileHeigthReference = tileHeigth;
int tileWidthReference = tileWidth;
int row = 1;
int col = 1;
byte[] bytesHeigthMeters = new byte[numBytes]; // Buffer to save each one elevation value to parse
while (i < bufferTiff.Length && contNumTile < numTiles + 1)
{
for (contBytesPerTile = 0; contBytesPerTile < bytesSavedPerTile; contBytesPerTile++)
{
bytesHeigthMeters[ptr] = bufferTiff[i];
ptr++;
if (ptr % numBytes == 0 && ptr != 0)
{
ptr = 0;
n++;
if (n == tileHeigthReference)
{
n = tileHeigthReference - tileHeigth;
m++;
if (m == tileWidthReference)
{
m = tileWidthReference - tileWidth;
}
}
double heigthMeters = BitConverter.ToDouble(bytesHeigthMeters, 0);
if (n < bytesWidth)
{
aux[m, n] = heigthMeters;
}
else
{
n = -1;
}
}
i++;
}
if (i % tilewidth == 0)
{
col++;
if (col == matrixSide + 1)
{
col = 1;
}
}
if (contNumTile % matrixSide == 0)
{
row++;
n = -1;
if (row == matrixSide + 1)
{
row = 1;
}
}
contNumTile++;
tileHeigthReference = tileHeight * (col);
tileWidthReference = tileWidth * (row);
m = tileWidth * (row - 1);
}
for (int x = 0; x < height; x++)
{
for (int y = 0; y < width; y++)
{
terrainElevation[x, y] = aux[x, y]; // Final result. Each position of matrix has saved each pixel terrain elevation of the map
}
}
}
问候!
答案 1 :(得分:0)
这是一个改进的代码,适用于非方形图块:
(function() {
// Do something to global_variable now
}())