def read_plist_roi_file(fname, nOfRois=0, shape=None, debug=False): with open(fname, 'rb') as fp: pl = plistlib.load(fp) outrois = [None] * len(pl['Images']) nRois = 0 for image in pl['Images']: points = image['ROIs'][0]['Point_px'] outpoints = [] try: imageHeight = image['ImageHeight'] except KeyError: if shape is not None: imageHeight = shape[1] else: raise IndexError( "The image height is not indicated in the xml file, pass it as input" ) imageIndex = image['ImageIndex'] for point in points: if debug: print(point, type(point)) px = float(point.split(",")[0][1:]) py = -float(point.split(",")[1][:-1]) if debug: print(px, py) outpoints.append([px, py]) if debug: print(image['ImageIndex'], outpoints) if imageIndex < len(outrois): outrois[imageIndex] = pg.PolyLineROI(outpoints, closed=True).saveState() else: outrois[nRois] = pg.PolyLineROI(outpoints, closed=True).saveState() nRois += 1 if nOfRois and nRois >= nOfRois: break return outrois, nRois
def roi2myroi(ROI, verbose=False): rois = [None]*len(ROI) firsttime = True for layer in xrange(0, len(ROI)): fetta = ROI[layer] apoints = [] if fetta.max() > 0 : for j, riga in enumerate(fetta): for i, elemento in enumerate(riga): if elemento: thispoint = [i,j] apoints.append(thispoint) points = np.array(apoints) if firsttime: firsttime = False for point in points: print(point) hull = ConvexHull(points) rois[layer] = pg.PolyLineROI(hull.simplices.tolist(), pen=(6,9), closed=True).saveState() return rois
def __init__(self): # QtGui.QWidget.__init__(self) super(Window_dicom_roi2, self).__init__() # self.setGeometry(50, 50, 500, 300) self.setWindowTitle("DICOM roi (v3)") # self.setWindowIcon(QtGui.QIcon('pythonlogo.png')) widgetWindow = QtGui.QWidget(self) self.setCentralWidget(widgetWindow) outfname = "roi.txt" self.inpath = "." parser = argparse.ArgumentParser() parser.add_argument("-v", "--verbose", help="increase output verbosity", action="store_true") parser.add_argument("-r", "--raw", help="dont read raw data", action="store_true") parser.add_argument("-i", "--inputpath", help="path of the DICOM directory (default ./)") parser.add_argument("-o", "--outfile", help="define output file name (default roi.txt)") parser.add_argument("-l", "--layer", help="select layer", type=int) parser.add_argument( "-f", "--filterROI", help= "filter the image with a ROI (folder path, nrrd file supported)") group = parser.add_mutually_exclusive_group() group.add_argument("-y", "--yview", help="swap axes", action="store_true") group.add_argument("-x", "--xview", help="swap axes", action="store_true") args = parser.parse_args() self.layer = 0 if args.outfile: outfname = args.outfile if args.inputpath: self.inpath = args.inputpath if args.layer: self.layer = args.layer self.raw = not args.raw openFile = QtGui.QAction("&Open ROI File", self) openFile.setShortcut("Ctrl+O") openFile.setStatusTip('Open ROI File') openFile.triggered.connect(self.file_open) saveFile = QtGui.QAction("&Save ROI on File", self) saveFile.setShortcut("Ctrl+S") saveFile.setStatusTip('Save ROI on File') saveFile.triggered.connect(self.file_save) # self.statusBar() mainMenu = self.menuBar() fileMenu = mainMenu.addMenu('&ROI') # fileMenu.addAction(extractAction) fileMenu.addAction(openFile) fileMenu.addAction(saveFile) self.verbose = args.verbose self.filterROI = args.filterROI freader = FileReader(self.inpath, args.filterROI, args.verbose) # dataRGB, unusedROI = read_files(inpath, False, args.verbose, False) if self.raw: dataBW, ROI = freader.read(True) self.dataZ = dataBW #[:,:,::-1] else: dataRGB, ROI = freader.read(False) self.dataZ = dataRGB #[:,:,:,0] # # self.data = dataRGB[:,:,::-1,:] #dataswappedX = np.swapaxes(np.swapaxes(self.data,0,1),1,2) self.dataswappedX = np.swapaxes(np.swapaxes(self.dataZ, 0, 1), 1, 2)[:, ::-1, ::-1] self.dataswappedY = np.swapaxes(self.dataZ, 0, 2)[:, :, ::-1] self.ConstPixelDims = freader.ConstPixelDims self.ConstPixelSpacing = freader.ConstPixelSpacing if args.verbose: print(self.dataZ.shape) print("layer: ", self.layer) self.xview = args.xview self.yview = args.yview self.img1a = pg.ImageItem() self.arr = None self.firsttime = True if self.xview: imgScaleFactor = 1. / freader.scaleFactor self.data = self.dataswappedX self.ROI = np.swapaxes(np.swapaxes(ROI, 0, 1), 1, 2)[:, ::-1, ::-1] self.xscale = self.ConstPixelSpacing[1] self.yscale = self.ConstPixelSpacing[2] elif self.yview: imgScaleFactor = 1. / freader.scaleFactor self.data = self.dataswappedY self.ROI = np.swapaxes(ROI, 0, 2)[:, :, ::-1] self.xscale = self.ConstPixelSpacing[0] self.yscale = self.ConstPixelSpacing[2] else: imgScaleFactor = 1. self.data = self.dataZ self.ROI = ROI self.xscale = self.ConstPixelSpacing[0] self.yscale = self.ConstPixelSpacing[1] self.xshift = 0 self.yshift = 0 if self.verbose: print("data len:", len(self.data)) self.updatemain() self.rois = [None] * len(self.data) self.button_next = QtGui.QPushButton('Next', self) self.button_prev = QtGui.QPushButton('Prev', self) self.button_next.clicked.connect(self.nextimg) self.button_prev.clicked.connect(self.previmg) # layout = QtGui.QVBoxLayout(self) # layout = QtGui.QGridLayout(self) layout = QtGui.QGridLayout(widgetWindow) layout.addWidget(self.button_next, 1, 1) layout.addWidget(self.button_prev, 2, 1) self.button_setroi = QtGui.QPushButton('Set ROI', self) self.button_setroi.clicked.connect(self.setROI) layout.addWidget(self.button_setroi, 12, 1) self.button_delroi = QtGui.QPushButton('Del ROI', self) self.button_delroi.clicked.connect(self.delROI) layout.addWidget(self.button_delroi, 13, 1) label = QtGui.QLabel( "Click on a line segment to add a new handle. Right click on a handle to remove." ) # label.setAlignment(Qt.AlignCenter) layout.addWidget(label, 0, 0) self.label_layer = QtGui.QLabel("layer: " + str(self.layer + 1) + "/" + str(len(self.data))) self.label_shape = QtGui.QLabel("shape: " + str(self.arr.shape)) self.label_size = QtGui.QLabel("size: " + str(self.arr.size)) self.label_min = QtGui.QLabel("min: " + str(self.arr.min())) self.label_max = QtGui.QLabel("max: " + str(self.arr.max())) self.label_mean = QtGui.QLabel("mean: " + str(self.arr.mean())) self.label_sd = QtGui.QLabel("sd: " + str(ndimage.mean(self.arr))) self.label_sum = QtGui.QLabel("sum: " + str(ndimage.sum(self.arr))) layout.addWidget(self.label_layer, 3, 1) layout.addWidget(self.label_shape, 4, 1) layout.addWidget(self.label_size, 5, 1) layout.addWidget(self.label_min, 6, 1) layout.addWidget(self.label_max, 7, 1) layout.addWidget(self.label_mean, 8, 1) layout.addWidget(self.label_sd, 9, 1) layout.addWidget(self.label_sum, 10, 1) self.roisSetted = 0 self.label2_roisSetted = QtGui.QLabel("ROI setted: 0") self.label2_shape = QtGui.QLabel() self.label2_size = QtGui.QLabel() self.label2_min = QtGui.QLabel() self.label2_max = QtGui.QLabel() self.label2_mean = QtGui.QLabel() self.label2_sd = QtGui.QLabel() self.label2_sum = QtGui.QLabel() layout.addWidget(self.label2_roisSetted, 14, 1) layout.addWidget(self.label2_shape, 15, 1) layout.addWidget(self.label2_size, 16, 1) layout.addWidget(self.label2_min, 17, 1) layout.addWidget(self.label2_max, 18, 1) layout.addWidget(self.label2_mean, 19, 1) layout.addWidget(self.label2_sd, 20, 1) layout.addWidget(self.label2_sum, 21, 1) self.p1 = pg.PlotWidget() self.p1.setAspectLocked(True, imgScaleFactor) self.p1.addItem(self.img1a) # imv = pg.ImageView(imageItem=img1a) layout.addWidget(self.p1, 1, 0, 10, 1) # self.slider = QtGui.QSlider(QtCore.Qt.Horizontal) self.slider = QtGui.QScrollBar(QtCore.Qt.Horizontal) self.slider.setMinimum(1) self.slider.setMaximum(len(self.data)) self.slider.setValue(self.layer + 1) self.slider.setSingleStep(1) self.slider.setFocus() self.slider.setFocusPolicy(QtCore.Qt.StrongFocus) # self.slider.setTickPosition(QtGui.QSlider.TicksBelow) # self.slider.setTickInterval(5) # self.slider.sliderMoved.connect(self.slider_jump_to) self.slider.valueChanged.connect(self.slider_jump_to) layout.addWidget(self.slider, 11, 0) self.statusBar = MyStatusBar() self.statusBar.setSize(len(self.data)) layout.addWidget(self.statusBar, 12, 0) self.img1b = pg.ImageItem() # self.img1a.scale(self.xscale, self.yscale) # self.img1a.translate(self.xshift, self.yshift) # self.img1b.scale(self.xscale, self.yscale) # self.img1b.translate(self.xshift, self.yshift) if not args.filterROI: self.roi = pg.PolyLineROI([[80, 60], [90, 30], [60, 40]], pen=(6, 9), closed=True) else: self.rois = roi2myroi(self.ROI) if self.rois[self.layer]: self.roi = self.rois[self.layer] else: self.roi = pg.PolyLineROI([[80, 60], [90, 30], [60, 40]], pen=(6, 9), closed=True) # for simplex in hull.simplices: # if self.rois[self.layer]: # self.roi = self.rois[self.layer] self.p2 = pg.PlotWidget() # self.p2.disableAutoRange('xy') self.p2.setAspectLocked(True, imgScaleFactor) self.p2.addItem(self.img1b) # if not args.filterROI: self.p1.addItem(self.roi) self.roi.sigRegionChanged.connect(self.update) layout.addWidget(self.p2, 13, 0, 10, 1)
# elif args.yview: # imv.setImage(dataswappedY, xvals=np.linspace(0, dataswappedY.shape[0], dataswappedY.shape[0] )) # else: # imv.setImage(data, xvals=np.linspace(0, data.shape[0], data.shape[0] )) v1a.addItem(img1a) img1b = pg.ImageItem() v1b.addItem(img1b) # v1a.disableAutoRange('xy') v1a.autoRange() #v1b.autoRange() v1b.disableAutoRange('xy') #rois = [] roi = pg.PolyLineROI([[80, 60], [90, 30], [60, 40]], pen=(6, 9), closed=True) def update(roi): thisroi = roi.getArrayRegion(arr, img1a).astype(int) img1b.setImage(thisroi, levels=(0, arr.max())) print(type(thisroi[0][0])) print("shape: ", thisroi.shape) print("size: ", thisroi.size) print("min: ", thisroi.min()) print("max: ", thisroi.max()) print("mean: ", thisroi.mean()) print("mean: ", ndimage.mean(thisroi)) print("sd: ", ndimage.standard_deviation(thisroi)) print("sum: ", ndimage.sum(thisroi))