Best Python code snippet using pyatom_python
SeriesGraphicsView.py
Source:SeriesGraphicsView.py  
1from pyqtgraph import ImageView as PGImageView2import numpy as np3import math4from PyQt5.QtCore import Qt5from PyQt5 import QtCore6from PyQt5.QtCore import pyqtSignal7import pyqtgraph as pg8from pyqtgraph.GraphicsScene import mouseEvents9from PyQt5.QtWidgets import QFrame, QHBoxLayout10from itertools import groupby11from scripts.UI.Graphics.OverlayGraphics import OverlayGraphics12from scripts.UI.Stats.ImageStats import ImageStats13from scripts.ToolBox.AutoSegmentation import AutoSegmentation14from scripts.UI.Cursor import Cursor15from scripts.Helper.SegmentationRegion import SegmentationRegion16"""17Widget that takes a viewbox and image item to display images associated with Series18"""19class SeriesGraphicsView(PGImageView):20    newSegmentationBundle = pyqtSignal(object)21    def __init__(self, parent, toolBar):22        super().__init__(parent=parent, view=ViewBox(), imageItem=ImageItem(toolBar))23        self.toolBar = toolBar24        self.toolBar.playBtn.clicked.connect(lambda x: self.play(5))25        self.toolBar.colorMapBtn.colorMapSelected.connect(self.setLookupTable)26        self.toolBar.overlayBtn.overlaySelected.connect(self.setOverlayCursor)27        self.cursor = Cursor()28        self.overlay = OverlayGraphics(self.view, self.imageItem, self.toolBar)29        self.autoSeg = AutoSegmentation(self, self.toolBar)30        self.imageStats = ImageStats(self)31        self.initUI()32    def initUI(self):33        self.centralFrame = QFrame(self)34        self.centralFrame.setFrameShape(QFrame.NoFrame)35        self.centralFrame.setFrameShadow(QFrame.Raised)36        self.centralFrame.setContentsMargins(0, 0, 0, 0)37        self.centralFrame.setStyleSheet("border: none;")38        self.setMinimumWidth(500)39        self.setMinimumHeight(300)40        self.setObjectName("imageView")41        self.ui.histogram.hide()42        self.ui.roiBtn.hide()43        self.ui.menuBtn.hide()44        self.ui.roiPlot.setVisible(False)45        self.ignorePlay = False46        self.ui.splitter.setSizes([self.height() - 35, 35])47        self.splitterHandle = self.ui.splitter.handle(1)48        self.splitterHandle.setEnabled(False)49        self.centralLayout = QHBoxLayout(self.centralFrame)50        self.centralLayout.addWidget(self.centralFrame)51        self.centralLayout.setContentsMargins(0, 0, 0, 0)52        self.setLayout(self.centralLayout)53    """54    Called when new patient is loaded. Calls reset function55    ================== ===========================================================================56    **Arguments:**57    patient            loaded patient58    ================== ===========================================================================59    """60    def newPatient(self, patient):61        self.reset()62    """63    Clears image item and sets image to None64    """65    def reset(self):66        self.clear()67        self.view.setCursor(self.cursor.DefaultCursor)68        # self.imageStats.disable()69        self.imageItem.lut = self.toolBar.colorMapBtn.colorMap70    """71    Sets cursor for series viewbox72    ================== ===========================================================================73    **Arguments:**74    activeOverlay      the overlay selected in the toolbar75    ================== ===========================================================================76    """77    def setOverlayCursor(self, overlayColor):78        if overlayColor is None:79            self.view.setCursor(self.cursor.DefaultCursor)80        else:81            self.view.setCursor(self.cursor.CrossCursor)82    """83    Sets color map for series images84    ================== ===========================================================================85    **Arguments:**86    lut                lookup table87    ================== ===========================================================================88    """89    def setLookupTable(self, lut):90        self.imageItem.setLookupTable(lut)91    """92    Iterates through the image slices at specified rate93    ================== ===========================================================================94    **Arguments:**95    rate               play rate96    ================== ===========================================================================97    """98    def play(self, rate):99        if self.ignorePlay:100            return101        if self.playTimer.isActive():102            self.playTimer.stop()103            self.toolBar.playBtn.setPlayState()104            return105        if self.currentIndex == (self.image.shape[0] - 1):106            self.setCurrentIndex(0)107        self.toolBar.playBtn.setPauseState()108        super().play(rate)109    """110    Checks for completion of play111    """112    def timeout(self):113        if self.currentIndex == (self.image.shape[0] - 1):114            self.playTimer.stop()115            self.toolBar.playBtn.setPlayState()116            return117        super().timeout()118    """119    Displays the images associated with the active series.120    ================== ===========================================================================121    **Arguments:**122    series             the series object123    ================== ===========================================================================124    """125    def seriesSelected(self, series):126        self.reset()127        if series is None:128            return129        images = []130        for image in series.images:131            images.append(image.pixel_array)132        imageData = np.array(images)133        # pytgraph assumes images are in column-major order (col, row) so we need to transpose data into that format134        imageData = imageData.transpose((0, 2, 1))135        # scaling the image to fit the viewbox dimensions is causing all sorts of issues. set to 1 for now136        imageScale = 1137        # imageScale = self.getImageScale(imageData)138        # set image for imageView139        self.setImage(imageData, scale=(imageScale, imageScale))140        self.setViewScale(imageScale)  # adjust view to fit new image141        self.view.addItem(self.imageItem)142        # show image stats panel143        # self.imageStats.enable()144        self.toolBar.colorMapBtn.colorMap = self.imageItem.lut145    """146    Updates the imageROI to match the image region specified by the mask. Mask is assumed to be147    in mask item coordinates.148    ================== ===========================================================================149    **Arguments:**150    mask               the mask151    ================== ===========================================================================152    """153    def newMask(self, mask):154        self.segmentationBundle = SegmentationBundle()155        regions = mask.regions156        regionsSorted = sorted(regions, key=lambda x: x.id)157        regionsGroupedBy = groupby(regionsSorted, key=lambda x: x.id)158        regionsGrouped = {}159        for _id, _regions in regionsGroupedBy:160            regionsGrouped[_id] = list(_regions)161        for _id, _regions in regionsGrouped.items():162            mask = sum(region.mask for region in _regions)163            mask[mask > 1] = 0164            maskCoordinates = np.argwhere(mask)165            maskCoordinates = [QtCore.QPointF(coordinate[0], coordinate[1]) for coordinate in maskCoordinates]166            maskCoordinates = [[math.floor(coordinate.x()), math.floor(coordinate.y())] for coordinate in167                               maskCoordinates]168            mask = np.zeros((self.image.shape[1], self.image.shape[2]))169            x_coords = [c[0] for c in maskCoordinates]170            y_coords = [c[1] for c in maskCoordinates]171            mask[x_coords, y_coords] = 1172            mask[mask == 0] = np.nan  # convert mask zeros to nan to differentiate between image zeros173            mask = np.ma.masked_invalid(mask)  # create a mask array to handle nan during multiplication174            masked_image = mask * self.image  # multiply masked array by image175            masked_image = masked_image.filled(176                np.nan)  # convert back to numpy array, filling in masked values with nan177            masked_image = masked_image.transpose((0, 2, 1))  # transpose image back to row-major order (row, col)178            region = SegmentationRegion()179            region.image = masked_image180            region.id = _id181            self.segmentationBundle.regions.append(region)182        self.newSegmentationBundle.emit(self.segmentationBundle)183    """184    Changes the overlaid text based on the current image185    """186    def timeLineChanged(self):187        super().timeLineChanged()188    """189    Adjusts the view limits based on the image to display. Prevents zooming out too far.190    Centers image within the view.191    ================== ===========================================================================192    **Arguments:**193    imageScale         the scale of the image194    ================== ===========================================================================195    """196    def setViewScale(self, imageScale):197        self.view.setLimits(xMin=0,198                            xMax=self.imageItem.width() * imageScale,199                            yMin=0,200                            yMax=self.imageItem.height() * imageScale,201                            minXRange=1,202                            minYRange=1)203        # viewWidth = self.view.screenGeometry().width()204        # viewHeight = self.view.screenGeometry().height()205        # if viewWidth > viewHeight:206        #     self.view.setLimits(xMin=-(viewWidth - self.imageItem.width() * imageScale),207        #                         xMax=viewWidth,208        #                         yMin=0,209        #                         yMax=viewHeight,210        #                         minXRange=1,211        #                         minYRange=1)212        #213        # else:214        #     self.view.setLimits(xMin=0,215        #                         xMax=viewWidth,216        #                         yMin=-(viewHeight - self.imageItem.height() * imageScale),217        #                         yMax=viewHeight,218        #                         minXRange=1,219        #                         minYRange=1)220        self.view.translateBy(x=0, y=0)221        aspectRatio = self.image.shape[1] / self.image.shape[2]  # width / height ratio222        self.view.setAspectLocked(lock=True, ratio=aspectRatio)223    """224    Determines the proper image scale based on the viewbox.225    ================== ===========================================================================226    **Arguments:**227    imageData          the ndarray associated with the image228    229    **Returns:**230    imageScale         the image scale231    ================== ===========================================================================232    """233    def getImageScale(self, imageData):234        viewWidth = self.view.screenGeometry().width()235        viewHeight = self.view.screenGeometry().height()236        if viewWidth < viewHeight:237            imageScale = viewWidth / imageData.shape[1]238        else:239            imageScale = viewHeight / imageData.shape[2]240        return imageScale241class SegmentationBundle:242    def __init__(self):243        self.regions = []244"""245The pyqtgraph viewbox. The viewbox displays items.246"""247class ViewBox(pg.ViewBox):248    def __init__(self):249        super().__init__()250        self.cursor = Cursor()251        self.initUI()252    def initUI(self):253        self.setAspectLocked(True)254        self.setMouseMode(pg.ViewBox.PanMode)255    def mouseDragEvent(self, ev, axis=None):256        if ev.isStart():257            self.setCursor(self.cursor.ClosedHandCursor)258        if ev.isFinish():259            self.setCursor(self.cursor.DefaultCursor)260        super().mouseDragEvent(ev, axis)261    def mouseClickEvent(self, ev):262        if ev.button() == Qt.LeftButton:263            super().mouseClickEvent(ev)264        else:265            return266    def wheelEvent(self, ev, axis=None):267        super().wheelEvent(ev, axis)268    def resizeEvent(self, ev):269        super().resizeEvent(ev)270"""271The pyqtgraph image item. An image item stores the images.272"""273class ImageItem(pg.ImageItem):274    leftMouseDragged = pyqtSignal(mouseEvents.MouseDragEvent)275    mouseHovered = pyqtSignal(mouseEvents.HoverEvent)276    contextMenuTriggered = pyqtSignal(object)277    def __init__(self, toolBar):278        super().__init__()279        self.toolBar = toolBar280    def mouseDragEvent(self, ev, axis=None):281        if self.toolBar.overlayBtn.overlayColor is None:282            super().mouseDragEvent(ev)283            return284        if ev.button() == Qt.LeftButton:285            self.leftMouseDragged.emit(ev)286    def hoverEvent(self, ev):287        if self.toolBar.overlayBtn.overlayColor is None:288            super().hoverEvent(ev)289            self.mouseHovered.emit(ev)290            return291        self.mouseHovered.emit(ev)292        ev.acceptDrags(QtCore.Qt.LeftButton)293    def contextMenuEvent(self, event):...MaskGraphicsView.py
Source:MaskGraphicsView.py  
1from PyQt5.QtCore import pyqtSignal, Qt2import pyqtgraph as pg3from pyqtgraph import GraphicsView as PGGraphicsView4from pyqtgraph.GraphicsScene import mouseEvents5import numpy as np6from PIL import Image, ImageDraw7from PyQt5.QtWidgets import QFrame, QHBoxLayout8from scripts.UI.Graphics.KernelGraphics import KernelGraphics9from scripts.UI.Cursor import Cursor10from scripts.Helper.SegmentationRegion import SegmentationRegion11"""12Widget displays mask associated with overlay drawn on series graphics13"""14class MaskGraphicsView(PGGraphicsView):15    newMask = pyqtSignal(object)16    def __init__(self, parent, toolBar):17        super().__init__(parent)18        self.view = ViewBox(self)19        self.toolBar = toolBar20        self.toolBar.clearBtn.clicked.connect(self.clear)21        self.cursor = Cursor()22        self.gridItem = GridItem(textPen=None)23        self.gridItem.setZValue(10)24        self.view.addItem(self.gridItem)25        self.maskItem = MaskItem()26        self.view.addItem(self.maskItem)27        self.kernelGraphics = KernelGraphics(self.view, self.maskItem, self.toolBar)28        self.kernelGraphics.newStamp.connect(self.newStamp)29        self.mask = None30        self.initUI()31    def initUI(self):32        self.centralFrame = QFrame(self)33        self.centralFrame.setFrameShape(QFrame.NoFrame)34        self.centralFrame.setFrameShadow(QFrame.Raised)35        self.centralFrame.setContentsMargins(0, 0, 0, 0)36        self.centralFrame.setStyleSheet("border: none;")37        self.setObjectName("maskView")38        self.view.invertY()39        self.view.setAspectLocked(True)40        self.setCentralItem(self.view)41        self.setMinimumWidth(500)42        self.setMinimumHeight(300)43        self.centralLayout = QHBoxLayout(self.centralFrame)44        self.centralLayout.addWidget(self.centralFrame)45        self.centralLayout.setContentsMargins(0, 0, 0, 0)46        self.setLayout(self.centralLayout)47        self.show()48    """49    Called when new patient is loaded. Calls reset function50    ================== ===========================================================================51    **Arguments:**52    patient            loaded patient53    ================== ===========================================================================54    """55    def newPatient(self, patient):56        self.reset()57    """58    Clears mask item and sets image to None59    """60    def reset(self):61        self.maskItem.clear()62        self.setCursor(self.cursor.DefaultCursor)63    """64    Resets binary mask array in mask item to all 0's65    """66    def clear(self):67        if self.maskItem.image is not None:68            self.maskItem.image[:, :] = 069            self.maskItem.updateImage()70    """71    Clears the existing mask. Called when the active series has changed.72    ================== ===========================================================================73    **Arguments:**74    series             the series object75    ================== ===========================================================================76    """77    def seriesSelected(self, series):78        self.reset()79        if series is None:80            self.kernelGraphics.unsubscribe()81            return82        elif series.parentSequence.getSeriesByType("Phase") is None:83            self.kernelGraphics.unsubscribe()84            return85        images = []86        for image in series.images:87            images.append(image.pixel_array.T)88        images = np.array(images)89        mask = np.zeros((images.shape[1], images.shape[2]))90        self.maskItem.setImage(mask)91        self.view.addItem(self.maskItem)92        self.maskItem.updateImage()93        self.kernelGraphics.subscribe()94    """95    Called when the kernel stamper changes the existing mask.96    ================== ===========================================================================97    **Arguments:**98    mask               numpy array mask99    100    **Signal:**101    newMask            returns mask object102    ================== ===========================================================================103    """104    def newStamp(self, mask):105        self.mask = Mask()106        # adjust emitted mask107        adjustedMask = np.copy(mask)108        non_zero_indexes = np.nonzero(adjustedMask)109        nonzero_row = non_zero_indexes[0]110        nonzero_col = non_zero_indexes[1]111        for row, col in zip(nonzero_row, nonzero_col):112            if adjustedMask[row + 1, col] == 0:113                adjustedMask[row + 1, col] = 1114            if adjustedMask[row, col + 1] == 0:115                adjustedMask[row, col + 1] = 1116            if adjustedMask[row + 1, col + 1] == 0:117                adjustedMask[row + 1, col + 1] = 1118        _region = SegmentationRegion()119        _region.mask = adjustedMask120        self.mask.regions.append(_region)121        self.newMask.emit(self.mask)122    """123    Updates the mask to match the overlay. Overlay is assumed to be in image item coordinates.124    ================== ===========================================================================125    **Arguments:**126    overlay            overlay object containing all independent overlays127    ================== ===========================================================================128    """129    def newOverlay(self, overlay):130        self.view.removeItem(self.maskItem)131        imageShape = (self.maskItem.image.shape[0], self.maskItem.image.shape[1])132        overallMask = np.empty(imageShape)133        self.mask = Mask()134        for region in overlay.regions:135            regionVertices = region.vertices136            regionCoordinates = [tuple([vertice.x(), vertice.y()]) for vertice in regionVertices]137            regionMask = Image.new('L', imageShape)138            ImageDraw.Draw(regionMask).polygon(regionCoordinates, outline=1, fill=1)139            regionMask = np.array(regionMask).T140            # adjust displayed mask to match overlay141            adjustedMask = np.copy(regionMask)142            non_zero_indexes = np.nonzero(adjustedMask)143            nonzero_row = non_zero_indexes[0]144            nonzero_col = non_zero_indexes[1]145            for row, col in zip(nonzero_row, nonzero_col):146                if adjustedMask[row + 1, col] == 0:147                    adjustedMask[row, col] = 0148                if adjustedMask[row, col + 1] == 0:149                    adjustedMask[row, col] = 0150                if adjustedMask[row + 1, col + 1] == 0:151                    adjustedMask[row, col] = 0152            overallMask = adjustedMask + overallMask153            region.mask = regionMask154            self.mask.regions.append(region)155        overallMask[overallMask > 1] = 0156        self.maskItem.setImage(overallMask)157        self.view.addItem(self.maskItem)158        self.maskItem.updateImage()159        self.newMask.emit(self.mask)160    """161    Updates the mask to match the overlay. Overlay is assumed to be in image item coordinates.162    ================== ===========================================================================163    **Arguments:**164    vertices           A list of tuples containing vertices from autosegmentation routine165    ================== ===========================================================================166    """167    def newAutoSeg(self, vertices):168        self.view.removeItem(self.maskItem)169        imageShape = (self.maskItem.image.shape[0], self.maskItem.image.shape[1])170        self.mask = Mask()171        overallMask = np.empty(imageShape)172        autoSegCoordinates = [tuple(vertice) for vertice in vertices]173        autoSegMask = Image.new('L', imageShape)174        ImageDraw.Draw(autoSegMask).polygon(autoSegCoordinates, outline=1, fill=1)175        autoSegMask = np.array(autoSegMask)176        overallMask = autoSegMask + overallMask177        overallMask[overallMask > 1] = 0178        _region = SegmentationRegion()179        _region.mask = overallMask180        self.mask.regions.append(_region)181        self.maskItem.setImage(overallMask)182        self.view.addItem(self.maskItem)183        self.maskItem.updateImage()184        self.newMask.emit(self.mask)185class Mask:186    def __init__(self):187        self.regions = []188"""189The pyqtgraph viewbox. The viewbox displays items.190"""191class ViewBox(pg.ViewBox):192    def __init__(self, parent):193        super().__init__()194        self.graphicsWidget = parent195    def initUI(self):196        self.setMouseEnabled(True)197    def mouseDragEvent(self, ev, axis=None):198        return199    def mouseClickEvent(self, ev):200        if ev.button() == Qt.RightButton:201            return202"""203The pyqtgraph image item. An image item stores the images.204"""205class MaskItem(pg.ImageItem):206    leftMousePressed = pyqtSignal(mouseEvents.MouseClickEvent)207    leftMouseDragged = pyqtSignal(mouseEvents.MouseDragEvent)208    def __init__(self, image=None):209        super().__init__(image=image)210    def mouseClickEvent(self, ev):211        if ev.button() == Qt.RightButton:212            return213        if ev.button() == Qt.LeftButton:214            self.leftMousePressed.emit(ev)215    def mouseDragEvent(self, ev):216        if ev.button() != Qt.LeftButton:217            return218        else:219            self.leftMouseDragged.emit(ev)220    def updateImage(self, *args, **kargs):221        super().updateImage(*args, **kargs)222"""223The pyqtgraph grid item. A grid item displays grid lines224"""225class GridItem(pg.GridItem):226    def __init__(self, textPen=None):...KernelGraphics.py
Source:KernelGraphics.py  
1from PyQt5.QtWidgets import QGraphicsObject2from PyQt5.QtCore import pyqtSignal3from pyqtgraph.GraphicsScene import mouseEvents4import numpy as np5import math6from scripts.UI.Cursor import Cursor7class KernelGraphics(QGraphicsObject):8    newStamp = pyqtSignal(object)9    def __init__(self, maskView, maskItem, toolBar):10        super().__init__()11        self.maskView = maskView12        self.maskItem = maskItem13        self.toolBar = toolBar14        self.setSize(self.toolBar.kernelBtn.kernelSize)15        self.toolBar.kernelBtn.kernelSelected.connect(self.setSize)16        self.eraseMode = False17        self.enabled = False18    def subscribe(self):19        self.unsubscribe()20        self.maskItem.leftMousePressed.connect(self.stampOnMouseAction)21        self.maskItem.leftMouseDragged.connect(self.stampOnMouseAction)22    def unsubscribe(self):23        try:24            self.maskItem.leftMousePressed.disconnect(self.stampOnMouseAction)25        except:26            pass27        try:28            self.maskItem.leftMouseDragged.disconnect(self.stampOnMouseAction)29        except:30            pass31    """32    Sets the size of the draw kernel.33    ================== ===========================================================================34    **Arguments:**35    kernelSize         a 2d numpy array of 1's. size is defined by arrays shape36    ================== ===========================================================================37    """38    def setSize(self, kernelSize):39        cursor = Cursor()40        if kernelSize is None:41            self.maskView.graphicsWidget.setCursor(cursor.DefaultCursor)42            self.enabled = False43            return44        self.kernelSize = kernelSize45        self.kernel = np.tile(np.ones(self.kernelSize), (self.kernelSize, 1))46        self.maskItem.setDrawKernel(kernel=self.kernel,47                                    center=(math.floor(self.kernelSize / 2), math.floor(self.kernelSize / 2)),48                                    mode='set')49        self.maskView.graphicsWidget.setCursor(cursor.CrossCursor)50        self.enabled = True51    """52    Adds kernel at the current mouse position if mask is empty. Otherwise, erases existing kernel.53    ================== ===========================================================================54    **Arguments:**55    ev                 mouse event56    ================== ===========================================================================57    """58    def stampOnMouseAction(self, ev):59        if not self.enabled:60            return61        itemPos = ev.pos()62        viewPos = self.maskView.mapFromItemToView(self.maskItem, itemPos)63        i, j = viewPos.x(), viewPos.y()64        i = int(np.clip(i, 0, self.maskItem.image.shape[0] - 1))65        j = int(np.clip(j, 0, self.maskItem.image.shape[1] - 1))66        val = self.maskItem.image[i, j]67        bound_1 = math.floor(self.kernel.shape[0] / 2)68        bound_2 = math.ceil(self.kernel.shape[0] / 2)69        if type(ev) == mouseEvents.MouseDragEvent:70            if ev.isStart():71                if val == 1:72                    self.eraseMode = True73                else:74                    self.eraseMode = False75            if ev.isFinish():76                self.newStamp.emit(self.maskItem.image)77            if self.eraseMode:78                self.maskItem.image[(i - bound_1):(i + bound_2), (j - bound_1):(j + bound_2)] = 079            else:80                self.maskItem.drawAt(viewPos, ev)81        elif type(ev) == mouseEvents.MouseClickEvent:82            if val == 1:83                self.maskItem.image[(i - bound_1):(i + bound_2), (j - bound_1):(j + bound_2)] = 084            else:85                self.maskItem.drawAt(viewPos, ev)86            self.newStamp.emit(self.maskItem.image)...Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
