Я написал приложение OpenCV, которое в основном захватывает кадры с камеры, выполняет некоторую обработку изображения и отображает изображение в двух отредактированных вариантах. Во-первых, я использовал cv2.imshow()
для отображения изображений, но в то время как OpenCV (Build без поддержки Qt) не может предоставить современные элементы GUI, я решил использовать PySide
для моего графического интерфейса.Ошибка памяти QImage
Но так как это я получаю эту ошибку после обработки около 830-850 кадров (независимо от того, какая скорость таймера я использую, или сколько обработки изображений я):
QImage: out of memory, returning null image
для обоих моих взглядов изображения в графическом интерфейсе, а затем в каждом цикле это один:
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_())
В диспетчере задач Windows, я могу видеть использование оперативной памяти моей программы:
В момент аварии, приложение использует около 1,5 Гб оперативной памяти. Я пробовал использовать модуль gc
и gc.collect()
после del img
, без успеха.
Что еще я могу сделать?
EDIT:
Резьбовое Camera
класс здесь не имеет значения, ошибка делает также появляться без него.
Можете ли вы предоставить полную автономную программу, которая позволяет нам воспроизводить вашу проблему? – tfv
Im не дома прямо сейчас, но я отправлю его в ближайшее время! Любые идеи о том, как удалить экземпляр img? – linusg
@tfv Я обновил свой код прямо сейчас. Было бы неплохо, если бы вы могли посмотреть на него ... – linusg