2013-03-10 1 views
5

私は、ウェブカメラから写真を撮ってから、それをサイズ変更し、HSVに変換し、特定の色を見つけるためにそれにいくらかの閾値をつけるプログラムを作ろうとしています。これが行われた後、私は閾値化された画像を用いて等高線を見つけ出し、異なる輪郭のx、y座標を印刷する。これを繰り返して繰り返し、ウェブカメラからの処理をリアルタイムで行います。javacvのメモリリーク

2秒ごとに約100 MBのRAMを使い切っていることを除いて、すべてうまく動作します。

これまでのところ、ウェブカメラからのライブイメージの代わりに静的なイメージを使用すると、メモリが消費されているにもかかわらず、メモリリークを大幅に最小限に抑えることができました。私のコードの下

は次のとおりです。

public class Application { 
private CaptureImage ci; 
private ImageUtils iu; 
private CanvasFrame canvasContours; 

IplImage grabbedFrame; 
IplImage resizedFrame; 
IplImage thresholdedFrame; 
IplImage clonedImage; 

public Application(){ 
    ci = new CaptureImage(); 
    iu = new ImageUtils(); 
    canvasContours = new CanvasFrame("contours"); 

} 

public void frameProcessing(){ 

    grabbedFrame = ci.grabImage(); 
    //below call used for testing purposes 
    //grabbedFrame = (IplImage) opencv_highgui.cvLoadImage("testingImage.jpg"); 
    //cloning image due to highgui guidelines. 
    clonedImage = opencv_core.cvCloneImage(grabbedFrame); 
    resizedFrame = iu.resizeImage(clonedImage); 

    opencv_core.cvReleaseImage(clonedImage); 

    thresholdedFrame = iu.thresholdImage(resizedFrame); 


    IplImage contoursFrame = iu.findContours(thresholdedFrame, resizedFrame); 

    canvasContours.showImage(contoursFrame); 


} 
} 

grabImageはこのようになりますこれは、javacvからわずか標準フレームグラバーです:私はあなたが私を与えることができます任意の助けに感謝

public class CaptureImage { 
private final OpenCVFrameGrabber grabber; 
private IplImage img = null; 


public CaptureImage(){ 
    // 0-default camera, 1 - next...so on 
      grabber = new OpenCVFrameGrabber(0); 
      try { 
       grabber.start(); 
      } catch (Exception e) { 
       System.err.print("Failed to initialize camera"); 
       e.printStackTrace(); 
      } 

} 

public IplImage grabImage(){ 

    try { 

    //A grabbed image from Logitech webcam is in following resolution: 1200x800px 

     img = grabber.grab(); 



    } catch (Exception e) { 

     e.printStackTrace(); 
    } 
    return img; 
} 

、そしてあなたの場合これ以上の情報は必要ありません。

/ジェスパー

+0

少し更新しますが、ちょうどグラバーを自分の中に入れて(真の)ループにすると、メモリリークはありません。したがって、おそらく問題の原因となるフレームグラバー自体ではありません。 –

+0

'jmap -dump:format = b、file = 'を実行すると([ここ](http://docs.oracle.com/javase/6/docs/technotes/tools/share/jmap.html)を参照) )、どこかに圧縮された形式でダンプを投稿すると、私はそれを見ていきます。 –

+0

ダンプファイルをアップロードしました。ここでダウンロードできます。 http://speedy.sh/eaJ7a/javadump.zip –

答えて

1

あなたのヒープダンプから、使用されるメモリは、ネイティブコードから参照されるすべてのバイトとint型の配列です。あなたのコードを見ると、元のイメージではなく、クローンされたイメージに対してはcvReleaseImageと呼んでいるだけです。

+0

これは正しいことです。これは、FrameGrabbersのドキュメントでは、イメージを解放しないように指示されています。これは、グラバー自体によって行われます。 –

+0

いずれの場合も、ネイティブライブラリから割り当てられたメモリなので、未リリースのイメージに関係している可能性があります。 –

+0

これも私が考えていることです。しかし、画像をロードして新しいフレームをつかむのではなく、その静的な画像を処理する場合は、まだメモリリークがありますが、約30 mb/sekの "唯一の"ものです。 –