質問内容
C#で大きな(数GB)マルチページTiffファイルから任意のページの画像データを読み込もうとしています。
1枚の画像は 640 x 640 の 16bit Gray 画像で、これが5000ページ程度あるようなデータを想定しています。
まとめてメモリに読み込むのは無理なので、Nを指定してNページ目を抜き出すようなことができないか悩んでいます。
どうか良い方法をご存じの方教えてください。
直接アクセスできなくても、先頭からシーケンシャルに読んでN-1枚スキップする方法でも構わないと考えています。
なお、C# VisualStudio2015 + OpenCV / OpenCvSharp を利用しています。
試してみたことなど
(下記サンプルは読み込んだ画像を表示のために変換して16bit深度を利用していませんが、実際には16bitのデータとして使用予定です)
(1) もともとはマルチTiffでなかったため、下記の様な方法で読み込み、表示していた。 16bitでの取得もできていたと思われる
C#
1 var myBitmap = ImgConvert.Mat16bitGrayToBmp24(wMat); 2 pboxMain.Image = myBitmap; 3 Mat wMat = Cv2.ImRead(fn, ImreadModes.AnyColor | ImreadModes.AnyDepth); 4``` 5 **↓↓↓** 6 7(2) 対象がマルチページTIFFになったため、変更。(小さいデータならOK ?、メモリに入らないのでこのコードにできない・・) 8```C# 9 Mat[] wMats; 10 Cv2.ImReadMulti(fn, out wMats, ImreadModes.AnyColor | ImreadModes.AnyDepth); 11 var page = Math.Min( 100, wMats.Length )-1; // 100ページ目 12 var myBitmap = ImgConvert.Mat16bitGrayToBmp24(wMat[page]); // 表示のために変換。 13 pboxMain.Image = myBitmap;
↓↓↓
(3) ストリームを利用して何か方法はないか試してみるも行き詰まる ・・
C#
1 var tifFS = new FileStream(fn, FileMode.Open, FileAccess.Read); 2 var decoder = new TiffBitmapDecoder(tifFS, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default); 3 var page= Math.Min(100, decoder.Frames.Count)-1; // 100ページ目 4 var img = decoder.Frames[page]; // iページ目の画像 5 // ・・・ imgは BitmapFrame型。 ★これからTiff画像データである16bit配列を生成したい
【解決】(3)にコードを追加して解決しました。 ・・hihijijiさん、ありがとうございました。
C#
1 // ・・(3)の続き 2 var datas = new UInt16[img.PixelWidth * img.PixelHeight]; // 16bitデータ格納先 3 var stride = img.PixelWidth * ((format.BitsPerPixel + 7) / 8); // CopyPixelsに指定する stride 4 img.CopyPixels(datas, stride, 0); // データの取得 5 var img16 = new Img16Gray(datas, img.PixelWidth, img.PixelHeight); // Gray 16bitデータとして保存。オリジナルクラス 6 var myBitmap = img16.ToBitmapRgb24(); // 表示用のビットマップ生成 (Gray16bit=> Rgb24bitに変換) 7 pboxMain.Image = myBitmap; 8 Refresh(); 9
回答1件
あなたの回答
tips
プレビュー