问题描述
如何在没有任何压缩的情况下保存16位图像(PNG或TIFF)?
$ p2年后OpenCV可以用压缩(LZW)保存16位TIFF(2.4.x版本) )。但它也支持功能无证参数TIFFTAG_COMPRESSION
布尔imwrite(常量字符串和放大器;文件名,InputArray IMG,常量矢量< INT>&安培; PARAMS = (< int>())
它可以设置为COMPRESSION_LZMA,
$ b
您可以使用COMPRESSION_NONE作为此参数(你也必须设置TIFFTAG_ROWSPERSTRIP参数图像高度)的值。
但OpenCV的还是,产生在这种情况下不正确的TIFF(尝试设置TIFFTAG_COMPRESSION到COMPRESSION_NONE),即使在2.4.9版本
看着OpenCV的来源后,我发现2种方法来克服这种限制:
-
使用opencv / modules / imgcodecs / src / grfmt_tiff.cpp中的变更重新编译OpenCV压缩,但忘记了事实,libtiff不能设置预测器在TIFF句柄,如果我们不想压缩。您应该可以找到此代码
if(!TIFFSetField(pTiffHandle,TIFFTAG_IMAGEWIDTH,width)
||!TIFFSetField(pTiffHandle,TIFFTAG_IMAGELENGTH,高)
||!TIFFSetField(pTiffHandle,TIFFTAG_BITSPERSAMPLE,bitsPerChannel)
||!TIFFSetField(pTiffHandle,TIFFTAG_COMPRESSION,压缩)
||!TIFFSetField(pTiffHandle,TIFFTAG_PHOTOMETRIC,色彩)
||!TIFFSetField(pTiffHandle,TIFFTAG_SAMPLESPERPIXEL,通道)
||!TIFFSetField(pTiffHandle,TIFFTAG_PLANARCONFIG,PLANARCONFIG_CONTIG)
||!TIFFSetField(pTiffHandle,TIFFTAG_ROWSPERSTRIP,rowsPerStrip)
||!TIFFSetField (pTiffHandle,TIFFTAG_PREDICTOR,predictionor)
)
{
TIFFClose(pTiffHandle);
return false;
}
并将其更改为
如果(!TIFFSetField(pTiffHandle,TIFFTAG_IMAGEWIDTH,宽度)
||!TIFFSetField(pTiffHandle,TIFFTAG_IMAGELENGTH,高度)
||!TIFFSetField(pTiffHandle,TIFFTAG_BITSPERSAMPLE,bitsPerChannel)
||! TIFFSetField(pTiffHandle,TIFFTAG_COMPRESSION,压缩)
||!TIFFSetField(pTiffHandle,TIFFTAG_PHOTOMETRIC,色彩)
||!TIFFSetField(pTiffHandle,TIFFTAG_SAMPLESPERPIXEL,通道)
||!TIFFSetField(pTiffHandle,TIFFTAG_PLANARCONFIG ,PLANARCONFIG_CONTIG)
||!TIFFSetField(pTiffHandle,TIFFTAG_ROWSPERSTRIP,rowsPerStrip)
)
{
TIFFClose(pTiffHandle);
return false;
}
if(compression!= COMPRESSION_NONE
&&!TIFFSetField(pTiffHandle,TIFFTAG_PREDICTOR,predictor)
)
{
TIFFClose(pTiffHandle) ;
return false;这个OpenCV之后可以保存压缩和未压缩的TIFF(取决于}
> imwrite )。 -
另一种方法是在应用程序中直接使用libtiff来保存TIFF。当然,在这种情况下你需要实现写入功能。对于windows,你应该编译的libtiff,但比较简单的任务(的libtiff包含很多编译makefile和完美的MinGW和MSVC,32位和64位编译)。
How can I save a 16 bit image (PNG or TIFF) without any compression? What is the syntax?
After 2 years OpenCV can save 16-bit TIFFs (2.4.x versions) with compression (LZW). But it also supports undocumented parameter TIFFTAG_COMPRESSION in function
bool imwrite(const string& filename, InputArray img, const vector<int>& params=vector<int>() )
It can be set to COMPRESSION_LZMA, for example (and working correctly).
You can use COMPRESSION_NONE as a value for this parameter (also you have to set TIFFTAG_ROWSPERSTRIP parameter to image height).
But OpenCV still generates incorrect TIFF in that case (trying to set TIFFTAG_COMPRESSION to COMPRESSION_NONE) even in 2.4.9 version.
After looking at OpenCV sources I found 2 ways to overcome this restriction:
Recompile OpenCV with changes in "opencv/modules/imgcodecs/src/grfmt_tiff.cpp" - guys from OpenCV added parameter for compression, but forgot about the fact that libtiff can't set predictor in TIFF handle if we don't want compression. You should find this code
if ( !TIFFSetField(pTiffHandle, TIFFTAG_IMAGEWIDTH, width) || !TIFFSetField(pTiffHandle, TIFFTAG_IMAGELENGTH, height) || !TIFFSetField(pTiffHandle, TIFFTAG_BITSPERSAMPLE, bitsPerChannel) || !TIFFSetField(pTiffHandle, TIFFTAG_COMPRESSION, compression) || !TIFFSetField(pTiffHandle, TIFFTAG_PHOTOMETRIC, colorspace) || !TIFFSetField(pTiffHandle, TIFFTAG_SAMPLESPERPIXEL, channels) || !TIFFSetField(pTiffHandle, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG) || !TIFFSetField(pTiffHandle, TIFFTAG_ROWSPERSTRIP, rowsPerStrip) || !TIFFSetField(pTiffHandle, TIFFTAG_PREDICTOR, predictor) ){ TIFFClose(pTiffHandle); return false;}
and change it to
if ( !TIFFSetField(pTiffHandle, TIFFTAG_IMAGEWIDTH, width) || !TIFFSetField(pTiffHandle, TIFFTAG_IMAGELENGTH, height) || !TIFFSetField(pTiffHandle, TIFFTAG_BITSPERSAMPLE, bitsPerChannel) || !TIFFSetField(pTiffHandle, TIFFTAG_COMPRESSION, compression) || !TIFFSetField(pTiffHandle, TIFFTAG_PHOTOMETRIC, colorspace) || !TIFFSetField(pTiffHandle, TIFFTAG_SAMPLESPERPIXEL, channels) || !TIFFSetField(pTiffHandle, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG) || !TIFFSetField(pTiffHandle, TIFFTAG_ROWSPERSTRIP, rowsPerStrip) ){ TIFFClose(pTiffHandle); return false;}if (compression != COMPRESSION_NONE && !TIFFSetField(pTiffHandle, TIFFTAG_PREDICTOR, predictor) ){ TIFFClose(pTiffHandle); return false;}
after this OpenCV can save compressed and uncompressed TIFFs (depends on parameters to
imwrite
).The other way is direct using libtiff in your application for saving TIFFs. Of course you need implement writing function in such case. For windows you should compile libtiff, but it is rather simple task (libtiff contains makefiles for many compilers and perfectly compiles in MinGW and MSVC, 32 and 64 bit).
这篇关于使用OpenCV写入16位未压缩图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!