"""AnnotatedImageView: Displays images with bounding boxes etc.""" from PyQt5 import QtWidgets, QtGui, QtCore from ..utils import Video class AnnotatedImageView(QtWidgets.QGraphicsView): def __init__(self, parent): super(AnnotatedImageView, self).__init__(parent=parent) self._scene = QtWidgets.QGraphicsScene() self.setScene(self._scene) self._rect = QtCore.QRectF(0, 0, 0, 0) self.setRenderHint(QtGui.QPainter.Antialiasing) self._image = None self._current_video = None def display(self, prediction, mode='prediction'): self._scene.clear() if prediction['filetype'] == 'image': self._image = QtGui.QImage(prediction['filename']) item = QtWidgets.QGraphicsPixmapItem(QtGui.QPixmap.fromImage(self._image)) self._scene.addItem(item) self._scene.setSceneRect(item.boundingRect()) self._rect = item.boundingRect() if mode in prediction.keys(): self._overlay(prediction[mode]) elif prediction['filetype'] == 'video': if 'cap' in prediction.keys(): cap = prediction['cap'] else: cap = Video(prediction['filename']) if 'frame' in prediction.keys(): frame = prediction['frame'] else: frame = 0 video_frame = cap.get_frame(frame) if video_frame is not None: self._image = QtGui.QImage(video_frame, video_frame.shape[1], video_frame.shape[0], video_frame.shape[2] * video_frame.shape[1], QtGui.QImage.Format_RGB888) item = QtWidgets.QGraphicsPixmapItem(QtGui.QPixmap.fromImage(self._image)) self._scene.addItem(item) self._scene.setSceneRect(item.boundingRect()) self._rect = item.boundingRect() if 'prediction-by-frame' in prediction.keys(): self._overlay(prediction['prediction-by-frame'][frame]) self.refit_display() def _overlay(self, prediction): if 'faces' in prediction.keys(): self._overlay_faces(prediction['faces']) def _overlay_faces(self, faces): box_background = QtGui.QColor(255, 255, 255, 51) box_border = QtGui.QColor(0, 0, 0, 1) width = float(self._image.width()) height = float(self._image.height()) for face in faces: self._scene.addRect(face['x'] * width, face['y'] * height, face['w'] * width, face['h'] * height, QtGui.QPen(QtGui.QBrush(box_border), 3.0), QtGui.QBrush(box_background)) def refit_display(self): if self._rect is None: self.resetTransform() else: self.fitInView(self._rect, QtCore.Qt.KeepAspectRatio) def resizeEvent(self, event: QtGui.QResizeEvent): self.refit_display() QtWidgets.QGraphicsView.resizeEvent(self, event) def reset(self): self._scene.clear() self._image = None self._current_video = None self._rect = None # TODO display context action