質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

0回答

2768閲覧

Python+OpenCVでメモリが解放されない

kirishima1913

総合スコア0

OpenCV

OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2020/07/03 07:32

前提・実現したいこと

python+opnencvでネットワークカメラから白色の物体をリアルタイム検知するシステムを作っています。
輪郭を検出する際は毎フレームcv2.findContoursをループ実行しています
エラーはなく機能を実装できたのですが長時間動かすシステムの為、tracemallocでメモリークの調査をしていたところ以下の問題点を見つけました。
cv2.findContoursがメモリを確保し続け、メモリの容量が大きくなっていきます。
また下記の該当コードは本コードではなく同じ現象を再現する為の試験用コードです。

発生している問題・エラーメッセージ

cv2.findContours(image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)のところでメモリを確保し続ける。 tracemallocの出力  C:/PATH/video.py:29: size=68.8 KiB (+68.8 KiB), count=154 (+154), average=457 B        ↑         ↑               ↑                  cv2.findContours   増え続ける           増え続ける              を書いた行

該当のソースコード

python

1import numpy as np 2import cv2 3import tracemalloc 4import gc 5from statistics import mean 6 7tracemalloc.start() 8 9url = "rtsp://user:pass@ip_address/MediaInput/h264/stream_1" 10cap = cv2.VideoCapture(url) 11cv2.namedWindow('frame', cv2.WINDOW_NORMAL) 12 13snap1 = tracemalloc.take_snapshot() 14 15i = 0 16 17while (True): 18 # フレーム読み込み 19 ret, frame = cap.read() 20 # フィルター 21 filter_image = cv2.GaussianBlur(frame, (5, 5), 0) 22  # グレースケール化 23 gray = cv2.cvtColor(filter_image, cv2.COLOR_BGR2GRAY) 24 # 2値化 25 ret2, binary_image = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) 26 # モルフォロジー変換 27 morphology_image = cv2.morphologyEx(binary_image, cv2.MORPH_OPEN, np.ones((15, 15), np.uint8)) 28  # 輪郭検出*ここでメモリが確保され続ける? 29 cv2.findContours(morphology_image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) 30 31 # 映像出力 32 cv2.imshow('frame', filter_image) 33 if cv2.waitKey(1) & 0xFF == 27: 34 break 35 36 if cv2.waitKey(1) & 0xFF == ord('c'): 37 cv2.moveWindow('frame', 100, 100) 38 39 i += 1 40 41  #100フレームに1回スナップショットと差分比較 42 if i == 100: 43 i = 0 44 snap2 = tracemalloc.take_snapshot() 45 top_stats = snap2.compare_to(snap1, 'lineno') 46 print("[ Top 10 differences ]") 47 for stat in top_stats[:10]: 48 print(stat) 49 50 gc.collect() #効果なし 51 52cap.release() 53cv2.destroyAllWindows()

試したこと

輪郭を出すときはcv2.findContours()を変数に入れると思いますが、その変数を[del]したあと手動でガベージをしましたが効果なし。
どうやらcv2.findContours()をループ実行するだけでメモリが確保され続けるようです

補足情報(FW/ツールのバージョンなど)

os: windows10
python: 3.7.5

ライブラリ
numpy: 1.19.0
opnencv-contrib-python: 4.2.0.34

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yymmt

2020/07/03 11:09

参考情報です。 macOS 10.13.6 python 3.7.7 OpenCV 3.4.2 カメラ: 内臓カメラ(url=0を指定) で試験したところメモリの増加は見られませんでした。起動直後は増加が見られますが、すぐに一定値に落ち着きます。memory_profilerパッケージを使っても調査しても同様の結果です。
kirishima1913

2020/07/03 11:43

回答ありがとうございます。 当方でも色々試行しているのですがどうも検出が変化する時に参照回数と確保メモリが増加するような気がします。 おそらく変化のない静止画であれば一定値に落ち着くのかもしれません。 この程度の増加量なら無視してもいいものでしょうか?
yymmt

2020/07/03 12:03

個人的にはメモリリークは全部潰したいところですが、運用次第では無視して良いと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問