ubuntu 下 C++ 利用 libtiff 库 tif(DEM)文件转换为opencv Mat 格式
写在前面:opencv 是支持打开 tif 格式彩图的,但是对于常见的 DEM 数据打开会报错。当然为了省事可以直接使用 MatLab 进行处理,但笔者偏爱 C++。这篇博客解决用 tif 数据转成 cv::Mat 格式问题。
libtiff 库编译
cd ${
libtiff_path}
mkdir release
cd release
cmake ..
make -j4
顺便一题的是压缩包中有很多无用文件,使用时可以直接留下 libtiff 和release 文件夹,其他都可以删了。
libtiff 使用教程
http://www.libtiff.org/libtiff.html
这个教程太不友好了,并没有介绍 buf 如何去使用。
main()
{
TIFF* tif = TIFFOpen("myfile.tif", "r");
if (tif) {
uint32 imageWidth, imageLength;
uint32 tileWidth, tileLength;
uint32 x, y;
tdata_t buf;
TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &imageWidth);
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &imageLength);
TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tileWidth);
TIFFGetField(tif, TIFFTAG_TILELENGTH, &tileLength);
buf = _TIFFmalloc(TIFFTileSize(tif));
for (y = 0; y < imageLength; y += tileLength)
for (x = 0; x < imageWidth; x += tileWidth)
TIFFReadTile(tif, buf, x, y, 0);
_TIFFfree(buf);
TIFFClose(tif);
}
}
DEM 数据 tif 文件是采用 tile model,所以选择这种方式。
其中 buf 类型是 tdata_t ,源码中类型年是 void * 类型,这是一种灵活的指针类型。
下面讲一下如何使用,这是一个将数据 value 提取出来的 demo。
TIFF* tif = TIFFOpen(tifPath.c_str(),"r");
uint32 imageWidth, imageLength;
uint32 tileWidth, tileLength;
if (tif) {
uint32 x, y, z;
tdata_t buf;
float* data;
TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &imageWidth);
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &imageLength);
TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tileWidth);
TIFFGetField(tif, TIFFTAG_TILELENGTH, &tileLength);
buf = _TIFFmalloc(TIFFTileSize(tif));
for (y = 0; y < imageLength; y