Я новичок в работе с чтением tiff-изображений, и я пытаюсь получить значения рельефа местности с tiff-карты с помощью LibTiff. Карты, которые мне нужно декодировать, являются структурированными. Ниже фрагмент кода я использую в настоящее время, чтобы получить эти значения, на основе библиотечной документации и исследований в Интернете:Как перевести Tiff.ReadEncodedTile в матрицу рельефа местности из карты высот в C#?
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#, поэтому я могу сравнить ожидаемые результаты с моими. Как ссылки (я думаю, что это может быть полезно), вот некоторые данные, извлеченные из одного из TIFF-файлов с LibTIFF методами чтения тегов:
- ImageWidth 2001
- ImageLength: 2001
- BitsPerSample: 32
- сжатия: PackBits (ака Macintosh RLE)
- Фотометрический: MinIsBlack
- SamplesPerPixel: 1
- PlanarConfig: Contig
- TileWidth: 208
- TileLength: 208
- SampleFormat: 3
Спасибо заранее по вашей помощи, ребята!
Я ничего об этом формате, не знаю, но простая математика показывает, что 2001 не делится на 208. Как 208 х 208 фрагментов, созданных в 2001 году в 2001 году? –
[Здесь (Open Tiff Toolkit on sourceforge)] (https://sourceforge.net/projects/opentiff/) вы можете найти tiff-фрагменты кода исходного кода C++. Возможно, вы найдете ответ, проверив его. –
Спасибо, что ответил @ OlivierJacot-Descombes. Да, точно. Работая и работая с файлами TIF RGB, я заметил, что происходит то же самое: плитки последнего столбца и последней строки имеют «пустую зону», в которой нет изображения.Я не эксперт в этой теме, но изображение внутри этих плит, которые имеют большое количество пикселей, чем само изображение. Это может быть проблема, но я не знаю, как систематически игнорировать байты, у которых нет изображения, или если у LibTiff есть способ сделать это – tofraguzbel