Issue
I've written a OpenCV application which basically grabs frames from a camera, does some image processing and displays the image in two edited variants. First, I've used cv2.imshow()
to display the images, but while OpenCV (Build without Qt support) isn't able to provide modern GUI elements, I decided to use PySide
for my GUI.
But since this I get this error after processing about 830-850 frames (no matter, what timer rate I use, or how much image processing I do):
QImage: out of memory, returning null image
for both of my image views in the GUI, and then in each loop this one:
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
Here's a part of my code (without image processing, but it also produces the error):
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_())
In the Windows task manager I can see the RAM usage of my program:
At the point of crash, the app uses about 1.5 GB of RAM. I've tried using the gc
module and gc.collect()
after del img
, no success.
What else can I do?
EDIT:
The threaded Camera
class doesn't matter here, the error does also appear without it.
Solution
It seems to be a PySide specific bug, using PyQt will fix it. It's not even OpenCV related. It doesn't look like there will be a solution for using PySide right now...
Answered By - linusg
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.