openmv/usr/framebuffer.py
2014-10-29 09:00:10 -06:00

120 lines
3.3 KiB
Python

import string
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import numpy
import openmv
from usb.core import USBError
class FrameBuffer(QLabel):
error = pyqtSignal(int)
error_detected = False
def __init__(self):
QLabel.__init__(self)
self.thread = QThread()
# image scaling
self.scale = 1.0
# the object to poll the camera for framebuffer
self.updater = ImageUpdater()
# update image whenever the updater tells us to
self.updater.update.connect(self.do_update)
# handle errors sent from the updater
self.updater.error.connect(self.handle_error)
# move updater into its own thread
self.updater.moveToThread(self.thread)
# start the thread
self.thread.start(QThread.HighPriority)
# set up a timer to do periodic polling
self.timer = QTimer(self)
# connect timeout to updater do_process
self.timer.timeout.connect(self.updater.do_process)
self.do_update(QImage(chr(0) * (321 * 241 * 3), 320, 240, QImage.Format_RGB888))
def quit(self):
try:
self.timer.stop()
self.thread.quit()
self.thread.wait(500)
except QErrorMessage as e:
print('FrameBuffer error quitting %s' % e.message)
def start_updater(self):
#print 'start_updater %s' % QThread.currentThreadId()
error_detected = False
self.timer.start(17)
def stop_updater(self):
#print 'stop_updater %s' % QThread.currentThreadId()
self.timer.stop()
def handle_error(self, error):
assert isinstance(error, Exception)
if not self.error_detected:
self.error_detected = True
self.stop_updater()
self.error.emit(error.errno)
print('FrameBuffer IOError dumping frame buffer: %s' % error)
def do_update(self, image):
#print 'do_update %s' % QThread.currentThreadId()
pixmap = QPixmap()
assert isinstance(image, QImage)
w = image.width()*self.scale
h = image.height()*self.scale
pixmap.convertFromImage(image.scaled(w, h, transformMode=Qt.SmoothTransformation), Qt.DiffuseDither)
self.setPixmap(pixmap)
# auto-adjust sizing on the pixmap frame
self.setMinimumWidth(pixmap.width())
self.setMinimumHeight(pixmap.height())
def set_scale(self, scale):
if 0 < scale < 4.0:
self.scale = scale
def increase_scale(self, scale):
self.set_scale(self.scale + 0.5)
def decrease_scale(self, scale):
self.set_scale(self.scale - 0.5)
def reset_scale(self):
self.set_scale(1.0)
class ImageUpdater(QObject):
update = pyqtSignal(QImage)
stop = pyqtSignal()
error = pyqtSignal(Exception)
jpeg_error = pyqtSignal()
buff = ''
def __init__(self):
QObject.__init__(self)
self.img = QImage()
def do_process(self):
try:
b = openmv.fb_dump()
except (IOError, USBError) as e:
print 'ImageUpdater error: %s' % e
self.error.emit(e)
else:
if b:
w = b[0]
h = b[1]
self.buff = b[2]
stride = w * 3
self.img = QImage(self.buff, w, h, stride, QImage.Format_RGB888)
self.update.emit(self.img)