圧縮せずに16ビット画像(PNGまたはTIFF)を保存するにはどうすればよいですか?構文は何ですか?
5 に答える
2 年後、OpenCV は 16 ビット TIFF (2.4.x バージョン) を圧縮 (LZW) で保存できます。ただし、関数で文書化されていないパラメーター TIFFTAG_COMPRESSION もサポートしています
bool imwrite(const string& filename, InputArray img, const vector<int>& params=vector<int>() )
たとえば、COMPRESSION_LZMA に設定できます (正しく動作します)。
このパラメーターの値として COMPRESSION_NONE を使用できます (また、TIFFTAG_ROWSPERSTRIP パラメーターを画像の高さに設定する必要があります)。
しかし、OpenCV は 2.4.9 バージョンであっても、その場合 (TIFFTAG_COMPRESSION を COMPRESSION_NONE に設定しようとしている) 正しくない TIFF を生成します。
OpenCV のソースを調べた後、この制限を克服する 2 つの方法を見つけました。
「opencv/modules/imgcodecs/src/grfmt_tiff.cpp」に変更を加えて OpenCV を再コンパイルします。OpenCV の担当者が圧縮用のパラメーターを追加しましたが、圧縮が必要ない場合、libtiff が TIFF ハンドルに予測子を設定できないという事実を忘れていました。このコードが見つかるはずです
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; }
そしてそれをに変更します
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; }
この後、OpenCV は圧縮および非圧縮の TIFF を保存できます (パラメータによって異なります
imwrite
)。もう 1 つの方法は、TIFF を保存するためにアプリケーションで libtiff を直接使用することです。もちろん、そのような場合は書き込み機能を実装する必要があります。Windows の場合、libtiff をコンパイルする必要がありますが、それはかなり単純なタスクです (libtiff には多くのコンパイラ用の makefile が含まれており、MinGW および MSVC、32 ビットおよび 64 ビットで完全にコンパイルされます)。
OpenCVのドキュメントによると、cvSaveImageは8ビットのシングルチャネルまたはBGRイメージのみをサポートします。2.0ドキュメントを参照してください。
他のビット深度と形式で保存するには、libpng、libMagick ++、またはその他のライブラリを使用する必要があります。
libpngのドキュメントには、PNG画像の作成方法に関するチュートリアルが含まれています。チャネルあたり16ビットのデータでRGBを指定するには、bit_depth=16およびcolor_type=PNG_COLOR_TYPE_RGBを使用します。
あなたの人生を(おそらく)少し楽にするために、png++もあります。
編集: OpenCVは新しいバージョンでの16bpcイメージの書き込みをサポートしているようです。p.streefからの回答を参照してください。関連するドキュメントへのリンクは次のとおりです。
少なくとも 2.1 以降 (古いバージョンを使用していない) cvSaveImage は、単一チャネルの 16b 深度画像を問題なく保存します。私は通常、これに .png を使用します。
これにより、「somedata」を含む 16b イメージが取得されます。
IplImage* image = cvCreateImage(cvSize(100,100),16,1);
memset(image->imageData,someData,image->width*image->height*2);
cvSaveImage("image.png",image);
私の経験では、OpenCV は画像を 16 ビットとして保存します (3 チャンネルでは試しませんでした)。pgm 形式は確実に機能し、実際の生の形式です (ランレングス圧縮なし)。