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

概要

  • 普通のRGBなら良いが、いわゆるfloatのデータを保存/読み込みたい場面がある。
  • CSVやXMLで吐き出すのも悪くはないが、ただのセーブ/ロードにしてはオーバーヘッドが大きすぎる*1

サンプルコード

  • 無理やり4色モードで保存する
    1. // float の single channel 画像
    2. cv::Mat image = cv::Mat(480, 640, CV_32FC1);
    3. /* do something */
    4. /* 何かする */
    5. // 保存するためのバッファ
    6. // データ自体は image.data を直接参照する→→→→→→→→→→→→→→↓
    7. // type を CV_8UC4 で4 channel の 8bit(unsigned char) 型に変更する   ↓
    8. // サイズは image.rows, image.cols で引き継ぐ→          ↓          ↓
    9. //                                   ↓        ↓        ↓          ↓
    10. cv::Mat saveImage = cv::Mat(image.rows, image.cols, CV_8UC4, image.data);
    11. // png は4 channel 受け付ける
    12. // bmp も保存可能
    13. cv::imwrite("temp.png", saveImage);
    14.  
    15. // ここでCV_LOAD_IMAGE_UNCHANGEDを指定しないと、 ↓
    16. // 3チャンネル画像として読み込まれてしまうので注意↓
    17. cv::Mat read = cv::imread("temp.png", CV_LOAD_IMAGE_UNCHANGED);
    18. // 4チャンネルの画像を1チャンネルのfloatとして変換
    19. cv::Mat readImage = cv::Mat(read.rows, read.cols, CV_32FC1, read.data);

実行結果

  • 入力データ(単純なsync関数)
    sync-sample.png
  • cv::Mat を単純に表示*2
    float-image-sample.png
  • 保存されたファイル temp.png
    temp.png
  • 再読み込みして表示された画像
    float-image-result.png

注意

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

ジャンル:OpenCV:OpenCV 2.3準拠


*1 大き過ぎるといってもmsオーダーの話
*2 imshowでは、1、3、4チャンネルの画像は表示できる

添付ファイル: filefloat-image-result.png 481件 [詳細] filetemp.png 480件 [詳細] filefloat-image-sample.png 488件 [詳細] filesync-sample.png 504件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2013-02-07 (木) 13:46:35 (1751d)