cv::Matのメモリリークで落ちる

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
ace-k@
記事: 5
登録日時: 6年前

cv::Matのメモリリークで落ちる

#1

投稿記事 by ace-k@ » 6年前

複数箇所のカメラ視点(約3000箇所)からOpenGLのglReadPixelsで描画した画面を画像(2000×1000pix)にし,画像処理をするコードを書いています.しかし,ループで繰り返し処理をしていくと,メモリがどんどん増大し,最終的にメモリがいっぱいになり,落ちてしまいます.
以下が実際に実装したコードですが,何が原因なのでしょうか.

コード:

 
// ●●.h
cv::Mat mesh_rgb_image_f;	// RGB画像(float型)
cv::Mat mesh_rgb_image_u;	// RGB画像(uchar型)

// ●●.cpp
void ReadPixels(int i, int width, int height){
mesh_rgb_image_f.create(cv::Size(width, height), CV_32FC3);	

// フレームバッファの内容を取得
glReadPixels(0, 0, width, height, GL_BGR, GL_FLOAT, mesh_rgb_image_f.data);
cv::flip(mesh_rgb_image_f, mesh_rgb_image_f, -1);
mesh_rgb_image_f.convertTo(mesh_rgb_image_u, CV_8UC3, 255);
}

// ○○.cpp
for(int i = 0; i < pos_num; i++){ // pos_num=3000
 
  // ウインドウを設定し,カメラ視点を算出する関数
  bool ortho = true;	// 平行投影
  pDoc->_vis.ViewCamera(ortho, i, WIDTH2, HEIGHT2);	
				
  DrawVisibilityMesh();	// メッシュを描画
 
  // glReadPixels()によりRGB画像を取得して格納
  pDoc->_vis.ReadPixels(i, WIDTH2, HEIGHT2);
				
  // 画像処理する関数
  pDoc->_vis.CalculateMeshParameters(i);
				
  cv::waitKey(0);	// 何かキーを押すまで待機
		
  // 画像メモリ解放
  pDoc->_vis.mesh_rgb_image_u.release();	
}
		
pDoc->_vis.mesh_rgb_image_f.release();
cv::destroyAllWindows();
	
 

よもやま
記事: 68
登録日時: 8年前
連絡を取る:

Re: cv::Matのメモリリークで落ちる

#2

投稿記事 by よもやま » 6年前

ace-k@ さんが書きました:
6年前

コード:

 
// ●●.h
cv::Mat mesh_rgb_image_f;	// RGB画像(float型)
cv::Mat mesh_rgb_image_u;	// RGB画像(uchar型)

// ●●.cpp
void ReadPixels(int i, int width, int height){
mesh_rgb_image_f.create(cv::Size(width, height), CV_32FC3);	

}
ReadPixels関数でmesh_rgb_image_f.createしているけどdestroyはループの外
なぜに??

コード:

// ○○.cpp
for(int i = 0; i < pos_num; i++){ // pos_num=3000
 
  DrawVisibilityMesh();	// メッシュを描画
 
  // glReadPixels()によりRGB画像を取得して格納
  pDoc->_vis.ReadPixels(i, WIDTH2, HEIGHT2);
				
  pDoc->_vis.mesh_rgb_image_u.release();	
}
		
pDoc->_vis.mesh_rgb_image_f.release();
cv::destroyAllWindows();
	
 

ace-k@
記事: 5
登録日時: 6年前

Re: cv::Matのメモリリークで落ちる

#3

投稿記事 by ace-k@ » 6年前

よもやまさんご回答ありがとうございます.
ご指摘のように,destroy()とrelease()をループ内の最後に記述しなおしてみました.
しかし,以前とメモリがループごとに増えてしまいます.
どこかにメモリが確保されたままになっているのでしょうか?

コード:

// ○○.cpp
for(int i = 0; i < pos_num; i++){ // pos_num=3000
 
  DrawVisibilityMesh();	// メッシュを描画
 
  // glReadPixels()によりRGB画像を取得して格納
  pDoc->_vis.ReadPixels(i, WIDTH2, HEIGHT2);
  
  pDoc->_vis.mesh_rgb_image_f.release();			
  pDoc->_vis.mesh_rgb_image_u.release();
  cv::destroyAllWindows();	
}

よもやま
記事: 68
登録日時: 8年前
連絡を取る:

Re: cv::Matのメモリリークで落ちる

#4

投稿記事 by よもやま » 6年前

コード:

  cv::destroyAllWindows();	
すいません。destoryAllWindowsに関する指摘は間違いでした。
~.release()関数と~.create()関数が対になっていなかった事を言いたかったのです。t
Mat::create関数とMat::release関数のソースを追いかけてみたのですが
pDoc->_vis.mesh_rgb_image_fかpDoc->_vis.mesh_rgb_image_uのcreateとreleaseをループではなくアプリケーション起動時に1回のみだとメモリ使用量は増えないはずなのですがいかがでしょう。
あと作業用に使う場合には関数内の変数とするのも良いと思います。
release関数でも内部データすべてリリースされるわけではないようです。

返信

“C言語何でも質問掲示板” へ戻る