OpenCVで巨大画像を読み込んで、縮小するプログラムを作成しているのですが、巨大画像の読み込みに失敗してしまい、数日悩んだのですが解決策がわからなかったため質問させていただきました。
OpenCVのcv::imread を用いて画像の読み込みをしているのですが、32768px × 32768pxサイズの画像の読み込みに失敗してしまいます。
但し、16384px × 16384pxでは正常に読み込め、縮小処理もできているので、OpenCV自体でメモリ制限でもしてあるのでしょうか・・・
32768px × 32768px以上のサイズなどを読み込む時の注意点などありましたら、アドバイスいただけないでしょうか。
よろしくお願いします。
------------------------[開発環境]-------------------------------
Windows7 Professional 64bit
RAM : 32GB
OpenCV 2.4.9 x64
Visual studio 2013 Professional (x64でビルドしています)
--------------------------------------------------------------------
OpenCVで巨大画像の処理
OpenCVで巨大画像の処理
プログラムを貼っていませんでしたので、追記します。
主な処理を抜粋して掲載します。
主な処理を抜粋して掲載します。
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
int main(int argc, char** argv){
if (argc < 2){
// エラー処理(省略)
}
cv::Mat i_img = cv::imread(argv[1]); //画像ファイルの読み込み
if (i_img.empty()){ //画像ファイル以外を読み込んだ場合
//プログラムの終了処理 32768px * 32768pxだとここで終了となります
}
//画像を1/4サイズにする(バイキュービック)
double scale = 0.5;
cv::Mat o_img(i_img.rows * scale, i_img.cols * scale, i_img.type());
cv::resize(i_img, o_img, o_img.size(), cv::INTER_LANCZOS4);
//画像出力
cv::imwrite((fname + "_" + ".jpg").c_str(), o_img)
}
Re: OpenCVで巨大画像の処理
(RGB * タテ * ヨコ) / ギガ
= (3 * 32768 * 32768) / (1024 * 1024 * 1024)
= 3
3GBになりますが・・さすがにでかすぎやしませんかね.
メモリ割り当てに失敗しだしたのかもしれませんね.
= (3 * 32768 * 32768) / (1024 * 1024 * 1024)
= 3
3GBになりますが・・さすがにでかすぎやしませんかね.
メモリ割り当てに失敗しだしたのかもしれませんね.
Re: OpenCVで巨大画像の処理
顔芸様 返信ありがとうございます
おっしゃる通りだと思います。
OpenCVでこのサイズのdata自体は確保できるものの、BMP画像を読み込むとメモリエラーとなってしまうので、一度dataを作成してから、自分が定義したdataへコピーしているためメモリが膨大に必要になり、エラーが発生してしまうのではないかと考えております。
そのため(?)、jpgでの読み込みはこのサイズではできています。
(間違っていましたらすみません)
どうしてもこのサイズのBMP画像を扱う必要があり、手軽にOpenCVで行えないかと模索していたのですが、なかなかサクッとできないものですね(私の勉強不足なんですが・・・
おっしゃる通りだと思います。
OpenCVでこのサイズのdata自体は確保できるものの、BMP画像を読み込むとメモリエラーとなってしまうので、一度dataを作成してから、自分が定義したdataへコピーしているためメモリが膨大に必要になり、エラーが発生してしまうのではないかと考えております。
そのため(?)、jpgでの読み込みはこのサイズではできています。
(間違っていましたらすみません)
どうしてもこのサイズのBMP画像を扱う必要があり、手軽にOpenCVで行えないかと模索していたのですが、なかなかサクッとできないものですね(私の勉強不足なんですが・・・
Re: OpenCVで巨大画像の処理
まともな情報を提示できませんが,
確か画像サイズが巨大すぎるとOpenCVで読み込めないということはあったと思います.
で,読めないものは仕方ないので,何らかの対応を行う必要があるのでしょうが,
>どうしてもこのサイズのBMP画像を扱う必要があり
これの理由次第かな,と思います.
・そもそも縮小してしまうのならば,初めから縮小したサイズの絵を入力…
・他のファイルフォーマットではダメなのですか?
ファイルフォーマットがjpgだろうがBMPだろうが,読み込んだ結果のデータの容量は同じですから,
jpgで読めるのであれば,エラー原因は必要メモリ量ではなく
OpenCVのBMPフォーマットのファイル読込処理で何かしらの制限がかけられているからなのでしょう.
であれば,そのサイズの巨大な入れ物(画像領域)を作成して あとはそこに自前でBMPを読み込めばいかがでしょうか.
確か画像サイズが巨大すぎるとOpenCVで読み込めないということはあったと思います.
で,読めないものは仕方ないので,何らかの対応を行う必要があるのでしょうが,
>どうしてもこのサイズのBMP画像を扱う必要があり
これの理由次第かな,と思います.
・そもそも縮小してしまうのならば,初めから縮小したサイズの絵を入力…
・他のファイルフォーマットではダメなのですか?
ファイルフォーマットがjpgだろうがBMPだろうが,読み込んだ結果のデータの容量は同じですから,
jpgで読めるのであれば,エラー原因は必要メモリ量ではなく
OpenCVのBMPフォーマットのファイル読込処理で何かしらの制限がかけられているからなのでしょう.
であれば,そのサイズの巨大な入れ物(画像領域)を作成して あとはそこに自前でBMPを読み込めばいかがでしょうか.
Re: OpenCVで巨大画像の処理
usao様 返信ありがとうございます
>確か画像サイズが巨大すぎるとOpenCVで読み込めないということはあったと思います
まだ詳細は把握していませんが、画像サイズorメモリ量が規定量を超える読み込みor書き込みがあると失敗するみたいです。
この上限値はBMPとJPEGで異なる(?)ようです・・・
>・そもそも縮小してしまうのならば,初めから縮小したサイズの絵を入力…
>・他のファイルフォーマットではダメなのですか?
計測結果がデフォルトで巨大サイズとなっており、それを縮小するのが目的なため、初めから縮小したサイズを得ることはできない状態です。
またそのフォーマットがBMPのみとなっています。(情報不足ですみません)
>OpenCVのBMPフォーマットのファイル読込処理で何かしらの制限がかけられているからなのでしょう.
>であれば,そのサイズの巨大な入れ物(画像領域)を作成して あとはそこに自前でBMPを読み込めばいかがでしょうか.
確かにこの方法が一番手っ取り早いですね・・・。メモリ確保自体はライブラリ側では制限がなさそうなので、ストリームの部分だけ自作して処理する方向でいこうと思います。
様々なアドバイスを頂きありがとうございました
>確か画像サイズが巨大すぎるとOpenCVで読み込めないということはあったと思います
まだ詳細は把握していませんが、画像サイズorメモリ量が規定量を超える読み込みor書き込みがあると失敗するみたいです。
この上限値はBMPとJPEGで異なる(?)ようです・・・
>・そもそも縮小してしまうのならば,初めから縮小したサイズの絵を入力…
>・他のファイルフォーマットではダメなのですか?
計測結果がデフォルトで巨大サイズとなっており、それを縮小するのが目的なため、初めから縮小したサイズを得ることはできない状態です。
またそのフォーマットがBMPのみとなっています。(情報不足ですみません)
>OpenCVのBMPフォーマットのファイル読込処理で何かしらの制限がかけられているからなのでしょう.
>であれば,そのサイズの巨大な入れ物(画像領域)を作成して あとはそこに自前でBMPを読み込めばいかがでしょうか.
確かにこの方法が一番手っ取り早いですね・・・。メモリ確保自体はライブラリ側では制限がなさそうなので、ストリームの部分だけ自作して処理する方向でいこうと思います。
様々なアドバイスを頂きありがとうございました