プロが教えるわが家の防犯対策術!

現在USBWebカメラを利用し、画像処理をしたのちに画像をJPEG形式で保存するというプログラムを作成しています。
入力画像ビットマップデータをINT配列化⇒画像処理⇒INT配列をBufferedImageに変換⇒JPEGで保存
という流れです。
このとき、以下のコードでBufferedImageをJPEGで保存しています。

public void saveJpgbuf(BufferedImage ssimg ,String fname ) throws IOException {
//ImageIO.setUseCache(true);//プログラムの初めで実行済み
ImageWriter writer = ImageIO.getImageWritersByFormatName("jpeg").next();
ImageOutputStream out = ImageIO.createImageOutputStream(new File("c:\\"+fname + ".jpg"));
writer.setOutput(out);
writer.write(ssimg);
out.close();

}

しかし、この処理が非常に重いようで、現状のノートPC(Corei5 2.56GHz)では一画像の保存に20msはかかってしまうようです。
保存先をramdiskに変えても17msはかかります。
他の処理と比べてこの保存処理のコストが非常に高く、全体のパフォーマンスを低下させています。
このような処理を高速化できる方法はありませんでしょうか?

A 回答 (5件)

(追記)


あと、そもそもリアルタイムの画像処理はデータ量や計算量が多すぎてソフトウェアではなく専用のハードウェアに処理させるのが一般的だと思います。
つまり、ソフトウェアでやろうとしていること自体に無理があると思います。3Dゲームなどもハードウェア処理のおかげで秒30フレーム以上で処理ができるわけで、ソフトウェアでやれば秒10フレームでればいいということもあります。

ソフトウェアで処理を行う場合、入力画像の解像度を下げることや秒あたりのフレーム数を減らさざるを得ません。基本的に高性能なマシンを使用することや、CPUアーキテクチャとの相性も考慮する必要があります。
Intel の CPU は互換性に優れていると言えるが、時代遅れとも言えるかもしれない。(アーキテクチャが)と、まだまだ勉強不足ながらそんな印象を最近受けました。

あとは、画像圧縮処理を高速化することですかね。こんなのありました。
http://jpn.nec.com/press/201211/20121105_03.html
まあ、ご参考までに。
    • good
    • 0
この回答へのお礼

ありがとうございます。参考になります。
私の研究におけるこの処理は、当初ハードウェアでやろうと検討したら5000万の機械が必要と言われ、ソフトウェアでできたら安く済むな、という経緯がありました。
ソフトウェアで成果が上がれば、専用ハードウェアを頼めるのです。

とりあえずは今あるハードウェア(CPU,GPU,SSD等)をうまく使って解決していきます。

お礼日時:2012/12/18 16:04

JPEGにしないで、ベタに出力したらどうなるでしょう?


読み書きの速度と圧縮速度のどちらが早いか、によりますが。RAMディスクに出力すれば、早いかもしれません
    • good
    • 0

>すでにマルチスレッド化されており、画像処理後のBufferedImageを他のスレッドに受け渡し、他のスレッドでJPEG保存を行っています。


だったらもうその処理だけC/C++でネイティブ化(Windowsならdll)して作る。
    • good
    • 0
この回答へのお礼

ありがとうございます。
もうこれ以上はJAVAでは不可能ということですかね・・・。
C等で一部処理を行う必要があるなら、いっそOpenCV等に移植を検討してみます。

お礼日時:2012/12/18 15:39

いや、ちょっと、秒あたり何フレーム処理させようとしているの?


20ms なら秒あたり50フレーム分はできるし・・・。

ハイスピードカメラでも作ろうとしているの?
http://ja.wikipedia.org/wiki/ハイスピードカメラ)

そもそも、あなたの使っているUSBWebカメラの性能はいくつですか?

http://www.amazon.co.jp/dp/B002J4UA9G/
カメラ・最大フレームレート : ~1280×720ピクセル時 : 30fps、、1600×1200ピクセル時 : 10fps、2048×1536ピクセル時 : 10fps

普通のカメラなら秒30フレームですよ!!


本題
タイマを使って秒30フレームでカメラの画像を取得するように入力系を設計し直すのが適当と思います。
ただ、タイマは精度に注意が必要ですね・・・。
タイマの精度が問題ないか事前にテストして見てください。
    • good
    • 0
この回答へのお礼

ありがとうございます。
秒あたりの処理フレーム数については以下の理由から早ければ早いほどいいのです。

(1)今後60FPSのUSB接続のカメラ(業務用の内視鏡や眼球カメラ等を含む)、を接続するかもしれない。

(2)現在の私の研究では 1フレームの1枚の画像から4枚の画像を生成し、それを連ねた動画にする、という処理をしています。
そのため、入力は15FPSでもよいのですが、出力は60
FPSの速度で保存できなければ、バッファに蓄積され続けてしまうのです。
ちなみに画像処理部は1フレーム取得から4フレーム分のデータ生成までで約60msで終わります。

とりあえず15FPSでJPEGファイルを保存して、そのあと画像処理という風にすればもちろん解決するのですが、それだとリアルタイム性に欠けるのです。

お礼日時:2012/12/18 15:26

マルチスレッド化して画像処理をメイン処理と切り離して裏で処理させて見た目的だけでも処理が止まったような状態ではなくしておく。

    • good
    • 1
この回答へのお礼

ありがとうございます。
が、すみません。説明が足りませんでした。
すでにマルチスレッド化されており、画像処理後のBufferedImageを他のスレッドに受け渡し、他のスレッドでJPEG保存を行っています。
このとき、画像処理と並列で行っているので、処理時間は20msより長くかかっています。
このJPEG保存の速度が遅いために、保持するBufferedImageが多くなりすぎてメモリが一杯になってしまうのです。

お礼日時:2012/12/18 13:27

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!