私はOpenCVアプリケーションを書いています。これは基本的にカメラからフレームを取得し、画像処理を行い、2つの編集されたバリアントで画像を表示します。まず、cv2.imshow()
を使用して画像を表示しましたが、OpenCV(Qtサポートなし)では最新のGUI要素を提供できませんでしたが、私はPySide
を自分のGUIに使用することに決めました。QImageメモリリーク
しかし、これ以来、私は約830から850フレーム(関係なく、私が使用しているものタイマー率、またはどのくらいの画像処理私は)処理した後に、このエラーを取得する:私のイメージビューの両方のための
QImage: out of memory, returning null image
をGUIにおいて、および各ループで、このいずれか
OpenCV Error: Unspecified error (The numpy array of typenum=2, ndims=3 can not be created) in NumpyAllocator::allocate, file ..\..\..\opencv-3.1.0\modules\python\src2\cv2.cpp, line 184
OpenCV Error: Insufficient memory (Failed to allocate 921600 bytes) in cv::OutOfMemoryError, file ..\..\..\opencv-3.1.0\modules\core\src\alloc.cpp, line 52
Traceback (most recent call last):
File "C:/myfile.py", line 140, in process_frame
img = QtGui.QImage(cv2.cvtColor(thresh_img, cv2.COLOR_RGB2BGR), self.width, self.height,
cv2.error: ..\..\..\opencv-3.1.0\modules\core\src\alloc.cpp:52: error: (-4) Failed to allocate 921600 bytes in function cv::OutOfMemoryError
(ここで画像処理することなく、それはまた、エラーが発生し)、私のコードの一部です:
import cv2
import sys
from PySide import QtGui, QtCore
from threading import Thread
class MainWindow(QtGui.QMainWindow):
def __init__(self, cam=0, parent=None):
super(MainWindow, self).__init__(parent)
self.camera = Camera(cam).start()
self.title = "Cam %s" % cam
self.counter = 0
widget = QtGui.QWidget()
self.layout = QtGui.QBoxLayout(QtGui.QBoxLayout.LeftToRight)
self.video_frame = QtGui.QLabel()
self.thresh_frame = QtGui.QLabel()
self.layout.addWidget(self.video_frame)
self.layout.addWidget(self.thresh_frame)
self.layout.addStretch()
self.setCentralWidget(widget)
widget.setLayout(self.layout)
self.setMinimumSize(640, 480)
self._timer = QtCore.QTimer(self)
self._timer.timeout.connect(self.process_frame)
self._timer.start(20)
def process_frame(self):
self.counter += 1
print(self.counter)
self.frame = self.camera.read()
self.height, self.width = self.frame.shape[:2]
thresh_img = cv2.threshold(cv2.cvtColor(self.frame, cv2.COLOR_RGB2GRAY), 0, 255,
cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
thresh_img = cv2.erode(thresh_img, None, iterations=2)
thresh_img = cv2.dilate(thresh_img, None, iterations=2)
thresh_img = cv2.cvtColor(thresh_img, cv2.COLOR_GRAY2RGB)
img = QtGui.QImage(cv2.cvtColor(self.frame, cv2.COLOR_RGB2BGR), self.width, self.height,
QtGui.QImage.Format_RGB888)
img = QtGui.QPixmap.fromImage(img)
self.video_frame.setPixmap(img)
img = QtGui.QImage(cv2.cvtColor(thresh_img, cv2.COLOR_RGB2BGR), self.width, self.height,
QtGui.QImage.Format_RGB888)
img = QtGui.QPixmap.fromImage(img)
self.thresh_frame.setPixmap(img)
def closeEvent(self, event):
self.camera.stop()
event.accept()
class Camera:
def __init__(self, src=0):
self.stream = cv2.VideoCapture(src)
(self.grabbed, self.frame) = self.stream.read()
self.stopped = False
def start(self):
Thread(target=self.update, args=()).start()
return self
def update(self):
while True:
if self.stopped:
return
(self.grabbed, self.frame) = self.stream.read()
def read(self):
return self.frame
def stop(self):
self.stopped = True
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
window = MainWindow(0)
window.show()
sys.exit(app.exec_())
私は私のプログラムのRAM使用量を見ることができ、Windowsのタスクマネージャで210
:
クラッシュの時点で、アプリはRAMのおよそ1.5ギガバイトを使用しています。私はgc
モジュールとdel img
の後にgc.collect()
を使ってみましたが、成功しませんでした。
他に何ができますか?
EDIT:スレッドCamera
クラスは、ここでは関係ありません
、エラーもそれなしで表示されません。
問題を再現できる完全なスタンドアロンプログラムを提供できますか? – tfv
今は家にいませんが、すぐに投稿します!任意のアイデアimgインスタンスを削除する方法? – linusg
@tfv私のコードを今更新しました。あなたはそれを見ていいかもしれません... – linusg