普通のRGBでなく、シングルチャンネルの 32bit 浮動小数点データを画像として保存したい

#contents

*概要 [#q1691c48]
-普通のRGBなら良いが、いわゆるfloatのデータを保存/読み込みたい場面がある。
-CSVやXMLで吐き出すのも悪くはないが、ただのセーブ/ロードにしてはオーバーヘッドが大きすぎる((大き過ぎるといってもmsオーダーの話))

*サンプルコード [#zf5d62f3]
-無理やり4色モードで保存する
#geshi(c++,number){{
// float の single channel 画像
cv::Mat image	= cv::Mat(480, 640, CV_32FC1);
/* do something */
/* 何かする */
// 保存するためのバッファ
// データ自体は image.data を直接参照する→→→→→→→→→→→→→→↓
// type を CV_8UC4 で4 channel の 8bit(unsigned char) 型に変更する   ↓
// サイズは image.rows, image.cols で引き継ぐ→          ↓          ↓
//                                   ↓        ↓        ↓          ↓
cv::Mat saveImage	= cv::Mat(image.rows, image.cols, CV_8UC4, image.data); 
// png は4 channel 受け付ける
// bmp も保存可能
cv::imwrite("temp.png", saveImage);

// ここでCV_LOAD_IMAGE_UNCHANGEDを指定しないと、 ↓
// 3チャンネル画像として読み込まれてしまうので注意↓
cv::Mat read 	= cv::imread("temp.png", CV_LOAD_IMAGE_UNCHANGED);
// 4チャンネルの画像を1チャンネルのfloatとして変換
cv::Mat readImage	= cv::Mat(read.rows, read.cols, CV_32FC1, read.data);
}}

*実行結果 [#lbf1f526]
-入力データ(単純なsync関数)
#ref(sync-sample.png)
-cv::Mat を単純に表示((imshowでは、1、3、4チャンネルの画像は表示できる))
#ref(float-image-sample.png)
-保存されたファイル temp.png
#ref(temp.png)
-再読み込みして表示された画像
#ref(float-image-result.png)

*注意 [#u002d8b3]
-データのセーブ/ロード自体は問題ないが、保存された画像が意味があるもになるかはデータ依存。
-bmpでも保存は成功した。ただ、pngに比べてオーバーヘッドが大きく、VGAの画像で200KB程増えた
-無理やり4チャンネル画像として保存してるので、imreadするときに、CV_LOAD_IMAGE_UNCHANGEDをflagとして渡す必要がある(サンプルコード17行目)

ジャンル[[:OpenCV]][[:OpenCV 2.3]]準拠

トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS