Exemple #1
0
    def ImportMedicalImages(self, directory, gui=True):
        patients_groups = dcm.GetDicomGroups(directory)
        name = directory.rpartition('\\')[-1].split('.')
        print("patients: ", patients_groups)

        if len(patients_groups):
            # OPTION 1: DICOM
            group = dcm.SelectLargerDicomGroup(patients_groups)
            matrix, matrix_filename, dicom = self.OpenDicomGroup(group, 0, [0, 0], gui=gui)
            self.CreateDicomProject(dicom, matrix, matrix_filename)
        else:
            # OPTION 2: NIfTI, Analyze or PAR/REC
            if name[-1] == 'gz':
                name[1] = 'nii.gz'

            suptype = ('hdr', 'nii', 'nii.gz', 'par')
            filetype = name[1].lower()

            if filetype in suptype:
                group = oth.ReadOthers(directory)
            else:
                utils.debug("No medical images found on given directory")
                return

            matrix, matrix_filename = self.OpenOtherFiles(group)
            self.CreateOtherProject(str(name[0]), matrix, matrix_filename)
            # OPTION 4: Nothing...

        self.LoadProject()
        Publisher.sendMessage("Enable state project", state=True)
Exemple #2
0
    def _export_surface(self, filename, filetype):
        if filetype in (const.FILETYPE_STL,
                        const.FILETYPE_VTP,
                        const.FILETYPE_PLY,
                        const.FILETYPE_STL_ASCII):
            # First we identify all surfaces that are selected
            # (if any)
            proj = prj.Project()
            polydata_list = []

            for index in proj.surface_dict:
                surface = proj.surface_dict[index]
                if surface.is_shown:
                    polydata_list.append(surface.polydata)

            if len(polydata_list) == 0:
                utl.debug("oops - no polydata")
                return
            elif len(polydata_list) == 1:
                polydata = polydata_list[0]
            else:
                polydata = pu.Merge(polydata_list)

            # Having a polydata that represents all surfaces
            # selected, we write it, according to filetype
            if filetype == const.FILETYPE_STL:
                writer = vtk.vtkSTLWriter()
                writer.SetFileTypeToBinary()
            elif filetype == const.FILETYPE_STL_ASCII:
                writer = vtk.vtkSTLWriter()
                writer.SetFileTypeToASCII()
            elif filetype == const.FILETYPE_VTP:
                writer = vtk.vtkXMLPolyDataWriter()
            #elif filetype == const.FILETYPE_IV:
            #    writer = vtk.vtkIVWriter()
            elif filetype == const.FILETYPE_PLY:
                writer = vtk.vtkPLYWriter()
                writer.SetFileTypeToASCII()
                writer.SetColorModeToOff()
                #writer.SetDataByteOrderToLittleEndian()
                #writer.SetColorModeToUniformCellColor()
                #writer.SetColor(255, 0, 0)

            if filetype in (const.FILETYPE_STL,
                            const.FILETYPE_STL_ASCII,
                            const.FILETYPE_PLY):
                # Invert normals
                normals = vtk.vtkPolyDataNormals()
                normals.SetInputData(polydata)
                normals.SetFeatureAngle(80)
                normals.AutoOrientNormalsOn()
                #  normals.GetOutput().ReleaseDataFlagOn()
                normals.UpdateInformation()
                normals.Update()
                polydata = normals.GetOutput()

            filename = filename.encode(const.FS_ENCODE)
            writer.SetFileName(filename)
            writer.SetInputData(polydata)
            writer.Write()
    def _display_previews(self):
        initial = self.displayed_position * NCOLS
        final = initial + NUM_PREVIEWS
        if len(self.files) < final:
            for i in range(final-len(self.files)):
                try:
                    self.previews[-i-1].Hide()
                except IndexError:
                    utils.debug("doesn't exist!")
            self.nhidden_last_display = final-len(self.files)
        else:
            if self.nhidden_last_display:
                for i in range(self.nhidden_last_display):
                    try:
                        self.previews[-i-1].Show()
                    except IndexError:
                        utils.debug("doesn't exist!")
                self.nhidden_last_display = 0

        for f, p in zip(self.files[initial:final], self.previews):
            p.SetDicomToPreview(f)
            if f.selected:
                self.selected_panel = p
            #p.interactor.Render()

        for f, p in zip(self.files[initial:final], self.previews):
            p.Show()
Exemple #4
0
 def CloseProject(self):
     import invesalius.constants as const
     debug("Session.CloseProject")
     self.project_path = ()
     self.project_status = const.PROJ_CLOSE
     #self.mode = const.MODE_RP
     self.temp_item = False
     self.WriteSessionFile()
Exemple #5
0
 def RemoveActor(self, pubsub_evt):
     utils.debug("RemoveActor")
     actor = pubsub_evt.data
     ren = self.ren
     ren.RemoveActor(actor)
     self.interactor.Render()
     self._to_show_ball -= 1
     self._check_and_set_ball_visibility()
Exemple #6
0
 def SaveProject(self, path=()):
     import invesalius.constants as const
     debug("Session.SaveProject")
     self.project_status = const.PROJ_OPEN
     if path:
         self.project_path = path
         self.__add_to_list(path)
     if self.temp_item:
         self.temp_item = False
     self.WriteSessionFile()
Exemple #7
0
 def CreateProject(self, filename):
     import invesalius.constants as const
     debug("Session.CreateProject")
     Publisher.sendMessage('Begin busy cursor')
     # Set session info
     self.project_path = (self.tempdir, filename)
     self.project_status = const.PROJ_NEW
     self.temp_item = True
     self.WriteSessionFile()
     return self.tempdir
Exemple #8
0
    def SetAcquisitionModality(self, type_=None):
        if type_ is None:
            type_ = self.modality

        if type_ == "MRI":
            self.threshold_modes = self.presets.thresh_mri
        elif type_ == "CT":
            self.threshold_modes = self.presets.thresh_ct
        else:
            debug("Different Acquisition Modality!!!")
        self.modality = type_
Exemple #9
0
    def OpenProject(self, filepath):
        import invesalius.constants as const
        debug("Session.OpenProject")
        # Add item to recent projects list
        item = (path, file) = os.path.split(filepath)
        self.__add_to_list(item)

        # Set session info
        self.project_path = item
        self.project_status = const.PROJ_OPEN
        self.WriteSessionFile()
 def OnRun(self):
     pos = self.slider.GetValue()
     pos += 1
     if not (self.nimages- pos):
         pos = 0
     self.slider.SetValue(pos)
     self.ShowSlice(pos)
     time.sleep(0.2)
     if self.ischecked:
         try:
             wx.Yield()
         #TODO: temporary fix necessary in the Windows XP 64 Bits
         #BUG in wxWidgets http://trac.wxwidgets.org/ticket/10896
         except(wx._core.PyAssertionError):
             utils.debug("wx._core.PyAssertionError")
         finally:
             wx.CallAfter(self.OnRun)
Exemple #11
0
 def ImportMedicalImages(self, directory):
     # OPTION 1: DICOM?
     patients_groups = dcm.GetDicomGroups(directory)
     if len(patients_groups):
         group = dcm.SelectLargerDicomGroup(patients_groups)
         matrix, matrix_filename, dicom = self.OpenDicomGroup(group, 0, [0,0],gui=True)
         self.CreateDicomProject(dicom, matrix, matrix_filename)
     # OPTION 2: ANALYZE?
     else:
         imagedata = analyze.ReadDirectory(directory)
         if imagedata:
             self.CreateAnalyzeProject(imagedata)
         # OPTION 3: Nothing...
         else:
             utils.debug("No medical images found on given directory")
             return
     self.LoadProject()
     Publisher.sendMessage("Enable state project", True)
Exemple #12
0
    def ShowDialogCloseProject(self):
        session = ses.Session()
        st = session.project_status
        print('Status', st, type(st))
        if st == const.PROJ_CLOSE:
            return -1
        try:
            filename = session.project_path[1]
        except(AttributeError):
            utils.debug("Project doesn't exist")
            filename = None

        if (filename):
            if (st == const.PROJ_NEW) or (st == const.PROJ_CHANGE):
                answer = dialog.SaveChangesDialog(filename, self.frame)
                if not answer:
                    utils.debug("Close without changes")
                    self.CloseProject()
                    Publisher.sendMessage("Enable state project", state=False)
                    Publisher.sendMessage('Set project name')
                    Publisher.sendMessage("Stop Config Recording")
                elif answer == 1:
                    self.ShowDialogSaveProject()
                    utils.debug("Save changes and close")
                    self.CloseProject()
                    Publisher.sendMessage("Enable state project", state=False)
                    Publisher.sendMessage('Set project name')
                    Publisher.sendMessage("Stop Config Recording")
                elif answer == -1:
                    utils.debug("Cancel")
            else:
                self.CloseProject()
                Publisher.sendMessage("Enable state project", state=False)
                Publisher.sendMessage('Set project name')
                Publisher.sendMessage("Stop Config Recording")

        else:
            Publisher.sendMessage('Stop Config Recording')
    def Update(self):
        # Ideally, AddFile would be sufficient for splitting DICOM
        # files into groups (series). However, this does not work for
        # acquisitions / equipments and manufacturers.

        # Although DICOM is a protocol, each one uses its fields in a
        # different manner

        # Check if Problem 1 occurs (n groups with 1 slice each)
        is_there_problem_1 = False
        utils.debug("n slice %d" % self.nslices)
        utils.debug("len %d" % len(self.groups_dict))
        if (self.nslices == len(self.groups_dict)) and\
                (self.nslices > 1):
            is_there_problem_1 = True

        # Fix Problem 1
        if is_there_problem_1:
            utils.debug("Problem1")
            self.groups_dict = self.FixProblem1(self.groups_dict)
Exemple #14
0
def print_events(data):
    """
    Print pubsub messages
    """
    utils.debug(data.topic)
Exemple #15
0
 def ChangeProject(self):
     import invesalius.constants as const
     debug("Session.ChangeProject")
     self.project_status = const.PROJ_CHANGE
Exemple #16
0
def print_events(topic=Publisher.AUTO_TOPIC, **msg_data):
    """
    Print pubsub messages
    """
    utils.debug("%s\n\tParameters: %s" % (topic, msg_data))
 def SetDicomDirectory(self, directory):
     utils.debug("Setting Dicom Directory %s" % directory)
     self.directory = directory
     self.series = dicom_reader.GetSeries(directory)[0]
Exemple #18
0
 def RemoveAllActor(self, pubsub_evt):
     utils.debug("RemoveAllActor")
     self.ren.RemoveAllProps()
     Publisher.sendMessage('Render volume viewer')
Exemple #19
0
    def OpenDicomGroup(self, dicom_group, interval, file_range, gui=True):
        # Retrieve general DICOM headers
        dicom = dicom_group.GetDicomSample()

        # Create imagedata
        interval += 1
        filelist = dicom_group.GetFilenameList()[::interval]
        if not filelist:
            utils.debug("Not used the IPPSorter")
            filelist = [i.image.file for i in dicom_group.GetHandSortedList()[::interval]]
        
        if file_range is not None and file_range[0] is not None and file_range[1] > file_range[0]:
            filelist = filelist[file_range[0]:file_range[1] + 1]

        zspacing = dicom_group.zspacing * interval

        size = dicom.image.size
        bits = dicom.image.bits_allocad
        sop_class_uid = dicom.acquisition.sop_class_uid
        xyspacing = dicom.image.spacing
        orientation = dicom.image.orientation_label

        wl = float(dicom.image.level)
        ww = float(dicom.image.window)

        if sop_class_uid == '1.2.840.10008.5.1.4.1.1.7': #Secondary Capture Image Storage
            use_dcmspacing = 1
        else:
            use_dcmspacing = 0

        imagedata = None

        if dicom.image.number_of_frames == 1:
            sx, sy = size
            n_slices = len(filelist)
            resolution_percentage = utils.calculate_resizing_tofitmemory(int(sx), int(sy), n_slices, bits/8)

            if resolution_percentage < 1.0 and gui:
                re_dialog = dialog.ResizeImageDialog()
                re_dialog.SetValue(int(resolution_percentage*100))
                re_dialog_value = re_dialog.ShowModal()
                re_dialog.Close() 

                if re_dialog_value == wx.ID_OK:
                    percentage = re_dialog.GetValue()
                    resolution_percentage = percentage / 100.0
                else:
                    return

            xyspacing = xyspacing[0] / resolution_percentage, xyspacing[1] / resolution_percentage

            self.matrix, scalar_range, self.filename = image_utils.dcm2memmap(filelist, size,
                                                                        orientation, resolution_percentage)

            print(xyspacing, zspacing)
            if orientation == 'AXIAL':
                spacing = xyspacing[0], xyspacing[1], zspacing
            elif orientation == 'CORONAL':
                spacing = xyspacing[0], zspacing, xyspacing[1]
            elif orientation == 'SAGITTAL':
                spacing = zspacing, xyspacing[1], xyspacing[0]
        else:
            self.matrix, spacing, scalar_range, self.filename = image_utils.dcmmf2memmap(filelist[0], orientation)

        self.Slice = sl.Slice()
        self.Slice.matrix = self.matrix
        self.Slice.matrix_filename = self.filename

        self.Slice.spacing = spacing

        # 1(a): Fix gantry tilt, if any
        tilt_value = dicom.acquisition.tilt
        if (tilt_value) and (gui):
            # Tell user gantry tilt and fix, according to answer
            message = _("Fix gantry tilt applying the degrees below")
            value = -1*tilt_value
            tilt_value = dialog.ShowNumberDialog(message, value)
            image_utils.FixGantryTilt(self.matrix, self.Slice.spacing, tilt_value)
        elif (tilt_value) and not (gui):
            tilt_value = -1*tilt_value
            image_utils.FixGantryTilt(self.matrix, self.Slice.spacing, tilt_value)

        self.Slice.window_level = wl
        self.Slice.window_width = ww

        scalar_range = int(self.matrix.min()), int(self.matrix.max())

        Publisher.sendMessage('Update threshold limits list',
                              threshold_range=scalar_range)

        return self.matrix, self.filename, dicom
 def CancelImageDataLoad(self, evt_pusub):
     utils.debug("Canceling")
     self.running = False
    def CreateImageData(self, filelist, zspacing, size, bits):
        message = _("Generating multiplanar visualization...")

        if not const.VTK_WARNING:
            log_path = os.path.join(const.USER_LOG_DIR, 'vtkoutput.txt')
            fow = vtk.vtkFileOutputWindow()
            fow.SetFileName(log_path)
            ow = vtk.vtkOutputWindow()
            ow.SetInstance(fow)

        x,y = size
        px, py = utils.predict_memory(len(filelist), x, y, bits)
        utils.debug("Image Resized to >>> %f x %f" % (px, py))

        if (x == px) and (y == py):
            const.REDUCE_IMAGEDATA_QUALITY = 0
        else:
            const.REDUCE_IMAGEDATA_QUALITY = 1

        if not(const.REDUCE_IMAGEDATA_QUALITY):
            update_progress= vtk_utils.ShowProgress(1, dialog_type = "ProgressDialog")

            array = vtk.vtkStringArray()
            for x in range(len(filelist)):
                if not self.running:
                    return False
                array.InsertValue(x,filelist[x])

            if not self.running:
                return False
            reader = vtkgdcm.vtkGDCMImageReader()
            reader.SetFileNames(array)
            reader.AddObserver("ProgressEvent", lambda obj,evt:
                         update_progress(reader,message))
            reader.Update()

            if not self.running:
                reader.AbortExecuteOn()
                return False
            # The zpacing is a DicomGroup property, so we need to set it
            imagedata = vtk.vtkImageData()
            imagedata.DeepCopy(reader.GetOutput())
            spacing = imagedata.GetSpacing()
            imagedata.SetSpacing(spacing[0], spacing[1], zspacing)
        else:

            update_progress= vtk_utils.ShowProgress(2*len(filelist),
                                                dialog_type = "ProgressDialog")

            # Reformat each slice and future append them
            appender = vtk.vtkImageAppend()
            appender.SetAppendAxis(2) #Define Stack in Z


            # Reformat each slice
            for x in range(len(filelist)):
                # TODO: We need to check this automatically according
                # to each computer's architecture
                # If the resolution of the matrix is too large
                if not self.running:
                    return False
                reader = vtkgdcm.vtkGDCMImageReader()
                reader.SetFileName(filelist[x])
                reader.AddObserver("ProgressEvent", lambda obj,evt:
                             update_progress(reader,message))
                reader.Update()

                #Resample image in x,y dimension
                slice_imagedata = ResampleImage2D(reader.GetOutput(), px, py, update_progress)
                #Stack images in Z axes
                appender.AddInput(slice_imagedata)
                #appender.AddObserver("ProgressEvent", lambda obj,evt:update_progress(appender))
                appender.Update()

            # The zpacing is a DicomGroup property, so we need to set it
            if not self.running:
                return False
            imagedata = vtk.vtkImageData()
            imagedata.DeepCopy(appender.GetOutput())
            spacing = imagedata.GetSpacing()

            imagedata.SetSpacing(spacing[0], spacing[1], zspacing)

        imagedata.AddObserver("ProgressEvent", lambda obj,evt:
                     update_progress(imagedata,message))
        imagedata.Update()

        return imagedata
Exemple #22
0
 def ChangeProject(self):
     import invesalius.constants as const
     debug("Session.ChangeProject")
     self.project_status = const.PROJ_CHANGE