def test_show_draw_and_pickup_segmentation_label(self): """ just run editor to see what is new Returns: """ app = QApplication(sys.argv) data = (np.random.rand(30, 31, 32) * 100).astype(np.int) data[15:40, 13:20, 10:18] += 50 segmentation = np.zeros_like(data) segmentation[15:40, 13:20, 10:18] = 1 se = seededitorqt.QTSeedEditor(data, contours=segmentation) se.selectSlice(20) se.slice_box.seed_mark = 3 # seed 3 se.slice_box.last_position = [1, 3] se.slice_box.drawSeeds([10, 5]) se.slice_box.seed_mark = 2 # left mouse button se.slice_box.last_position = [8, 1] se.slice_box.drawSeeds([7, 5]) # try to pick up seed from slice se.slice_box._pick_up_segmentation_label([16, 16]) # self.assertEqual(se.textFocusedSeedLabel, "3", "Pickuped value") idx = se.combo_segmentation_label.currentIndex() logger.debug("idx {}".format(idx)) self.assertEqual(idx, 1, "Picked up value") se.change_focus_segmentation_label(0) idx = se.combo_segmentation_label.currentIndex() logger.debug("idx {}".format(idx)) self.assertEqual(idx, 0, "Changed value")
def test_devel_vein_basin_segmentation(self): pth = r"E:\data\medical\processed\mik2018 para\P09_paraall_cropped.pklz" datap = io3d.read(pth) labels = { "1": 1, "2": 2, "3": 3, "4": 4, "5": 5, "6": 6, } from PyQt4.QtGui import QApplication, QPushButton app = QApplication(sys.argv) import seededitorqt se = seededitorqt.QTSeedEditor(datap["data3d"], contours=datap["segmentation"]) def split(obj): import lisa.virtual_resection as vr print(np.max(datap["data3d"])) print(np.unique(se.seeds)) out, sepobj = vr.split_vessel(datap, se.seeds, method="separate labels", input_seeds_label2=2) print(np.unique(out)) se.seeds = out se.contours = out se.setView(se.actual_view) qpb = QPushButton("Ahoj") qpb.clicked.connect(split) wg = se.my_layout.layout().itemAt(0).itemAt(2).addWidget(qpb) se.exec_()
def test_show_editor_with_seeds(self): """ just run editor to see what is new Returns: """ img, segm, seeds = self.make_data() app = QApplication(sys.argv) se = seededitorqt.QTSeedEditor(img, seeds=seeds) # se.exec_() assert np.max(se.seeds) > 0
def test_show_editor_with_too_much_wide_data(self): """ just run editor to see what is new Returns: """ app = QApplication(sys.argv) data = (np.random.rand(30, 31, 150) * 100).astype(np.int) data[15:40, 13:20, 10:18] += 50 se = seededitorqt.QTSeedEditor(data) se.exec_()
def test_addplugin(self): """ just run editor to see what is new Returns: """ app = QApplication(sys.argv) data = (np.random.rand(30, 31, 32) * 100).astype(np.int) data[15:40, 13:20, 10:18] += 50 se = seededitorqt.QTSeedEditor(data) wg0 = seededitorqt.plugin.SampleThresholdPlugin() se.addPlugin(wg0)
def test_draw_seed_function(self): """ just run editor to see what is new Returns: """ app = QApplication(sys.argv) data = (np.random.rand(30, 31, 32) * 100).astype(np.int) data[15:40, 13:20, 10:18] += 50 se = seededitorqt.QTSeedEditor(data) se.slice_box.seed_mark = 1 # left mouse button se.slice_box.last_position = [1, 3] se.slice_box.drawSeeds([10, 5]) se.slice_box.seed_mark = 2 # left mouse button se.slice_box.last_position = [8, 1] se.slice_box.drawSeeds([7, 5])
def test_show_editor_with_seeds_custom_colors(self): """ just run editor to see what is new Returns: """ img, segm, seeds = self.make_data() app = QApplication(sys.argv) seeds_colortable = seededitorqt.seed_editor_qt.SEEDS_COLORTABLE.copy() # BGRA seeds_colortable[0] = [255, 0, 0, 64] seeds_colortable[1] = [0, 255, 0, 64] seeds_colortable[2] = [0, 0, 255, 64] seeds_colortable[3] = [0, 255, 255, 64] seeds_colortable[4] = [255, 0, 255, 64] seeds_colortable[5] = [255, 255, 0, 64] se = seededitorqt.QTSeedEditor(img, seeds=seeds, contours=segm.astype(np.uint8), seeds_colortable=seeds_colortable) # se.exec_() assert se.slice_box.seeds_colortable[1][1] == 255 assert np.max(se.seeds) > 0
def test_show_draw_and_pickup_seed(self): """ just run editor to see what is new Returns: """ app = QApplication(sys.argv) data = (np.random.rand(30, 31, 32) * 100).astype(np.int) data[15:40, 13:20, 10:18] += 50 se = seededitorqt.QTSeedEditor(data) se.slice_box.seed_mark = 3 # seed 3 se.slice_box.last_position = [1, 3] se.slice_box.drawSeeds([10, 5]) se.slice_box.seed_mark = 2 # left mouse button se.slice_box.last_position = [8, 1] se.slice_box.drawSeeds([7, 5]) # try to pick up seed from slice se.slice_box._pick_up_seed_label([1, 3]) self.assertEqual(se.textFocusedSeedLabel, "3", "Pickuped value") se.change_focus_seed_label(2) self.assertEqual(se.textFocusedSeedLabel, "2", "Changed value")
def vesselSegmentation(data, segmentation=-1, threshold=None, voxelsize_mm=[1, 1, 1], inputSigma=-1, aoi_dilation_iterations=0, aoi_dilation_structure=None, nObj=10, biggestObjects=False, useSeedsOfCompactObjects=False, seeds=None, interactivity=True, binaryClosingIterations=2, binaryOpeningIterations=0, smartInitBinaryOperations=False, returnThreshold=False, binaryOutput=True, returnUsedData=False, qapp=None, auto_method='', aoi_label=1, forbidden_label=None, slab=None, old_gui=False, debug=False): """ Vessel segmentation z jater. Input: :param data: - CT (nebo MRI) 3D data :param segmentation: - zakladni oblast pro segmentaci, oznacena struktura se :param stejnymi: rozmery jako "data", kde je oznaceni (label) jako: 1 jatra, -1 zajimava tkan (kosti, ...) 0 jinde :param threshold: - prah :param voxelsize_mm: - (vektor o hodnote 3) rozmery jednoho voxelu :param inputSigma: - pocatecni hodnota pro prahovani :param aoi_dilation_iterations: - pocet operaci dilation nad zakladni oblasti pro segmentaci ("segmantation") :param aoi_dilation_structure: - struktura pro operaci dilation :param nObj: - oznacuje, kolik nejvetsich objektu se ma vyhledat - pokud je rovno 0 (nule), vraci cela data :param biggestObjects: - moznost, zda se maji vracet nejvetsi objekty nebo ne :param seeds: - moznost zadat pocatecni body segmentace na vstupu. Je to matice o rozmerech jako data. Vsude nuly, tam kde je oznaceni jsou jednicky It can be same shape like data, or it can be indexes e.g. from np.nonzero(seeds) :param interactivity: - nastavi, zda ma nebo nema byt pouzit interaktivni mod upravy dat :param binaryClosingIterations: - vstupni binary closing operations :param binaryOpeningIterations: - vstupni binary opening operations :param smartInitBinaryOperations: - logicka hodnota pro smart volbu pocatecnich hodnot binarnich operaci (bin. uzavreni a bin. otevreni) :param returnThreshold: - jako druhy parametr funkce vrati posledni hodnotu prahu :param binaryOutput: - zda ma byt vystup vracen binarne nebo ne (binarnim vystupem se rozumi: cokoliv jineho nez hodnota 0 je hodnota 1) :param returnUsedData: - vrati pouzita data :param aoi_label: label of organ where is the target vessel :param forbidden_label: int or list of ints. Labels of areas which are not used for segmentation. Output: filtrovana data """ # self.qapp = qapp dim = numpy.ndim(data) logger.debug('Dimenze vstupnich dat: ' + str(dim)) if (dim < 2) or (dim > 3): logger.debug('Nepodporovana dimenze dat!') logger.debug('Ukonceni funkce!') return None if seeds is None: logger.debug('Funkce spustena bez prioritnich objektu!') if biggestObjects: logger.debug( 'Funkce spustena s vracenim nejvetsich objektu => nebude mozne\ vybrat prioritni objekty!') if (nObj < 1): nObj = 1 if biggestObjects: logger.debug('Vybrano objektu k vraceni: ' + str(nObj)) logger.debug('Pripravuji data...') voxel = numpy.array(voxelsize_mm) # Kalkulace objemove jednotky (voxel) (V = a*b*c). voxel1 = voxel[0] # [0] voxel2 = voxel[1] # [0] voxel3 = voxel[2] # [0] voxelV = voxel1 * voxel2 * voxel3 # number je zaokrohleny 2x nasobek objemove jednotky na 2 desetinna mista. # number stanovi doporucenou horni hranici parametru gauss. filtru. number = (numpy.round((2 * voxelV**(1.0 / 3.0)), 2)) if aoi_label is None: target_organ_segmentation = np.ones(segmentation.shape) else: target_organ_segmentation = image_manipulation.select_labels( segmentation, aoi_label, slab) # Operace dilatace (dilation) nad samotnymi jatry ("segmentation"). if (aoi_dilation_iterations > 0.0): target_organ_segmentation = scipy.ndimage.binary_dilation( input=target_organ_segmentation, structure=aoi_dilation_structure, iterations=aoi_dilation_iterations) # remove forbidden areas from segmentation if forbidden_label is not None: forbidden_organ_segmentation = image_manipulation.select_labels( segmentation, forbidden_label, slab) target_organ_segmentation[forbidden_organ_segmentation] = 0 del (forbidden_organ_segmentation) # Ziskani datove oblasti jater (bud pouze jater nebo i jejich okoli - # zalezi, jakym zpusobem bylo nalozeno s operaci dilatace dat). preparedData = (data * (target_organ_segmentation)) # .astype(numpy.float) logger.debug('Typ vstupnich dat: ' + str(preparedData.dtype)) # if preparedData.dtype != numpy.uint8: # print 'Data nejsou typu numpy.uint8 => muze dojit k errorum' if not numpy.can_cast(preparedData.dtype, numpy.float): logger.debug( 'ERROR: (debug message) Data nejsou takoveho typu, aby se daly \ prevest na typ "numpy.float" => muze dojit k errorum') logger.debug('Ukoncuji funkci!') raise ValueError("Cannot cast input data to numpy.float") return None if (preparedData == False).all(): logger.debug( 'ERROR: (debug message) Jsou spatna data nebo segmentacni matice: \ all is true == data is all false == bad segmentation matrix (if data matrix is \ ok)') logger.debug('Ukoncuji funkci!') raise ValueError( "Wrong input data. All is true == data is all false == bad segmentation matrix (if data matrix is ok)" ) return None # del(data) # del(segmentation) # Nastaveni rozmazani a prahovani dat. if (inputSigma == -1): inputSigma = number if (inputSigma > number): inputSigma = number # seeds = None if biggestObjects == False and\ seeds is None and interactivity == True and threshold is None: if old_gui: logger.debug(( 'Nyni si levym nebo pravym tlacitkem mysi (klepnutim nebo tazenim)\ oznacte specificke oblasti k vraceni.')) import sed3 pyed = sed3.sed3qt(preparedData, contour=segmentation, windowW=400, windowC=50) # pyed.show() pyed.exec_() # from PyQt4.QtCore import pyqtRemoveInputHook # pyqtRemoveInputHook() # import ipdb; ipdb.set_trace() # noqa BREAKPOINT seeds = pyed.seeds # Zkontrolovat, jestli uzivatel neco vybral - nejaky item musi byt # ruzny od nuly. if (seeds != 0).any() == False: seeds = None logger.debug( 'Zadne seedy nezvoleny => nejsou prioritni objekty.') else: # seeds * (seeds != 0) ## seeds je n-tice poli indexu nenulovych # prvku => item krychle je == krychle[ seeds[0][x], seeds[1][x], # seeds[2][x] ] seeds = seeds.nonzero() logger.debug('Seedu bez nul: ' + str(len(seeds[0]))) closing = binaryClosingIterations opening = binaryOpeningIterations if (smartInitBinaryOperations and interactivity): if (seeds == None): # noqa closing = 5 opening = 1 else: closing = 2 opening = 0 # Samotne filtrovani if interactivity: if old_gui: uiT = uiThreshold.uiThresholdQt( preparedData, voxel=voxel, threshold=threshold, interactivity=interactivity, number=number, inputSigma=inputSigma, nObj=nObj, biggestObjects=biggestObjects, useSeedsOfCompactObjects=useSeedsOfCompactObjects, binaryClosingIterations=closing, binaryOpeningIterations=opening, seeds=seeds, threshold_auto_method=auto_method, ) output = uiT.run() else: # TODO use all parameters import seededitorqt se = seededitorqt.QTSeedEditor(preparedData, voxelSize=voxel) import imtools.threshold_qsed_plugin wg0 = imtools.threshold_qsed_plugin.QtSEdThresholdPlugin( nObj=nObj, debug=debug) se.addPlugin(wg0) se.exec_() output = se.getContours() else: uiT = uiThreshold.uiThreshold( preparedData, voxel=voxel, threshold=threshold, interactivity=interactivity, number=number, inputSigma=inputSigma, nObj=nObj, biggestObjects=biggestObjects, useSeedsOfCompactObjects=useSeedsOfCompactObjects, binaryClosingIterations=closing, binaryOpeningIterations=opening, seeds=seeds, threshold_auto_method=auto_method, ) output = uiT.run() # Vypocet binarni matice. if output is None: # noqa logger.debug('Zadna data k vraceni! (output == None)') elif binaryOutput: output[output != 0] = 1 # Vraceni matice. if returnThreshold: if returnUsedData: return preparedData, output, uiT.returnLastThreshold() else: return output, uiT.returnLastThreshold() else: if returnUsedData: return preparedData, output else: return output