def initGUI(self): QtGui.QMainWindow.__init__(self) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.setWindowTitle("Simple Dicom Viewer") #self.dicomReader = vtk.vtkDICOMImageReader() #self.dicomReader = vtkgdcm.vtkGDCMImageReader() self.show() self.figure = plt.figure() self.canvas = FigureCanvas(self.figure) self.toolbar = NavigationToolbar(self.canvas, self) self.ui.numpyLayout.addWidget(self.toolbar) self.ui.numpyLayout.addWidget(self.canvas) self.vtkWidget = QVTKRenderWindowInteractor(self.ui.imageFrame) self.vtkWidget.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) #self.ui.imageLayout.removeWidget(self.ui.dicomSlider) self.ui.imageLayout.addWidget(self.vtkWidget) #self.ui.imageLayout.addWidget(self.ui.dicomSlider) self.disableSlider() self.viewer= vtk.vtkImageViewer() #self.viewer.SetupInteractor(MyInteractor()) self.vtkWidget.GetRenderWindow().AddRenderer(self.viewer.GetRenderer()) self.iren = self.vtkWidget.GetRenderWindow().GetInteractor() #self.iren.SetRenderWindow(self.vtkWidget.GetRenderWindow()) self.drag = False self.measuring = False self.iren.AddObserver("LeftButtonPressEvent", self.leftClick) self.iren.AddObserver("LeftButtonReleaseEvent", self.leftRelease) self.iren.AddObserver("EnterEvent", self.mouseEntered) self.iren.AddObserver("LeaveEvent", self.mouseLeft) self.iren.AddObserver("MouseMoveEvent", self.mouseMoved)
class AppWindow(QtGui.QMainWindow): def __init__(self, parent): self.parent = parent self.queue = Queue.Queue() self.processThread = ProcessingThread(self.queue) #self.processThread = threading.Thread(target=self.consumer.run()) self.processThread.start() self.fileLoader = DicomLoader(self, "file") self.folderLoader = DicomLoader(self, "series") self.importSrc() self.initGUI() self.initToolbar() self.initConnections() def importSrc(self): # will be shown as errors in pyCharm pass def exit(self): self.close() def initConnections(self): self.connect(self.ui.actionLoad, QtCore.SIGNAL("triggered()"), self.loadSingleFile) self.connect(self.ui.actionExit, QtCore.SIGNAL("triggered()"), self.exit) def initGUI(self): QtGui.QMainWindow.__init__(self) self.ui = Ui_MainWindow() self.ui.setupUi(self) self.setWindowTitle("Simple Dicom Viewer") #self.dicomReader = vtk.vtkDICOMImageReader() #self.dicomReader = vtkgdcm.vtkGDCMImageReader() self.show() self.figure = plt.figure() self.canvas = FigureCanvas(self.figure) self.toolbar = NavigationToolbar(self.canvas, self) self.ui.numpyLayout.addWidget(self.toolbar) self.ui.numpyLayout.addWidget(self.canvas) self.vtkWidget = QVTKRenderWindowInteractor(self.ui.imageFrame) self.vtkWidget.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding) #self.ui.imageLayout.removeWidget(self.ui.dicomSlider) self.ui.imageLayout.addWidget(self.vtkWidget) #self.ui.imageLayout.addWidget(self.ui.dicomSlider) self.disableSlider() self.viewer= vtk.vtkImageViewer() #self.viewer.SetupInteractor(MyInteractor()) self.vtkWidget.GetRenderWindow().AddRenderer(self.viewer.GetRenderer()) self.iren = self.vtkWidget.GetRenderWindow().GetInteractor() #self.iren.SetRenderWindow(self.vtkWidget.GetRenderWindow()) self.drag = False self.measuring = False self.iren.AddObserver("LeftButtonPressEvent", self.leftClick) self.iren.AddObserver("LeftButtonReleaseEvent", self.leftRelease) self.iren.AddObserver("EnterEvent", self.mouseEntered) self.iren.AddObserver("LeaveEvent", self.mouseLeft) self.iren.AddObserver("MouseMoveEvent", self.mouseMoved) def mouseMoved(self, *args): if self.drag: self.temp = args[0].GetEventPosition() print(self.temp) print(self.begin) self.drawLine([self.begin, self.temp]) return time.sleep(0.1) #print(args[0].GetEventPosition()) def mouseEntered(self, *args): self.drag = False print("Entered") def mouseLeft(self, *args): self.drag = False print("Left") def leftClick(self, *args): if self.measuring: if self.drag == False: self.drag = True self.begin = args[0].GetEventPosition() print(self.begin) print(self.drag) else: self.drag = False self.end = args[0].GetEventPosition() self.drawLine([self.begin, self.end]) self.printDistance(self.dist) def leftRelease(self, *args): #self.drag = False #print(self.drag) pass def printDistance(self, dist): box = QtGui.QMessageBox(self) box.setInformativeText("Distance: " + str(dist) + " cm.") box.show() def initToolbar(self): self.actions = Actions(self) def drawLine(self, points): try: self.viewer.GetRenderer().RemoveActor(self.actor) self.viewer.GetRenderer().Render() except: pass point1 = points[0] point2 = points[1] points = vtk.vtkPoints() points.SetNumberOfPoints(2) points.Allocate(2) points.InsertPoint(0, point1[0], point1[1], 0.001) points.InsertPoint(1, point2[0], point2[1], 0.001) dist = numpy.sqrt(numpy.square((point1[0]-point2[0])*0.028) + numpy.square((point1[1]-point2[1])*0.030)) self.cells = vtk.vtkCellArray() self.cells.Initialize() line = vtk.vtkLine() line.GetPointIds().SetId(0,0) line.GetPointIds().SetId(1,1) self.cells.InsertNextCell(line) self.poly = vtk.vtkPolyData() self.poly.Initialize() self.poly.SetPoints(points) self.poly.SetLines(self.cells) self.poly.Modified() mapper = vtk.vtkPolyDataMapper2D() #print(dir(mapper)) mapper.SetInput(self.poly) mapper.ScalarVisibilityOn() mapper.SetScalarModeToUsePointData() mapper.Update() self.actor = vtk.vtkActor2D() self.actor.SetMapper(mapper) self.viewer.GetRenderer().AddActor2D(self.actor) self.dist = dist def loadSingleFile(self): loader = self.fileLoader loader.loadFile() if loader.accepted: loader.setDir(os.path.dirname(str(loader.selectedFile))) self.disableSlider() self.dicomReader = vtkgdcm.vtkGDCMImageReader() self.dicomReader.SetFileName(str(loader.selectedFile)) print(dir(self.dicomReader)) print(self.dicomReader.GetScale()) self.dicomReader.Update() imageData = self.dicomReader.GetOutput() size = imageData.GetDimensions() width = size[0] height = size[1] self.vtkWidget.setMaximumSize(QtCore.QSize(width, height)) self.vtkWidget.setMinimumSize(QtCore.QSize(width, height)) RefDs = dicom.read_file(str(loader.selectedFile)) ConstPixelDims = (int(RefDs.Rows), int(RefDs.Columns), 1) pointData = imageData.GetPointData() arrayData = pointData.GetArray(0) arrayDicom = numpy_support.vtk_to_numpy(arrayData) arrayDicom = arrayDicom.reshape(ConstPixelDims, order='F') shape = arrayDicom.shape wtf = arrayDicom.reshape(shape[0], shape[1]) wtf = numpy.fliplr(wtf).transpose() max = numpy.max(wtf) min = numpy.min(wtf) print(numpy.max(wtf)) print(numpy.min(wtf)) grad = numpy.gradient(wtf) print(wtf) computed = numpy.sqrt(numpy.square(grad[0]) + numpy.square(grad[1])) #self.proc.start() ax = self.figure.add_subplot(111) ax.imshow(wtf, interpolation="nearest", cmap=plt.get_cmap('gray'), vmin=0, vmax=max) self.canvas.draw() #points = vtk.vtkPoints() #points.SetNumberOfPoints(2) #points.Allocate(2) #points.InsertPoint(0, 100, 100, 0.001) #points.InsertPoint(0, 200, 200, 0.001) #cells = vtk.vtkCellArray() #cells.Initialize() #line = vtk.vtkLine() #line.GetPointIds().SetId(0,0) #line.GetPointIds().SetId(1,1) #cells.InsertNextCell(line) #poly = vtk.vtkPolyData() #poly.Initialize() #poly.SetPoints(points) #poly.SetLines(cells) #poly.Modified() #mapper = vtk.vtkPolyDataMapper2D() #print(dir(mapper)) #mapper.SetInput(poly) #mapper.ScalarVisibilityOn() #mapper.SetScalarModeToUsePointData() #mapper.Update() #self.drawLine([(200,200), (300,300)]) #actor = vtk.vtkActor2D() #actor.SetMapper(mapper) blend = vtk.vtkImageBlend() blend.AddInputConnection(self.dicomReader.GetOutputPort()) #blend.AddInputConnection(actor.GetOutputPort()) self.viewer.SetInputConnection(blend.GetOutputPort()) #print(dir(self.viewer.GetRenderer())) #self.viewer.GetRenderer().AddActor2D(actor) #self.viewer.SetInputConnection(self.dicomReader.GetOutputPort()) self.viewer.SetZSlice(0) self.getMedicalData() self.iren.ReInitialize() self.iren.Render() self.iren.Start() #actor = vtk.vtkImageActor() #self.viewer.GetRenderer().AddActor(actor) self.viewer.GetRenderer().Render() def getMedicalData(self): #print(self.dicomReader) splitter = "Medical Image Properties:" data = str(self.dicomReader).split(splitter) data = [x.strip() for x in data] data = data[1].split('\n') data = [x.split(":") for x in data if x] self.ui.dicomData.setRowCount(len(data)) self.ui.dicomData.setColumnCount(1) self.ui.dicomData.setHorizontalHeaderItem(0, QtGui.QTableWidgetItem("Data")) for i in xrange(0, len(data)): self.ui.dicomData.setVerticalHeaderItem(i, QtGui.QTableWidgetItem((data[i][0]))) self.ui.dicomData.setItem(i, 0, QtGui.QTableWidgetItem((data[i][1]))) self.ui.dicomData.horizontalHeader().setResizeMode(QtGui.QHeaderView.Stretch) self.ui.dicomData.setSortingEnabled(False) #print(data) def disableSlider(self): self.ui.playButton.setDisabled(True) self.ui.dicomSlider.setDisabled(True) self.ui.dicomSlider.setValue(0) self.ui.dicomSlider.disconnect(self.ui.dicomSlider, QtCore.SIGNAL("valueChanged(int)"), self.sliderMoved) self.ui.playButton.disconnect(self.ui.playButton, QtCore.SIGNAL("clicked()"), self.playMovie) @QtCore.pyqtSlot(int) def sliderMoved(self, value): try: self.viewer.SetZSlice(value) self.iren.Render() except: raise ValueError @QtCore.pyqtSlot(int) def movieStep(self, value): self.ui.dicomSlider.setValue(value) self.ui.dicomSlider.setSliderDown(value) self.viewer.SetZSlice(value) self.iren.Render() @QtCore.pyqtSlot() def playMovie(self): self.ui.dicomSlider.disconnect(self.ui.dicomSlider, QtCore.SIGNAL("valueChanged(int)"), self.sliderMoved) self.viewer.SetZSlice(0) self.obj = Waiter() self.obj.trigger.connect(self.movieStep) self.obj.ended.connect(self.movieEnded) thr = ThreadWait(self.obj, self.ui.dicomSlider.maximum()) self.queue.put((self.processThread.playMovie, thr, )) @QtCore.pyqtSlot() def movieEnded(self): self.ui.dicomSlider.connect(self.ui.dicomSlider, QtCore.SIGNAL("valueChanged(int)"), self.sliderMoved) def enableSlider(self, max): self.disableSlider() self.ui.playButton.setEnabled(True) self.ui.dicomSlider.setTracking(True) self.ui.dicomSlider.setEnabled(True) self.ui.dicomSlider.setValue(0) self.ui.dicomSlider.setMinimum(0) self.ui.dicomSlider.setMaximum(max) self.ui.dicomSlider.connect(self.ui.dicomSlider, QtCore.SIGNAL("valueChanged(int)"), self.sliderMoved) self.ui.playButton.connect(self.ui.playButton, QtCore.SIGNAL("clicked()"), self.playMovie) def loadFolder(self): loader = self.folderLoader loader.loadFile() if loader.accepted: loader.setDir(os.path.dirname(str(loader.selectedFolder))) self.dicomReader = vtkgdcm.vtkGDCMImageReader() regex = re.compile(r'.+\.dcm') files = [x for x in os.listdir(loader.selectedFolder) if re.match(regex, x)] self.seriesSize = len(files) temp = vtk.vtkStringArray() temp.SetNumberOfValues(len(files)) i = 0 for file in sorted(files): temp.SetValue(i, os.path.join(str(loader.selectedFolder), file)) i = i + 1 self.dicomReader.SetFileNames(temp) self.dicomReader.Update() imageData = self.dicomReader.GetOutput() size = imageData.GetDimensions() width = size[0] height = size[1] self.vtkWidget.setMaximumSize(QtCore.QSize(width, height)) self.vtkWidget.setMinimumSize(QtCore.QSize(width, height)) self.viewer.SetInputConnection(self.dicomReader.GetOutputPort()) self.iren.ReInitialize() self.getMedicalData() self.enableSlider(self.seriesSize-1) self.ui.dicomSlider.setFocus() def undo(self): print("Undo") def redo(self): print("Redo") def magnify(self): print("Magnify") def cut(self): print("Cut") def measure(self): self.measuring = not self.measuring