def __init__(self, parent): super().__init__(parent) self.parent = parent self.projection, self.projection_vb, self.projection_hist = self.image_in_vb( "Projection") self.sinogram, self.sinogram_vb, self.sinogram_hist = self.image_in_vb( "Sinogram") self.recon, self.recon_vb, self.recon_hist = self.image_in_vb("Recon") self.slice_line = InfiniteLine(pos=1024, angle=0, bounds=[0, self.projection.width()], movable=True) self.projection_vb.addItem(self.slice_line) self.tilt_line = InfiniteLine(pos=1024, angle=90, pen=(255, 0, 0, 255), movable=True) image_layout = self.addLayout(colspan=4) image_layout.addItem(self.projection_vb, 0, 0) image_layout.addItem(self.projection_hist, 0, 1) image_layout.addItem(self.recon_vb, 0, 2, rowspan=3) image_layout.addItem(self.recon_hist, 0, 3, rowspan=3) projection_details = LabelItem("Value") image_layout.addItem(projection_details, 1, 0, 1, 2) image_layout.addItem(self.sinogram_vb, 2, 0) image_layout.addItem(self.sinogram_hist, 2, 1) sino_details = LabelItem("Value") image_layout.addItem(sino_details, 3, 0, 1, 2) recon_details = LabelItem("Value") image_layout.addItem(recon_details, 3, 2, 1, 2) msg_format = "Value: {:.6f}" self.display_formatted_detail = { self.projection: lambda val: projection_details.setText(msg_format.format(val)), self.sinogram: lambda val: sino_details.setText(msg_format.format(val)), self.recon: lambda val: recon_details.setText(msg_format.format(val)) } self.projection.hoverEvent = lambda ev: self.mouse_over( ev, self.projection) self.projection.mouseClickEvent = lambda ev: self.mouse_click( ev, self.slice_line) self.slice_line.sigPositionChangeFinished.connect( self.slice_line_moved) self.sinogram.hoverEvent = lambda ev: self.mouse_over( ev, self.sinogram) self.recon.hoverEvent = lambda ev: self.mouse_over(ev, self.recon)
def __init__(self, parent): super().__init__(parent) self.parent = parent self.projection, self.projection_vb, self.projection_hist = self.image_in_vb("Projection") self.sinogram, self.sinogram_vb, self.sinogram_hist = self.image_in_vb("Sinogram") self.recon, self.recon_vb, self.recon_hist = self.image_in_vb("Recon") self.slice_line = InfiniteLine(pos=1024, angle=0, bounds=[0, self.projection.width()], movable=True) self.projection_vb.addItem(self.slice_line) self.tilt_line = InfiniteLine(pos=1024, angle=90, pen=(255, 0, 0, 255), movable=True) image_layout = self.addLayout(colspan=4) image_layout.addItem(self.projection_vb, 0, 0) image_layout.addItem(self.projection_hist, 0, 1) image_layout.addItem(self.recon_vb, 0, 2, rowspan=3) image_layout.addItem(self.recon_hist, 0, 3, rowspan=3) projection_details = LabelItem("Value") image_layout.addItem(projection_details, 1, 0, 1, 2) image_layout.addItem(self.sinogram_vb, 2, 0) image_layout.addItem(self.sinogram_hist, 2, 1) sino_details = LabelItem("Value") image_layout.addItem(sino_details, 3, 0, 1, 2) recon_details = LabelItem("Value") image_layout.addItem(recon_details, 3, 2, 1, 2) msg_format = "Value: {:.6f}" self.display_formatted_detail = { self.projection: lambda val: projection_details.setText(msg_format.format(val)), self.sinogram: lambda val: sino_details.setText(msg_format.format(val)), self.recon: lambda val: recon_details.setText(msg_format.format(val)) } self.projection.hoverEvent = lambda ev: self.mouse_over(ev, self.projection) self.projection.mouseClickEvent = lambda ev: self.mouse_click(ev, self.slice_line) self.slice_line.sigPositionChangeFinished.connect(self.slice_line_moved) self.sinogram.hoverEvent = lambda ev: self.mouse_over(ev, self.sinogram) self.recon.hoverEvent = lambda ev: self.mouse_over(ev, self.recon) # Work around for https://github.com/mantidproject/mantidimaging/issues/565 for scene in [ self.projection.scene(), self.projection_hist.scene(), self.sinogram.scene(), self.sinogram_hist.scene(), self.recon.scene(), self.recon_hist.scene(), ]: scene.contextMenu = [item for item in scene.contextMenu if "export" not in item.text().lower()]
def addItem(self, item, name): legendLabelStyle = {'size': '14pt', 'bold': True} label = LabelItem(name) label.setText(name, **legendLabelStyle) if isinstance(item, MyItem): sample = item else: sample = MyItem(item) row = self.layout.rowCount() self.items.append((sample, label)) self.layout.addItem(sample, row, 0) self.layout.addItem(label, row, 1) self.updateSize()
class DraggableTextItem(GraphicsWidget, GraphicsWidgetAnchor): def __init__(self, *args, text="", offset=None): GraphicsWidget.__init__(self) GraphicsWidgetAnchor.__init__(self) self.setFlag(self.ItemIgnoresTransformations) self.layout = QtGui.QGraphicsGridLayout() self.setLayout(self.layout) self.item_anchor = (0, 0) self.object_anchor = (0, 0) if offset is None: self.offset = (0, 0) else: self.offset = offset self.label_item = LabelItem() self.label_item.setText(text) self.layout.addItem(self.label_item, 0, 0) self.pen = mkPen(255, 255, 255, 100) self.brush = mkBrush(100, 100, 100, 50) self.updateSize() def setParentItem(self, parent): ret = GraphicsWidget.setParentItem(self, parent) if self.offset is not None: offset = Point(self.offset) anchorx = 1 if offset[0] <= 0 else 0 anchory = 1 if offset[1] <= 0 else 0 anchor = (anchorx, anchory) self.anchor(itemPos=anchor, parentPos=anchor, offset=offset) parent.items.append(self) return ret def paint(self, p, _options, _widget): p.setPen(self.pen) p.setBrush(self.brush) p.drawRect(self.boundingRect()) def anchor(self, itemPos, parentPos, offset=(0, 0)): super().anchor(itemPos, parentPos, offset) self.item_anchor = itemPos self.object_anchor = parentPos self.offset = offset def getOffset(self): return self.offset def setOffset(self, offs): if not isinstance(offs, tuple) or len(offs) != 2: raise ValueError("Must be a tuple (x, y)") self.anchor(self.item_anchor, self.object_anchor, offs) def updateSize(self): self.setGeometry(0, 0, self.label_item.width()+10, self.label_item.height()) def boundingRect(self): return QtCore.QRectF(0, 0, self.width(), self.height()) def hoverEvent(self, ev): ev.acceptDrags(QtCore.Qt.LeftButton) def mouseDragEvent(self, ev): if ev.button() == QtCore.Qt.LeftButton: dpos = ev.pos() - ev.lastPos() self.autoAnchor(self.pos() + dpos) def setText(self, text): self.label_item.setText(str(text)) self.updateSize() def getText(self): return self.label_item.text
def update_text(val: float, sqsum: float, pixel_label: LabelItem, sqsum_label: LabelItem): pixel_label.setText(f"Value: {val:.6f}") sqsum_label.setText(f"Sum of SQ: {sqsum:.6f}")
class CompareSlicesView(GraphicsLayoutWidget): less_img: ImageItem current_img: ImageItem more_img: ImageItem lessButton: QPushButton currentButton: QPushButton moreButton: QPushButton def __init__(self, parent: 'CORInspectionDialogView'): super().__init__(parent) self.parent = parent self.less_img, self.less_img_vb, self.less_hist = self.image_in_vb( "less") self.current_img, self.current_img_vb, self.current_hist = self.image_in_vb( "current") self.more_img, self.more_img_vb, self.more_hist = self.image_in_vb( "more") def on_level_change(): levels: Tuple[float, float] = self.current_hist.getLevels() self.less_hist.setLevels(*levels) self.more_hist.setLevels(*levels) self.current_hist.sigLevelsChanged.connect(on_level_change) for view, view2 in zip([self.less_img_vb, self.current_img_vb], [self.current_img_vb, self.more_img_vb]): view.linkView(ViewBox.XAxis, view2) view.linkView(ViewBox.YAxis, view2) image_layout = self.addLayout(colspan=6) self.less_label = LabelItem("") image_layout.addItem(self.less_label, 0, 0, 1, 2) self.current_label = LabelItem("") image_layout.addItem(self.current_label, 0, 2, 1, 2) self.more_label = LabelItem("Value") image_layout.addItem(self.more_label, 0, 4, 1, 2) image_layout.addItem(self.less_img_vb, 1, 0) image_layout.addItem(self.less_hist, 1, 1) image_layout.addItem(self.current_img_vb, 1, 2) image_layout.addItem(self.current_hist, 1, 3) image_layout.addItem(self.more_img_vb, 1, 4) image_layout.addItem(self.more_hist, 1, 5) less_pixel = LabelItem("Value") image_layout.addItem(less_pixel, 2, 0, 1, 2) current_pixel = LabelItem("Value") image_layout.addItem(current_pixel, 2, 2, 1, 2) more_pixel = LabelItem("Value") image_layout.addItem(more_pixel, 2, 4, 1, 2) less_sumsq = LabelItem("Value") image_layout.addItem(less_sumsq, 3, 0, 1, 2) current_sumsq = LabelItem("Value") image_layout.addItem(current_sumsq, 3, 2, 1, 2) more_sumsq = LabelItem("Value") image_layout.addItem(more_sumsq, 3, 4, 1, 2) def update_text(val: float, sqsum: float, pixel_label: LabelItem, sqsum_label: LabelItem): pixel_label.setText(f"Value: {val:.6f}") sqsum_label.setText(f"Sum of SQ: {sqsum:.6f}") self.display_formatted_detail = { # '' if val < 0 else ' ' pads out the line self.less_img: lambda val, sumsq: update_text(val, sumsq, less_pixel, less_sumsq), self.current_img: lambda val, sumsq: update_text(val, sumsq, current_pixel, current_sumsq), self.more_img: lambda val, sumsq: update_text(val, sumsq, more_pixel, more_sumsq), } for img in self.less_img, self.current_img, self.more_img: img.hoverEvent = lambda ev: self.mouse_over(ev) def mouse_over(self, ev): # Ignore events triggered by leaving window or right clicking if ev.exit: return pos = CloseEnoughPoint(ev.pos()) self._refresh_value_labels(pos) def _refresh_value_labels(self, pos: CloseEnoughPoint): diffs = [] for img in self.less_img, self.current_img, self.more_img: if img.image is not None and pos.x < img.image.shape[ 0] and pos.y < img.image.shape[1]: pixel_value = img.image[pos.y, pos.x] diff = np.sum(img.image**2) self.display_formatted_detail[img](pixel_value, diff) diffs.append(diff) return diffs @staticmethod def image_in_vb(name=None) -> Tuple[ImageItem, ViewBox, HistogramLUTItem]: im = ImageItem() vb = ViewBox(invertY=True, lockAspect=True, name=name) vb.addItem(im) hist = HistogramLUTItem(im) return im, vb, hist def set_image(self, image_type: ImageType, recon_data: np.ndarray, title: str): if image_type == ImageType.LESS: self.less_img.clear() self.less_img.setImage(recon_data) self.less_label.setText(title) elif image_type == ImageType.CURRENT: self.current_img.clear() self.current_img.setImage(recon_data, autoLevels=False) self.current_label.setText(title) elif image_type == ImageType.MORE: self.more_img.clear() self.more_img.setImage(recon_data) self.more_label.setText(title) self.less_hist.imageChanged(True, True) self.more_hist.imageChanged(True, True) self.current_hist.sigLevelsChanged.emit(self.current_hist) diffs = self._refresh_value_labels(CloseEnoughPoint([0, 0])) self.parent.mark_best_recon(diffs)