示例#1
0
 def save(self, window, data):
     name, ok = self.gui.getInputName(window)
     if ok and name:
         name = str(name)
         data.setName(name)
         dir = './Data/' + name
         db.saveRawData(dir, self.gui.dataModel, window.index)
         return True
示例#2
0
 def load(self, k, i):
     dataset = {'result': [], 'fix': []}
     data, info, point = db.loadMatData(self.savepath + self.dirs[k]
         + self.ini.file.name_result[i] + self.type[k], None)
     dataset['result'] = db.BasicData(data, info, point)
     
     data, info, point = db.loadMatData(self.path + self.ini.file.datadir + '/Contour/'
         + self.ini.file.name_fix[i] + '.mat', None)
     dataset['fix'] = db.BasicData(data, info, point)
     
     print 'Data %s loaded!' % self.ini.file.name_result[i]
         
     return dataset
示例#3
0
 def load(self, i):
     dataset = {'mov': [], 'fix': [], 'seg': []}
     
     data, info, point = db.loadMatData(self.path + self.ini.file.datadir + '/Contour/'
         + self.ini.file.name_fix[i] + '.mat', None)
     fileData = db.BasicData(data, info, point)
     dataset['fix'] = fileData
     
     data, info, point = db.loadMatData(self.savepath + self.ini.file.name_result[i] + '_mr.mat', None)
     fileData = db.BasicData(data, info, point)
     dataset['seg'] = fileData
     print 'Data %s loaded!' % self.ini.file.name_result[i]
         
     return dataset
示例#4
0
 def load(self, i):
     dataset = {'mov': [], 'fix': []}
     data, info, point = db.loadMatData(self.path + self.ini.file.datadir + '/Contour/'
         + self.ini.file.name_mov[i] + '.mat', None)
     point['Centerline'] = calCenterlineFromContour(point)
     dataset['mov'] = db.BasicData(data, info, point)
     
     data, info, point = db.loadMatData(self.path + self.ini.file.datadir + '/Contour/'
         + self.ini.file.name_fix[i] + '.mat', None)
     point['Centerline'] = calCenterlineFromContour(point)
     dataset['fix'] = db.BasicData(data, info, point)
     
     print 'Data %s loaded!' % self.ini.file.name_result[i]
         
     return dataset
示例#5
0
 def load(self, i):
     dataset = {'us': [], 'mr': []}
     
     data, info, point = db.loadMatData(self.path + self.ini.file.datadir + '/Contour/'
         + self.ini.file.name_fix[i] + '.mat', None)
     fileData = db.BasicData(data, info, point)
     dataset['mr'] = fileData
     
     data, info, point = db.loadMatData(self.path + self.ini.file.datadir + '/Contour/'
         + self.ini.file.name_mov[i] + '.mat', None)
     fileData = db.BasicData(data, info, point)
     dataset['us'] = fileData
     print 'Data %s loaded!' % self.ini.file.name_result[i]
         
     return dataset
示例#6
0
 def load(self, i):
     dataset = {'result': [], 'fix': [], 'mov': []}
     data, info, point = db.loadMatData(self.path + self.ini.file.datadir
         + self.ini.file.name_result[i] + '_icp_cen.mat', None)
     dataset['result'] = db.BasicData(data, info, point)
     
     data, info, point = db.loadMatData(self.path + self.ini.file.datadir + '/Contour/'
         + self.ini.file.name_fix[i] + '.mat', None)
     dataset['fix'] = db.BasicData(data, info, point)
     
     data, info, point = db.loadMatData(self.path + self.ini.file.datadir + '/Contour/'
         + self.ini.file.name_mov[i] + '.mat', None)
     dataset['mov'] = db.BasicData(data, info, point)
     print 'Data %s loaded!' % self.ini.file.name_result[i]
         
     return dataset
示例#7
0
    def loadDicomInfo(self, dir, dimension):
        # Only available for special data (Need to modify for more universal usage)
        info = db.ImageInfo()
        data = dicom.read_file(dir)
        modality = data.Modality
        info.addData('modality', modality)
        if modality == 'MR' or modality == 'CT':
            ps = data.PixelSpacing
            if modality == 'MR':
                z = data.SpacingBetweenSlices
            else:
                z = data.SliceThickness
            if dimension == 3:
                resolution = [float(z), float(ps[0]), float(ps[1])]
            else:
                resolution = [float(ps[0]), float(ps[1])]   
            resolution = npy.array(resolution)
            info.addData('resolution', resolution)
            orientation = npy.array(map(float, data.ImageOrientationPatient))
            info.addData('orientation', orientation)
        elif modality == 'US':
            r = data[0x200d, 0x3303].value
            resolution = npy.array([float(r[2]), float(r[1]), float(r[0])])
            info.addData('resolution', resolution)
            orientation = npy.array(map(float, data[0x200d, 0x3d00].value[0][0x0020, 0x9116].value[0][0x200d, 0x3d16].value))
            info.addData('orientation', orientation)
            
        # To make the orientation of images compatible
        view, flip = db.getViewAndFlipFromOrientation(orientation, resolution.shape[0])
        info.addData('view', view)
        info.addData('flip', flip)

        return info
示例#8
0
    def load(self, i):
        dataset = {'mov': [], 'fix': []}

        data, info, point = db.loadMatData(
            self.path + self.ini.file.datadir + '/Contour/' +
            self.ini.file.name_fix[i] + '.mat', None)
        fileData = db.BasicData(data, info, point)
        dataset['fix'] = fileData

        data, info, point = db.loadMatData(
            self.path + self.ini.file.datadir + '/Contour/' +
            self.ini.file.name_mov[i] + '.mat', None)
        fileData = db.BasicData(data, info, point)
        dataset['mov'] = fileData
        print 'Data %s loaded!' % self.ini.file.name_result[i]

        return dataset
示例#9
0
 def process(self, dataset, i):
     # ICP with centerline
     print 'Register Data %s with ICP(centerline)...' % self.ini.file.name_result[i]
     for delta in range(-15, 16):
         data, point, para = self.icp.register(dataset['fix'], dataset['mov'], 1, False, delta) # CLICP
         #data, point, para = self.icp.register(dataset['fix'], dataset['mov'], 0, False, delta) #SICP
         #data, point, para = self.icp.register(dataset['fix'], dataset['mov'], 1, False, delta, op = True) #CICP
         #data, point, para = self.icp.register(dataset['fix'], dataset['mov'], 0, False, delta, op = True) #SLICP
         resultData = db.ResultData(data, db.ImageInfo(dataset['fix'].info.data), point)
         resultData.info.addData('fix', 1)
         resultData.info.addData('move', 2)
         resultData.info.addData('transform', para)
         print 'Delta %dmm Done!' % delta
         mean_dis, mean_whole, max_dis, max_whole = self.surfaceerror.analysis(resultData, dataset['fix'].getPointSet('Contour').copy(), dataset['mov'].getPointSet('Contour').copy(), dataset['mov'].getPointSet('Mask').copy(), dataset['mov'].getResolution().tolist())
         print 'Contour Error Done! Whole mean is %0.2fmm.' % mean_whole
         self.error[delta + 15, 0] += mean_whole
         self.error[delta + 15, 1] += mean_whole ** 2
         del data, point, resultData
示例#10
0
 def process(self, dataset, i):
     # ICP with centerline
     print 'Register Data %s with ICP(centerline)...' % self.ini.file.name_result[i]
     for i in self.dis:
         for j in self.dis:
             data, point, para = self.icp.register(dataset['fix'], dataset['mov'], 1, down_fix = i, down_mov = j, MaxRate = 1.0) # CLICP
             #data, point, para = self.icp.register(dataset['fix'], dataset['mov'], 0, False, delta) #SICP
             #data, point, para = self.icp.register(dataset['fix'], dataset['mov'], 1, False, delta, op = True) #CICP
             #data, point, para = self.icp.register(dataset['fix'], dataset['mov'], 0, False, delta, op = True) #SLICP
             resultData = db.ResultData(data, db.ImageInfo(dataset['fix'].info.data), point)
             resultData.info.addData('fix', 1)
             resultData.info.addData('move', 2)
             resultData.info.addData('transform', para)
             print 'Sample (%d, %d) Done!' % (i, j)
             mean_dis, mean_whole, max_dis, max_whole = self.surfaceerror.analysis(resultData, dataset['fix'].getPointSet('Contour').copy(), dataset['mov'].getPointSet('Contour').copy(), dataset['mov'].getPointSet('Mask').copy(), dataset['mov'].getResolution().tolist())
             print 'Contour Error Done! Whole mean is %0.2fmm.' % mean_whole
             self.error[i - 1, j - 1] += mean_whole
             del data, point, resultData
示例#11
0
 def run(self, *args, **kwargs):
     indexes = self.gui.getRegisterDataIndex()
     if indexes:
         if len(indexes) == 2:
             data, point, para = self.register(
                 self.gui.dataModel[indexes[0]],
                 self.gui.dataModel[indexes[1]])
             if data is None:
                 return
             resultData = db.ResultData(
                 data,
                 db.ImageInfo(self.gui.dataModel[indexes[0]].info.data),
                 point)
             resultData.addDetail('fix', indexes[0])
             resultData.addDetail('move', indexes[1])
             resultData.addDetail('transform', para)
             resultData.setName(None)
             return resultData
    def process(self, dataset, i):
        '''
        mean_dis, mean_whole, max_dis, max_whole = self.contourerror.analysis(dataset['seg'], dataset['fix'].getPointSet('Contour').copy())
        print 'Segmentation Contour Error Done! Whole mean is %0.2fmm.' % mean_whole
        self.sheet1.write(0, i + 2, self.ini.file.name_result[i])
        for j in range(3):
            self.sheet1.write(j + 1, i + 2, mean_dis[j])
        self.sheet1.write(4, i + 2, mean_whole)
        
        self.book.save(self.path + self.ini.file.savedir + 'Test_segmentation.xls')
        '''
        # ICP with centerline
        print 'Register Data %s with ICP(centerline)...' % self.ini.file.name_result[
            i]
        data, point, para = self.icp.register(dataset['seg'], dataset['mov'],
                                              1)
        resultData = db.ResultData(data,
                                   db.ImageInfo(dataset['fix'].info.data),
                                   point)
        resultData.info.addData('fix', 1)
        resultData.info.addData('move', 2)
        resultData.info.addData('transform', para)
        mean_dis, mean_whole, max_dis, max_whole = self.surfaceerror.analysis(
            resultData, dataset['fix'].getPointSet('Contour').copy(),
            dataset['mov'].getPointSet('Contour').copy(),
            dataset['mov'].getResolution().tolist())
        #mean_dis, mean_whole, max_dis, max_whole = self.contourerror.analysis(resultData, dataset['fix'].getPointSet('Contour').copy())
        print 'Contour Error Done! Whole mean is %0.2fmm.' % mean_whole
        #dice_index, dice_index_all = self.areaerror.analysis(resultData, dataset['fix'].getPointSet('Contour').copy())
        #print 'Area Error Done! Whole Dice index is %0.3f.' % dice_index_all

        self.sheet2.write(0, i + 2, self.ini.file.name_result[i])
        for j in range(3):
            self.sheet2.write(j + 1, i + 2, mean_dis[j])
            self.sheet2.write(j + 5, i + 2, max_dis[j])
            #self.sheet2.write(j + 9, i + 2, dice_index[j])

        self.sheet2.write(4, i + 2, mean_whole)
        self.sheet2.write(8, i + 2, max_whole)
        #self.sheet2.write(12, i + 2, dice_index_all)

        self.book.save(self.path + self.ini.file.savedir +
                       'Test_segmentation_surface.xls')
        del data, point, resultData
示例#13
0
    def process(self, dataset, i):
        point_us = dataset['us'].pointSet.data['Contour']
        point_us = point_us[point_us[:, 0] >= 0][:, 2]
        point_mr = dataset['mr'].pointSet.data['Contour']
        point_mr = point_mr[point_mr[:, 0] >= 0][:, 2]

        bottom_us = npy.min(point_us)
        top_us = npy.max(point_us)
        bif_us = db.getBifurcation(dataset['us'].pointSet.data['Contour'])
        res_us = dataset['us'].getResolution()

        bottom_mr = npy.min(point_mr)
        top_mr = npy.max(point_mr)
        bif_mr = db.getBifurcation(dataset['mr'].pointSet.data['Contour'])
        res_mr = dataset['mr'].getResolution()

        point_mr = dataset['mr'].pointSet.data['Contour']
        self.mr[0] += bif_mr - bottom_mr + 1
        self.mr[1] += npy.max(
            point_mr[npy.round(point_mr[:, -1]) == 1][:, 2]) - bif_mr + 1
        self.mr[2] += npy.max(
            point_mr[npy.round(point_mr[:, -1]) == 2][:, 2]) - bif_mr + 1

        self.usslices += top_us - bottom_us + 1
        self.uspoints += point_us.shape[0]
        self.mrslices += top_mr - bottom_mr + 1
        self.mrpoints += point_mr.shape[0]

        self.sheet_us.write(i + 1, 0, self.ini.file.name_result[i])
        self.sheet_us.write(i + 1, 1, bottom_us)
        self.sheet_us.write(i + 1, 2, bif_us)
        self.sheet_us.write(i + 1, 3, top_us)
        for j in range(3):
            self.sheet_us.write(i + 1, j + 4, res_us[j])

        self.sheet_mr.write(i + 1, 0, self.ini.file.name_result[i])
        self.sheet_mr.write(i + 1, 1, bottom_mr)
        self.sheet_mr.write(i + 1, 2, bif_mr)
        self.sheet_mr.write(i + 1, 3, top_mr)
        for j in range(3):
            self.sheet_mr.write(i + 1, j + 4, res_mr[j])

        self.book.save('./Result/count.xls')
示例#14
0
 def load(self, dir):
     result = []
     for name in dir:
         data, info, point = db.loadMatData(name, self.gui.dataModel)
         if info.getData('fix') is not None:
             fileData = db.ResultData(data, info, point)
         else:
             fileData = db.BasicData(data, info, point)
         result.append(fileData)
     return result
示例#15
0
    def getInfo(self, res=[1.0, 1.0, 1.0], ori=0):
        info = db.ImageInfo()
        info.addData('modality', 'MR')
        resolution = npy.array(res)
        info.addData('resolution', resolution)
        if ori == 0:  # z
            orientation = npy.array([1, 0, 0, 0, 1, 0])
        elif ori == 1:  # y
            orientation = npy.array([1, 0, 0, 0, 0, -1])
        elif ori == 2:  # x
            orientation = npy.array([0, 1, 0, 0, 0, -1])
        info.addData('orientation', orientation)

        view, flip = db.getViewAndFlipFromOrientation(orientation,
                                                      resolution.shape[0])
        info.addData('view', view)
        info.addData('flip', flip)

        return info
示例#16
0
 def register(self, fixedData, movingData, discard = False):
     fixed_points = fixedData.getPointSet('Contour')
     moving_points = movingData.getPointSet('Contour')
     
     fixed_res = fixedData.getResolution().tolist()
     moving_res = movingData.getResolution().tolist()
     fixed_points = fixed_points.copy()[npy.where(fixed_points[:, 0] >= 0)]
     moving_points = moving_points.copy()[npy.where(moving_points[:, 0] >= 0)]
     # Use the bifurcation as the initial position
     fixed_bif = db.getBifurcation(fixed_points)
     moving_bif = db.getBifurcation(moving_points)
     if (fixed_bif < 0) or (moving_bif < 0):
         fixed_min = 0
     else:
         temp = moving_points[:, 2:]
         moving_delta = moving_bif - npy.min(temp[npy.where(npy.round(temp[:, 1]) == 0), 0])
         fixed_min = fixed_bif - moving_delta * moving_res[-1] / fixed_res[-1]
     
     # Get the result transformation parameters0
     T = ml.mat([0, 0, 0]).T;
     R = ml.mat([[1, 0, 0], 
                 [0, 1, 0], 
                 [0, 0, 1]]).I;
     if (fixed_bif >= 0) and (moving_bif >= 0):
         T[2] += (fixed_bif * fixed_res[2] - moving_bif * moving_res[2])
     
     moving_points = movingData.getPointSet('Contour').copy()
     moving_center = movingData.getPointSet('Centerline').copy()                
     new_trans_points, result_center_points = util.resliceTheResultPoints(moving_points, moving_center, 20, moving_res, fixed_res, discard, R, T)
     
     T = -T
     T = R * T
     
     transform = sitk.Transform(3, sitk.sitkAffine)
     para = R.reshape(1, -1).tolist()[0] + T.T.tolist()[0]
     transform.SetParameters(para)
     
     movingImage = movingData.getSimpleITKImage()
     fixedImage = fixedData.getSimpleITKImage()
     resultImage = sitk.Resample(movingImage, fixedImage, transform, sitk.sitkLinear, 0, sitk.sitkFloat32)
     
     return sitk.GetArrayFromImage(resultImage), {'Contour': trans_points, 'Centerline': result_center_points}, para + [0, 0, 0]
示例#17
0
 def process(self, dataset, i):
     point_us = dataset['us'].pointSet.data['Contour']
     point_us = point_us[point_us[:, 0] >= 0][:, 2]
     point_mr = dataset['mr'].pointSet.data['Contour']
     point_mr = point_mr[point_mr[:, 0] >= 0][:, 2]
     
     bottom_us = npy.min(point_us)
     top_us = npy.max(point_us)
     bif_us = db.getBifurcation(dataset['us'].pointSet.data['Contour'])
     res_us = dataset['us'].getResolution()
     
     bottom_mr = npy.min(point_mr)
     top_mr = npy.max(point_mr)
     bif_mr = db.getBifurcation(dataset['mr'].pointSet.data['Contour'])
     res_mr = dataset['mr'].getResolution()
     
     point_mr = dataset['mr'].pointSet.data['Contour']
     self.mr[0] += bif_mr - bottom_mr + 1
     self.mr[1] += npy.max(point_mr[npy.round(point_mr[:, -1]) == 1][:, 2]) - bif_mr + 1
     self.mr[2] += npy.max(point_mr[npy.round(point_mr[:, -1]) == 2][:, 2]) - bif_mr + 1
     
     self.usslices += top_us - bottom_us + 1
     self.uspoints += point_us.shape[0]
     self.mrslices += top_mr - bottom_mr + 1
     self.mrpoints += point_mr.shape[0]
     
     self.sheet_us.write(i + 1, 0, self.ini.file.name_result[i])
     self.sheet_us.write(i + 1, 1, bottom_us)
     self.sheet_us.write(i + 1, 2, bif_us)
     self.sheet_us.write(i + 1, 3, top_us)
     for j in range(3):
         self.sheet_us.write(i + 1, j + 4, res_us[j])
     
     self.sheet_mr.write(i + 1, 0, self.ini.file.name_result[i])
     self.sheet_mr.write(i + 1, 1, bottom_mr)
     self.sheet_mr.write(i + 1, 2, bif_mr)
     self.sheet_mr.write(i + 1, 3, top_mr)
     for j in range(3):
         self.sheet_mr.write(i + 1, j + 4, res_mr[j])
     
     self.book.save('./Result/count.xls')
示例#18
0
 def process(self, dataset, i):
     # ICP with centerline
     print 'Register Data %s with ICP(centerline)...' % self.ini.file.name_result[
         i]
     for fov in range(7):
         data, point, para = self.icp.register(dataset['fix'],
                                               dataset['mov'], 1, False, 0,
                                               9999.0, 1, fov + 1)
         resultData = db.ResultData(data,
                                    db.ImageInfo(dataset['fix'].info.data),
                                    point)
         resultData.info.addData('fix', 1)
         resultData.info.addData('move', 2)
         resultData.info.addData('transform', para)
         print 'FOV %dmm Done!' % (fov + 1)
         mean_dis, mean_whole, max_dis, max_whole = self.contourerror.analysis(
             resultData, dataset['fix'].getPointSet('Contour').copy())
         print 'Contour Error Done! Whole mean is %0.2fmm.' % mean_whole
         self.error[fov, :3] += mean_dis
         self.error[fov, 3] += mean_whole
         del data, point, resultData
示例#19
0
    def loadDicomInfo(self, dir, dimension):
        # Only available for special data (Need to modify for more universal usage)
        info = db.ImageInfo()
        data = dicom.read_file(dir)
        modality = data.Modality
        info.addData('modality', modality)
        if modality == 'MR' or modality == 'CT':
            ps = data.PixelSpacing
            if modality == 'MR':
                z = data.SpacingBetweenSlices
            else:
                z = data.SliceThickness
            if dimension == 3:
                resolution = [float(z), float(ps[0]), float(ps[1])]
            else:
                resolution = [float(ps[0]), float(ps[1])]
            resolution = npy.array(resolution)
            info.addData('resolution', resolution)
            orientation = npy.array(map(float, data.ImageOrientationPatient))
            info.addData('orientation', orientation)
        elif modality == 'US':
            r = data[0x200d, 0x3303].value
            resolution = npy.array([float(r[2]), float(r[1]), float(r[0])])
            info.addData('resolution', resolution)
            orientation = npy.array(
                map(
                    float,
                    data[0x200d,
                         0x3d00].value[0][0x0020,
                                          0x9116].value[0][0x200d,
                                                           0x3d16].value))
            info.addData('orientation', orientation)

        # To make the orientation of images compatible
        view, flip = db.getViewAndFlipFromOrientation(orientation,
                                                      resolution.shape[0])
        info.addData('view', view)
        info.addData('flip', flip)

        return info
示例#20
0
 def process(self, dataset, i):
     print 'Register Data %s with ICP(centerline) with label...' % self.ini.file.name_result[
         i]
     data, point, para = self.icp.register(dataset['fix'], dataset['mov'],
                                           1)
     resultData = db.ResultData(data,
                                db.ImageInfo(dataset['fix'].info.data),
                                point)
     resultData.info.addData('fix', 1)
     resultData.info.addData('move', 2)
     resultData.info.addData('transform', para)
     print 'Done!'
     print 'Evaluation Data %s...' % self.ini.file.name_result[i]
     mean_dis, mean_whole, max_dis, max_whole, result = self.contourerror.analysis(
         resultData, dataset['fix'].getPointSet('Contour').copy(), True)
     print 'Contour Error Done! Whole mean is %0.2fmm.' % mean_whole
     print result
     for cnt in range(3):
         for x in result[cnt].keys():
             self.result[cnt][x] = self.result[cnt].get(x,
                                                        0) + result[cnt][x]
             self.resultCnt[cnt][x] = self.resultCnt[cnt].get(x, 0) + 1
示例#21
0
    def load(self, dir):
        try:
            data = db.loadDicomArray(dir)
        except Exception:
            if self.gui:
                self.gui.showErrorMessage(
                    "Memory error",
                    "Data exceeded memory limit! If this problem occurs again, please restart the application."
                )
            else:
                print "Data exceeded memory limit!"
            return []

        # Format: z * x * y
        if type(data) == tuple:
            data = npy.concatenate((data[0], data[1]), axis=0)
        if data.shape[0] == 1:
            data = data.reshape(data.shape[1:])

        info = self.loadDicomInfo(dir[0], len(data.shape))
        fileData = db.BasicData(data=data, info=info)

        return [fileData]
示例#22
0
 def getInfo(self, res = [1.0, 1.0, 1.0], ori = 0):
     info = db.ImageInfo()
     info.addData('modality', 'MR') 
     resolution = npy.array(res)
     info.addData('resolution', resolution)
     if ori == 0: # z
         orientation = npy.array([1, 0, 0, 0, 1, 0])
     elif ori == 1: # y
         orientation = npy.array([1, 0, 0, 0, 0, -1])
     elif ori == 2: # x
         orientation = npy.array([0, 1, 0, 0, 0, -1])
     info.addData('orientation', orientation)
     
     view, flip = db.getViewAndFlipFromOrientation(orientation, resolution.shape[0])
     info.addData('view', view)
     info.addData('flip', flip)
     
     return info
示例#23
0
 def load(self, dir):
     try:
         data = db.loadDicomArray(dir)
     except Exception:
         if self.gui:
             self.gui.showErrorMessage("Memory error", "Data exceeded memory limit! If this problem occurs again, please restart the application.")
         else:
             print "Data exceeded memory limit!"
         return []
     
     # Format: z * x * y
     if type(data) == tuple:
         data = npy.concatenate((data[0], data[1]), axis = 0)
     if data.shape[0] == 1:
         data = data.reshape(data.shape[1:])
         
     info = self.loadDicomInfo(dir[0], len(data.shape))
     fileData = db.BasicData(data = data, info = info)
     
     return [fileData]
示例#24
0
 def KeyPressCallback(self, obj, event):
     ch = self.parent.window_interactor.GetKeySym()
     if ch == 'Return':
         if (self.X1, self.Y1) == (self.X2, self.Y2):
             return
             
         point = npy.round(self.getAllPoint())
         if self.parent.dimension:
             max = npy.max(point, axis = 0)
             min = npy.min(point, axis = 0)
             bound = [(min[i], max[i] + 1) for i in range(2)]
             bound = bound[::-1]
         else:
             point[0, self.parent.view] = 0
             point[1, self.parent.view] = self.parent.parent.getData().getData().shape[0] - 1
             max = npy.max(point, axis = 0)
             min = npy.min(point, axis = 0)
             bound = [(min[i], max[i] + 1) for i in range(3)]
             bound = bound[::-1]
         
         info = db.ImageInfo(self.parent.parent.getData().getInfo().data)
         info.setName(None)
         if not self.parent.dimension:
             orientation = npy.array([1, 0, 0, 0, 1, 0])
             info.addData('orientation', orientation)
             resolution = self.parent.parent.getData().getResolution()[::-1]
             info.addData('resolution', resolution)
             view, flip = db.getViewAndFlipFromOrientation(orientation, resolution.shape[0])
             info.addData('view', view)
             info.addData('flip', flip)
             info.addData('clip', npy.array([bound[0][0], bound[0][1], bound[1][0], 
                 bound[1][1], bound[2][0], bound[2][1]]))
             data = db.BasicData(data = self.parent.parent.getData().getData()[bound[0][0]:bound[0][1], 
                 bound[1][0]:bound[1][1], bound[2][0]:bound[2][1]], info = info)
         else:
             info.addData('clip', npy.array([bound[0][0], bound[0][1], bound[1][0], bound[1][1]]))
             data = db.BasicData(data = self.parent.parent.getData().getData()[bound[0][0]:bound[0][1], 
                 bound[1][0]:bound[1][1]], info = info)
             
         self.parent.parent.gui.addNewDataView(data)
    def load(self, i):
        dataset = {'mov': [], 'fix': [], 'seg': []}

        data, info, point = db.loadMatData(
            self.path + self.ini.file.datadir + '/Contour/' +
            self.ini.file.name_fix[i] + '.mat', None)
        point['Centerline'] = calCenterlineFromContour(point)
        fileData = db.BasicData(data, info, point)
        dataset['fix'] = fileData

        data, info, point = db.loadMatData(
            self.path + self.ini.file.datadir + '/Contour/' +
            self.ini.file.name_mov[i] + '.mat', None)
        point['Centerline'] = calCenterlineFromContour(point)
        fileData = db.BasicData(data, info, point)
        dataset['mov'] = fileData

        data, info, point = db.loadMatData(
            self.savepath + self.ini.file.name_result[i] + '_mr.mat', None)
        fileData = db.BasicData(data, info, point)
        dataset['seg'] = fileData
        print 'Data %s loaded!' % self.ini.file.name_result[i]

        return dataset
    def register(self, fixedData, movingData, discard=False):
        index = self.gui.getDataIndex({
            'Contour': 0,
            'Centerline': 1
        }, 'Select the object')
        if index is None:
            return None, None, None
        if index == 0:
            fixed_points = fixedData.getPointSet('Contour')
            moving_points = movingData.getPointSet('Contour')
        else:
            fixed_points = fixedData.getPointSet('Centerline')
            moving_points = movingData.getPointSet('Centerline')

        fixed_res = fixedData.getResolution().tolist()
        moving_res = movingData.getResolution().tolist()
        fixed_points = fixed_points.copy()[npy.where(fixed_points[:, 0] >= 0)]
        moving_points = moving_points.copy()[npy.where(
            moving_points[:, 0] >= 0)]
        # Use the bifurcation as the initial position
        fixed_bif = db.getBifurcation(fixed_points)
        moving_bif = db.getBifurcation(moving_points)
        if (fixed_bif < 0) or (moving_bif < 0):
            fixed_min = 0
        else:
            temp = moving_points[:, 2:]
            moving_delta = moving_bif - npy.min(
                temp[npy.where(npy.round(temp[:, 1]) == 0), 0])
            fixed_min = fixed_bif - moving_delta * moving_res[-1] / fixed_res[
                -1]
        #print moving_res
        #print fixed_res

        # Augmentation of pointset
        fixed = fixed_points[npy.where(fixed_points[:, 2] >= fixed_min)]
        moving = moving_points.copy()
        fixed = util.augmentPointset(fixed,
                                     int(fixed_res[-1] / moving_res[-1] + 0.5),
                                     moving.shape[0], fixed_bif)
        moving = util.augmentPointset(
            moving, int(moving_res[-1] / fixed_res[-1] + 0.5), fixed.shape[0],
            moving_bif)

        fixed = fixed[:, :3]
        moving = moving[:, :3]
        fixed[:, :3] *= fixed_res[:3]
        moving[:, :3] *= moving_res[:3]
        if (fixed_bif >= 0) and (moving_bif >= 0):
            fixed[:,
                  2] -= (fixed_bif * fixed_res[2] - moving_bif * moving_res[2])
        print fixed.shape[0], moving.shape[0]
        #return None, None, None

        sourcePoints = vtk.vtkPoints()
        sourceVertices = vtk.vtkCellArray()
        for x in moving:
            id = sourcePoints.InsertNextPoint(x[0], x[1], x[2])
            sourceVertices.InsertNextCell(1)
            sourceVertices.InsertCellPoint(id)
        source = vtk.vtkPolyData()
        source.SetPoints(sourcePoints)
        source.SetVerts(sourceVertices)

        targetPoints = vtk.vtkPoints()
        targetVertices = vtk.vtkCellArray()
        for x in fixed:
            id = targetPoints.InsertNextPoint(x[0], x[1], x[2])
            targetVertices.InsertNextCell(1)
            targetVertices.InsertCellPoint(id)
        target = vtk.vtkPolyData()
        target.SetPoints(targetPoints)
        target.SetVerts(targetVertices)

        icp = vtk.vtkIterativeClosestPointTransform()
        icp.SetSource(source)
        icp.SetTarget(target)
        icp.GetLandmarkTransform().SetModeToRigidBody()
        icp.Modified()
        icp.Update()

        icp_filter = vtk.vtkTransformPolyDataFilter()
        icp_filter.SetInput(source)
        icp_filter.SetTransform(icp)
        icp_filter.Update()

        # Get the result transformation parameters
        matrix = icp.GetMatrix()
        T = ml.mat([
            matrix.GetElement(0, 3),
            matrix.GetElement(1, 3),
            matrix.GetElement(2, 3)
        ]).T
        R = ml.mat([[
            matrix.GetElement(0, 0),
            matrix.GetElement(0, 1),
            matrix.GetElement(0, 2)
        ],
                    [
                        matrix.GetElement(1, 0),
                        matrix.GetElement(1, 1),
                        matrix.GetElement(1, 2)
                    ],
                    [
                        matrix.GetElement(2, 0),
                        matrix.GetElement(2, 1),
                        matrix.GetElement(2, 2)
                    ]]).I
        if (fixed_bif >= 0) and (moving_bif >= 0):
            T[2] += (fixed_bif * fixed_res[2] - moving_bif * moving_res[2])

        moving_points = movingData.getPointSet('Contour').copy()
        moving_center = movingData.getPointSet('Centerline').copy()
        new_trans_points, result_center_points = util.resliceTheResultPoints(
            moving_points, moving_center, 20, moving_res, fixed_res, discard,
            R, T)

        T = -T
        T = R * T

        transform = sitk.Transform(3, sitk.sitkAffine)
        para = R.reshape(1, -1).tolist()[0] + T.T.tolist()[0]
        transform.SetParameters(para)

        movingImage = movingData.getSimpleITKImage()
        fixedImage = fixedData.getSimpleITKImage()
        resultImage = sitk.Resample(movingImage, fixedImage, transform,
                                    sitk.sitkLinear, 0, sitk.sitkFloat32)

        return sitk.GetArrayFromImage(resultImage), {
            'Contour': trans_points,
            'Centerline': result_center_points
        }, para + [0, 0, 0]
 def register(self, fixedData, movingData, index = -1, isRigid = False, isTime = False): # For simple test
     if index == -1:
         if self.gui is not None:
             index = self.gui.getDataIndex({'Contour': 0, 'Centerline': 1}, 'Select the object')
         else:
             index = 1
     if index is None:
         return None, None, None
     if index == 0:
         fixed_points = fixedData.getPointSet('Contour')
         moving_points = movingData.getPointSet('Contour')
     else:
         fixed_points = fixedData.getPointSet('Centerline')
         moving_points = movingData.getPointSet('Centerline')
     time1 = time.time()
     # Initial data
     fixed_res = fixedData.getResolution().tolist()
     moving_res = movingData.getResolution().tolist()
     
     fixed_points_con = fixedData.getPointSet('Contour')
     moving_points_con = movingData.getPointSet('Contour')
     fixed_points_cen = fixedData.getPointSet('Centerline')
     moving_points_cen = movingData.getPointSet('Centerline')
     
     fixed_points_ori = fixed_points.copy()[npy.where(fixed_points[:, 0] >= 0)]
     moving_points_ori = moving_points.copy()[npy.where(moving_points[:, 0] >= 0)]
     fixed_points_con_ori = fixed_points_con.copy()[npy.where(fixed_points_con[:, 0] >= 0)]
     moving_points_con_ori = moving_points_con.copy()[npy.where(moving_points_con[:, 0] >= 0)]
     fixed_points_cen_ori = fixed_points_cen.copy()[npy.where(fixed_points_cen[:, 0] >= 0)]
     moving_points_cen_ori = moving_points_cen.copy()[npy.where(moving_points_cen[:, 0] >= 0)]
     
     fixed_points = fixed_points_ori.copy()
     moving_points = moving_points_ori.copy()
     fixed_points_con = fixed_points_con_ori.copy()
     moving_points_con = moving_points_con_ori.copy()
     fixed_points_cen = fixed_points_cen_ori.copy()
     moving_points_cen = moving_points_cen_ori.copy()
     
     init_time = 0.0
     time1 = time.time()
     
     fix_img = fixedData.getData()
     mov_img = movingData.getData()
     
     # Calculate the initial rigid transformation for 9 points T0
     fix_key_point = eutil.getKeyPoints(fixed_points_cen, fixed_res)
     mov_key_point = eutil.getKeyPoints(moving_points_cen, moving_res)
     T0, mov_bif = eutil.getRigidTransform(fix_key_point, mov_key_point) # 4 * 4 Matrix
     moving_points = eutil.applyRigidTransformOnPoints(moving_points, moving_res, T0)
     moving_points_con = eutil.applyRigidTransformOnPoints(moving_points_con, moving_res, T0)
     moving_points_cen_result = eutil.applyRigidTransformOnPoints(moving_points_cen, moving_res, T0)
     crop_fixed_index, crop_moving_index = eutil.cropCenterline(fixed_points_cen, moving_points_cen_result, fixed_res, moving_res, fix_key_point[0, 2] / fixed_res[2], mov_bif[2] / moving_res[2])
     
     # Use GMMREG for centerline-based rigid registration T1
     gmm = GmmregPointsetRegistration(self.gui)
     new_fixedData = db.BasicData(fix_img, db.ImageInfo(fixedData.getInfo().data), 
         {'Contour': fixed_points_con, 'Centerline': fixed_points_cen[crop_fixed_index]})
     new_movingData = db.BasicData(mov_img, db.ImageInfo(movingData.getInfo().data), 
         {'Contour': moving_points_con, 'Centerline': moving_points_cen_result[crop_moving_index]})
     tmp_img, points, para = gmm.register(new_fixedData, new_movingData, index, False, "rigid")
     T1 = eutil.getMatrixFromGmmPara(para)
     T_init = T0 * T1
     moving_points = points['Contour'].copy()
     moving_points_cen_result = points['Centerline'].copy()
     del new_movingData
     
     # Use GMMREG for centerline-based TPS registration
     if not isRigid:
         new_movingData = db.BasicData(mov_img, db.ImageInfo(fixedData.getInfo().data), 
             {'Contour': moving_points, 'Centerline': moving_points_cen_result}) # The image has been resampled into fixed resolution
         tmp_img, points, para = gmm.register(new_fixedData, new_movingData, index, False, "EM_TPS")
     time2 = time.time()
     
     sa = SurfaceErrorAnalysis(None)
     dataset = db.BasicData(npy.array([[[0]]]), fixedData.getInfo(), points)
     mean_dis, mean_whole, max_dis, max_whole = sa.analysis(dataset, point_data_fix = fixed_points_con.copy(), useResult = True)
     del dataset
     print mean_dis
     print mean_whole
     
     if isTime:
         return tmp_img, points, [mean_dis, mean_whole], time2 - time1
     return tmp_img, points, [mean_dis, mean_whole]
示例#28
0
    def analysis(self, data, point_data_fix = None, point_data_mov = None, point_data_mask = None, spacing_mov = None, useResult = False):
        if point_data_fix is None:
            point_data_fix = self.gui.dataModel[data.getFixedIndex()].getPointSet('Contour').copy()
            point_data_mov = self.gui.dataModel[data.getMovingIndex()].getPointSet('Contour').copy()
            point_data_mask = self.gui.dataModel[data.getMovingIndex()].getPointSet('Mask').copy()
            spacing_mov = self.gui.dataModel[data.getMovingIndex()].getResolution().tolist()
        
        self.spacing = data.getResolution().tolist()
        point_data_fix = point_data_fix[point_data_fix[:, 0] >= 0]
        bif = db.getBifurcation(point_data_fix)
        point_data_fix = util.augmentPointset(point_data_fix, 3, -1, bif, nn = 20)
        point_data_fix[:, :3] *= self.spacing[:3]
        if point_data_mov is not None:
            point_data_mov = point_data_mov[point_data_mov[:, 0] >= 0]

        if not useResult:
            para = npy.array(data.info.getData('transform')).flatten()
            point_data_result = point_data_mov.copy()
            for point in point_data_mask:
                point_data_result = npy.delete(point_data_result, npy.where((npy.abs(point_data_result[:, 2] - point[2]) < 0.0001) & (npy.round(point_data_result[:, -1]) == point[3])), axis = 0)
            point_data_result[:, :3] *= spacing_mov[:3]
            
            R = ml.mat(para[:9]).reshape(3, 3)
            T = ml.mat(para[9:12]).T
            if para.shape[0] > 12:
                C = ml.mat(para[12:]).T
            else:
                C = ml.zeros([3, 1], dtype = npy.float32)
            T = R.I * T
            T = -T
            point_data_result[:, :3] = util.applyTransformForPoints(point_data_result[:, :3], npy.array([1.0, 1, 1]), npy.array([1.0, 1, 1]), R, T, C)
        else:
            point_data_result = data.getPointSet('Contour').copy()
            point_data_result = point_data_result[point_data_result[:, -1] >= 0]
            point_data_result[:, :3] *= self.spacing[:3]
        
        targetPoints = [vtk.vtkPoints(), vtk.vtkPoints(), vtk.vtkPoints()]
        targetVertices = [vtk.vtkCellArray(), vtk.vtkCellArray(), vtk.vtkCellArray()]
        target = [vtk.vtkPolyData(), vtk.vtkPolyData(), vtk.vtkPolyData()]
        Locator = [vtk.vtkCellLocator(), vtk.vtkCellLocator(), vtk.vtkCellLocator()]
        
        label_dis = [3, 2, 1]
        
        for i in range(3):
            for x in point_data_fix[npy.round(point_data_fix[:, 3]) != label_dis[i]]:
                id = targetPoints[i].InsertNextPoint(x[0], x[1], x[2])
                targetVertices[i].InsertNextCell(1)
                targetVertices[i].InsertCellPoint(id)
            target[i].SetPoints(targetPoints[i])
            target[i].SetVerts(targetVertices[i])
            
            Locator[i].SetDataSet(target[i])
            Locator[i].SetNumberOfCellsPerBucket(1)
            Locator[i].BuildLocator()
        
        '''
        Locator = vtk.vtkCellLocator()
        targetPoints = vtk.vtkPoints()
        targetVertices = vtk.vtkCellArray()
        target = vtk.vtkPolyData()
        
        for x in point_data_fix:
            id = targetPoints.InsertNextPoint(x[0], x[1], x[2])
            targetVertices.InsertNextCell(1)
            targetVertices.InsertCellPoint(id)
        
        target.SetPoints(targetPoints)
        target.SetVerts(targetVertices)
        
        Locator.SetDataSet(target)
        Locator.SetNumberOfCellsPerBucket(1)
        Locator.BuildLocator()
        '''
        
        id1 = id2 = vtk.mutable(0)
        dist = vtk.mutable(0.0)
        outPoint = [0.0, 0.0, 0.0]
        
        cnt_num = npy.array([0, 0, 0])
        mean_dis = npy.array([0.0, 0.0, 0.0])
        max_dis = npy.array([0.0, 0.0, 0.0])
        
        for pt in point_data_result:
            cnt = int(pt[-1] + 0.5)
            Locator[cnt].FindClosestPoint(pt[:3].tolist(), outPoint, id1, id2, dist)
            dis = npy.sqrt(npy.sum((npy.array(outPoint) - pt[:3]) ** 2))
            mean_dis[cnt] += dis
            max_dis[cnt] = npy.max([max_dis[cnt], dis])
            cnt_num[cnt] += 1
        
        cnt_total = npy.sum(cnt_num)
        mean_whole = npy.sum(mean_dis) / cnt_total
        mean_dis /= cnt_num
        mean_dis[mean_dis != mean_dis] = 0 # Replace the NAN in the mean distance
        max_whole = npy.max(max_dis)
        
        if self.gui is not None:
            message = "Error on Vessel 0: %0.2fmm (Total %d slices)\nError on Vessel 1: %0.2fmm (Total %d slices)\nError on Vessel 2: %0.2fmm (Total %d slices)\nWhole Error: %0.2fmm (Total %d slices)\n" \
                % (mean_dis[0], cnt_num[0], mean_dis[1], cnt_num[1], mean_dis[2], cnt_num[2], mean_whole, cnt_total) + \
                "-----------------------------------------------------------------------------\n" + \
                "Max Error on Vessel 0: %0.2fmm\nMax Error on Vessel 1: %0.2fmm\nMax Error on Vessel 2: %0.2fmm\nTotal Max Error: %0.2fmm" \
                % (max_dis[0], max_dis[1], max_dis[2], npy.max(max_dis));
            self.gui.showErrorMessage("Centerline Registration Error", message)
        return mean_dis, mean_whole, max_dis, max_whole
示例#29
0
    def process(self, dataset, i):
        def autoDetectContour(point, cnt, start, end, delta, res, type):
            self.new_points = npy.append(self.new_points, point, 0)
            points = point[:, :-2]
            d = 20
            count = 0
            for i in range(start + delta, end + delta, delta):
                center = calCentroidFromContour(points).reshape(2)
                image = dataset[type].getData()[i, :, :].transpose().copy()
                image = (image - npy.min(image)) / (npy.max(image) -
                                                    npy.min(image)) * 255
                down = npy.max([npy.ceil(center[0] - d / res[0]), 0])
                up = npy.min(
                    [npy.floor(center[0] + d / res[0]), image.shape[0]])
                left = npy.max([npy.ceil(center[1] - d / res[1]), 0])
                right = npy.min(
                    [npy.floor(center[1] + d / res[1]), image.shape[1]])
                crop_image = image[down:up, left:right]
                center -= [down, left]

                result = ac_segmentation(center, crop_image)

                a1 = ac_area(points.transpose(), image.shape)
                a2 = ac_area(result, crop_image.shape)
                rate = a2 * 1.0 / a1
                if rate >= min(1.5 + count * 0.2, 2.1) or rate <= 0.7:
                    temp_array = points.copy()
                    if cnt != 1 and rate > 0.7:
                        count += 1
                else:
                    temp_array = result.transpose().copy()
                    temp_array[:, :2] += [down, left]
                    count = 0
                points = temp_array.copy()

                temp_array = npy.insert(temp_array, 2, [[i], [cnt]], 1)
                self.new_points = npy.append(self.new_points, temp_array, 0)

                sys.stdout.write(str(i) + ',')
                sys.stdout.flush()
            print ' '

        # Segmentation of data
        print 'Segment Data %s...' % self.ini.file.name_result[i]
        tmp = dataset['fix'].pointSet.data['Contour']
        tmp = tmp[tmp[:, 0] >= 0]

        self.new_points = npy.array([[-1, -1, -1, -1]], dtype=npy.float32)
        bottom = int(npy.round(npy.min(tmp[:, 2])))
        bif = int(db.getBifurcation(tmp) + 0.5)
        up = int(npy.round(npy.max(tmp[:, 2])))
        bottom += (bif - bottom) / 2
        up -= (up - bif) / 2

        point_vital = [0] * 3
        point_vital[0] = tmp[(npy.round(tmp[:, -1]) == 0)
                             & (npy.round(tmp[:, 2]) == bottom)].copy()
        point_vital[1] = tmp[(npy.round(tmp[:, -1]) == 1)
                             & (npy.round(tmp[:, 2]) == up)].copy()
        point_vital[2] = tmp[(npy.round(tmp[:, -1]) == 2)
                             & (npy.round(tmp[:, 2]) == up)].copy()

        autoDetectContour(point_vital[0], 0, bottom, bif, 1,
                          dataset['fix'].getResolution().tolist(), 'fix')
        autoDetectContour(point_vital[1], 1, up, bif, -1,
                          dataset['fix'].getResolution().tolist(), 'fix')
        autoDetectContour(point_vital[2], 2, up, bif, -1,
                          dataset['fix'].getResolution().tolist(), 'fix')
        print ' '
        print 'Finish segmentation for fix data. '
        pointset = {'Contour': self.new_points}
        dataset['fix'].pointSet.data['Centerline'] = calCenterlineFromContour(
            pointset)
        self.new_points_fix = self.new_points.copy()
        # For mov data
        tmp = dataset['mov'].pointSet.data['Contour']
        tmp = tmp[tmp[:, 0] >= 0]

        self.new_points = npy.array([[-1, -1, -1, -1]], dtype=npy.float32)
        bottom = int(npy.round(npy.min(tmp[:, 2])))
        bif = int(db.getBifurcation(tmp) + 0.5)
        up = int(npy.round(npy.max(tmp[:, 2])))
        bottom += (bif - bottom) / 2
        up -= (up - bif) / 2

        point_vital = [0] * 3
        point_vital[0] = tmp[(npy.round(tmp[:, -1]) == 0)
                             & (npy.round(tmp[:, 2]) == bottom)].copy()
        point_vital[1] = tmp[(npy.round(tmp[:, -1]) == 1)
                             & (npy.round(tmp[:, 2]) == up)].copy()
        point_vital[2] = tmp[(npy.round(tmp[:, -1]) == 2)
                             & (npy.round(tmp[:, 2]) == up)].copy()

        autoDetectContour(point_vital[0], 0, bottom, bif, 1,
                          dataset['mov'].getResolution().tolist(), 'mov')
        autoDetectContour(point_vital[1], 1, up, bif, -1,
                          dataset['mov'].getResolution().tolist(), 'mov')
        autoDetectContour(point_vital[2], 2, up, bif, -1,
                          dataset['mov'].getResolution().tolist(), 'mov')
        print ' '
        print 'Finish segmentation for mov data. '
        pointset = {'Contour': self.new_points}
        dataset['mov'].pointSet.data['Centerline'] = calCenterlineFromContour(
            pointset)
        self.new_points_mov = self.new_points.copy()

        # ICP with centerline without label
        print 'Register Data %s with ICP(centerline) without label...' % self.ini.file.name_result[
            i]
        data, point, para = self.icp.register(dataset['fix'],
                                              dataset['mov'],
                                              1,
                                              op=True)
        resultData = db.ResultData(data,
                                   db.ImageInfo(dataset['fix'].info.data),
                                   point)
        resultData.info.addData('fix', 1)
        resultData.info.addData('move', 2)
        resultData.info.addData('transform', para)
        print 'Done!'
        mean_dis, mean_whole, max_dis, max_whole = self.surfaceerror.analysis(
            resultData, dataset['fix'].getPointSet('Contour').copy(),
            dataset['mov'].getPointSet('Contour').copy(),
            dataset['mov'].getPointSet('Mask').copy(),
            dataset['mov'].getResolution().tolist())
        print 'Contour Error Done! Whole mean is %0.2fmm.' % mean_whole
        dice_index, dice_index_all = self.areaerror.analysis(
            resultData, dataset['fix'].getPointSet('Contour').copy())
        print 'Area Error Done! Whole Dice index is %0.3f.' % dice_index_all

        self.sheet2.write(0, i + 2, self.ini.file.name_result[i])
        for j in range(3):
            self.sheet2.write(j + 1, i + 2, mean_dis[j])
            self.sheet2.write(j + 5, i + 2, max_dis[j])
            self.sheet2.write(j + 9, i + 2, dice_index[j])
        self.sheet2.write(4, i + 2, mean_whole)
        self.sheet2.write(8, i + 2, max_whole)
        self.sheet2.write(12, i + 2, dice_index_all)
        self.book.save(self.path + self.ini.file.savedir +
                       'multicontrast_seg_feature.xls')
        del data, point, resultData

        # ICP with centerline with label
        print 'Register Data %s with ICP(centerline) with label...' % self.ini.file.name_result[
            i]
        data, point, para = self.icp.register(dataset['fix'],
                                              dataset['mov'],
                                              1,
                                              op=False)
        resultData = db.ResultData(data,
                                   db.ImageInfo(dataset['fix'].info.data),
                                   point)
        resultData.info.addData('fix', 1)
        resultData.info.addData('move', 2)
        resultData.info.addData('transform', para)
        print 'Done!'
        mean_dis, mean_whole, max_dis, max_whole = self.surfaceerror.analysis(
            resultData, dataset['fix'].getPointSet('Contour').copy(),
            dataset['mov'].getPointSet('Contour').copy(),
            dataset['mov'].getPointSet('Mask').copy(),
            dataset['mov'].getResolution().tolist())
        print 'Contour Error Done! Whole mean is %0.2fmm.' % mean_whole
        dice_index, dice_index_all = self.areaerror.analysis(
            resultData, dataset['fix'].getPointSet('Contour').copy())
        print 'Area Error Done! Whole Dice index is %0.3f.' % dice_index_all

        self.sheet4.write(0, i + 2, self.ini.file.name_result[i])
        for j in range(3):
            self.sheet4.write(j + 1, i + 2, mean_dis[j])
            self.sheet4.write(j + 5, i + 2, max_dis[j])
            self.sheet4.write(j + 9, i + 2, dice_index[j])
        self.sheet4.write(4, i + 2, mean_whole)
        self.sheet4.write(8, i + 2, max_whole)
        self.sheet4.write(12, i + 2, dice_index_all)
        self.book.save(self.path + self.ini.file.savedir +
                       'multicontrast_seg_feature.xls')
        del data, point, resultData

        fix_points = dataset['fix'].getPointSet('Contour').copy()
        dataset['fix'].pointSet.data['Contour'] = self.new_points_fix
        mov_points = dataset['mov'].getPointSet('Contour').copy()
        dataset['mov'].pointSet.data['Contour'] = self.new_points_mov
        print 'Saving Data %s...' % self.ini.file.name_result[i]
        db.saveMatData(
            self.path + self.ini.file.savedir + self.ini.file.name_result[i] +
            '_snap.mat', [dataset['fix']], 0)
        db.saveMatData(
            self.path + self.ini.file.savedir + self.ini.file.name_result[i] +
            '_merge.mat', [dataset['mov']], 0)
        print 'Done!'

        # ICP with contour without label
        print 'Register Data %s with ICP(contour) without label...' % self.ini.file.name_result[
            i]
        data, point, para = self.icp.register(dataset['fix'],
                                              dataset['mov'],
                                              0,
                                              op=False)
        resultData = db.ResultData(data,
                                   db.ImageInfo(dataset['fix'].info.data),
                                   point)
        resultData.info.addData('fix', 1)
        resultData.info.addData('move', 2)
        resultData.info.addData('transform', para)
        print 'Done!'
        mean_dis, mean_whole, max_dis, max_whole = self.surfaceerror.analysis(
            resultData, fix_points.copy(), mov_points.copy(),
            dataset['mov'].getPointSet('Mask').copy(),
            dataset['mov'].getResolution().tolist())
        print 'Contour Error Done! Whole mean is %0.2fmm.' % mean_whole
        para = resultData.info.getData('transform')
        R = ml.mat(para[:9]).reshape(3, 3)
        T = ml.mat(para[9:12]).T
        T = R.I * T
        T = -T
        tmp_con, result_center_points = util.resliceTheResultPoints(
            mov_points, None, 20, dataset['mov'].getResolution().tolist(),
            dataset['fix'].getResolution().tolist(), False, R, T)
        resultData.pointSet.data['Contour'] = tmp_con
        dice_index, dice_index_all = self.areaerror.analysis(
            resultData, fix_points.copy())
        print 'Area Error Done! Whole Dice index is %0.3f.' % dice_index_all

        self.sheet1.write(0, i + 2, self.ini.file.name_result[i])
        for j in range(3):
            self.sheet1.write(j + 1, i + 2, mean_dis[j])
            self.sheet1.write(j + 5, i + 2, max_dis[j])
            self.sheet1.write(j + 9, i + 2, dice_index[j])
        self.sheet1.write(4, i + 2, mean_whole)
        self.sheet1.write(8, i + 2, max_whole)
        self.sheet1.write(12, i + 2, dice_index_all)
        self.book.save(self.path + self.ini.file.savedir +
                       'multicontrast_seg_feature.xls')
        del data, point, resultData

        # ICP with contour with label
        print 'Register Data %s with ICP(contour) with label...' % self.ini.file.name_result[
            i]
        data, point, para = self.icp.register(dataset['fix'],
                                              dataset['mov'],
                                              0,
                                              op=True)
        resultData = db.ResultData(data,
                                   db.ImageInfo(dataset['fix'].info.data),
                                   point)
        resultData.info.addData('fix', 1)
        resultData.info.addData('move', 2)
        resultData.info.addData('transform', para)
        print 'Done!'
        mean_dis, mean_whole, max_dis, max_whole = self.surfaceerror.analysis(
            resultData, fix_points.copy(), mov_points.copy(),
            dataset['mov'].getPointSet('Mask').copy(),
            dataset['mov'].getResolution().tolist())
        print 'Contour Error Done! Whole mean is %0.2fmm.' % mean_whole
        para = resultData.info.getData('transform')
        R = ml.mat(para[:9]).reshape(3, 3)
        T = ml.mat(para[9:12]).T
        T = R.I * T
        T = -T
        tmp_con, result_center_points = util.resliceTheResultPoints(
            mov_points, None, 20, dataset['mov'].getResolution().tolist(),
            dataset['fix'].getResolution().tolist(), False, R, T)
        resultData.pointSet.data['Contour'] = tmp_con
        dice_index, dice_index_all = self.areaerror.analysis(
            resultData, fix_points.copy())
        print 'Area Error Done! Whole Dice index is %0.3f.' % dice_index_all

        self.sheet3.write(0, i + 2, self.ini.file.name_result[i])
        for j in range(3):
            self.sheet3.write(j + 1, i + 2, mean_dis[j])
            self.sheet3.write(j + 5, i + 2, max_dis[j])
            self.sheet3.write(j + 9, i + 2, dice_index[j])
        self.sheet3.write(4, i + 2, mean_whole)
        self.sheet3.write(8, i + 2, max_whole)
        self.sheet3.write(12, i + 2, dice_index_all)
        self.book.save(self.path + self.ini.file.savedir +
                       'multicontrast_seg_feature.xls')
        del data, point, resultData

        del self.new_points, fix_points, self.new_points_fix, self.new_points_mov, mov_points, tmp_con, result_center_points
 def register(self, fixedData, movingData, index = -1, discard = False, delta = 0, fov = 9999999.0,
         down_fix = 1, down_mov = 1, occ = 9999999.0, op = False, useMask = False, isTime = False, MaxRate = 0.2,
         aug = False, distance_fix = 0.3, distance_mov = 0.1):
     time1 = time.time()
     if index == -1:
         index = self.gui.getDataIndex({'Contour': 0, 'Centerline': 1}, 'Select the object')
     if index is None:
         return None, None, None
     if index == 0:
         fixed_points = fixedData.getPointSet('Contour').copy()
         moving_points = movingData.getPointSet('Contour').copy()
     else:
         fixed_points = fixedData.getPointSet('Centerline').copy()
         moving_points = movingData.getPointSet('Centerline').copy()
     
     fixed_bif = db.getBifurcation(fixed_points)
     moving_bif = db.getBifurcation(moving_points)
     
     if useMask:
         mask_points = movingData.getPointSet('Mask')
         for point in mask_points:
             moving_points = npy.delete(moving_points, npy.where((npy.abs(moving_points[:, 2] - point[2]) < 0.0001) & (npy.round(moving_points[:, -1]) == point[3])), axis = 0)
         
     fixed_res = fixedData.getResolution().tolist()
     moving_res = movingData.getResolution().tolist()
     fixed_points = fixed_points[npy.where(fixed_points[:, 0] >= 0)]
     moving_points = moving_points[npy.where(moving_points[:, 0] >= 0)]
     
     # Use the bifurcation as the initial position
     if (fixed_bif < 0) or (moving_bif < 0):
         fixed_min = 0
     
     # Augmentation of pointset
     fixed = fixed_points.copy()
     moving = moving_points.copy()
     
     if index == 1 and aug:
         fixed = util.augmentCenterline(fixed, 1, 10)
         moving = util.augmentCenterline(moving, 1, 10)
         fix_dis = util.getAxisSin(fixed, 3 / fixed_res[2]) * distance_fix
         mov_dis = util.getAxisSin(moving, 3 / moving_res[2]) * distance_mov
         fixed = util.resampleCenterline(fixed, fix_dis / fixed_res[2])
         moving = util.resampleCenterline(moving, mov_dis / moving_res[2])
     
     fixed = fixed[npy.cast[npy.int32](npy.abs(fixed[:, 2] - fixed_bif)) % down_fix == 0]
     moving = moving[npy.cast[npy.int32](npy.abs(moving[:, 2] - moving_bif)) % down_mov == 0]
     
     fixed[:, :3] *= fixed_res[:3]
     moving[:, :3] *= moving_res[:3]
     
     if (fixed_bif >= 0) and (moving_bif >= 0):
         fixed[:, 2] -= (fixed_bif * fixed_res[2] - moving_bif * moving_res[2] + delta)
     
     # Prepare for ICP
     LandmarkTransform = vtk.vtkLandmarkTransform()
     LandmarkTransform.SetModeToRigidBody()
     MaxIterNum = 50
     #MaxNum = 600
     MaxNum = int(MaxRate * moving.shape[0] + 0.5)
     
     targetPoints = [vtk.vtkPoints(), vtk.vtkPoints(), vtk.vtkPoints()]
     targetVertices = [vtk.vtkCellArray(), vtk.vtkCellArray(), vtk.vtkCellArray()]
     target = [vtk.vtkPolyData(), vtk.vtkPolyData(), vtk.vtkPolyData()]
     Locator = [vtk.vtkCellLocator(), vtk.vtkCellLocator(), vtk.vtkCellLocator()]
     if index == 0:
         if not op:
             label_dis = [3, 3, 3]
         else:
             label_dis = [3, 2, 1]
     else:
         if op:
             label_dis = [3, 3, 3]
         else:
             label_dis = [3, 2, 1]
         
     
     for i in range(3):
         for x in fixed[npy.round(fixed[:, 3]) != label_dis[i]]:
             id = targetPoints[i].InsertNextPoint(x[0], x[1], x[2])
             targetVertices[i].InsertNextCell(1)
             targetVertices[i].InsertCellPoint(id)
         target[i].SetPoints(targetPoints[i])
         target[i].SetVerts(targetVertices[i])
         
         Locator[i].SetDataSet(target[i])
         Locator[i].SetNumberOfCellsPerBucket(1)
         Locator[i].BuildLocator()
     
     step = 1
     if moving.shape[0] > MaxNum:
         ind = moving[:, 2].argsort()
         moving = moving[ind, :]
         step = moving.shape[0] / MaxNum
     nb_points = moving.shape[0] / step
     
     accumulate = vtk.vtkTransform()
     accumulate.PostMultiply()
     
     points1 = vtk.vtkPoints()
     points1.SetNumberOfPoints(nb_points)
     
     label = npy.zeros([MaxNum * 2], dtype = npy.int8)
     
     j = 0
     for i in range(nb_points):
         points1.SetPoint(i, moving[j][0], moving[j][1], moving[j][2])
         label[i] = moving[j][3]
         j += step
     
     closestp = vtk.vtkPoints()
     closestp.SetNumberOfPoints(nb_points)
     points2 = vtk.vtkPoints()
     points2.SetNumberOfPoints(nb_points)
     
     id1 = id2 = vtk.mutable(0)
     dist = vtk.mutable(0.0)
     outPoint = [0.0, 0.0, 0.0]
     p1 = [0.0, 0.0, 0.0]
     p2 = [0.0, 0.0, 0.0]
     iternum = 0
     a = points1
     b = points2
     
     '''
     path = sys.argv[0]
     if os.path.isfile(path):
         path = os.path.dirname(path)
     path += '/Data/Transform'
     wfile = open("%s/transform.txt" % path, 'w')
     
     matrix = accumulate.GetMatrix()
     T = ml.mat([matrix.GetElement(0, 3), matrix.GetElement(1, 3), matrix.GetElement(2, 3)]).T;
     R = ml.mat([[matrix.GetElement(0, 0), matrix.GetElement(0, 1), matrix.GetElement(0, 2)], 
                 [matrix.GetElement(1, 0), matrix.GetElement(1, 1), matrix.GetElement(1, 2)], 
                 [matrix.GetElement(2, 0), matrix.GetElement(2, 1), matrix.GetElement(2, 2)]]).I
     if (fixed_bif >= 0) and (moving_bif >= 0):
         T[2] += (fixed_bif * fixed_res[2] - moving_bif * moving_res[2] + delta)
     saveTransform(wfile, T, R)
     '''
     
     while True:
         for i in range(nb_points):
             Locator[label[i]].FindClosestPoint(a.GetPoint(i), outPoint, id1, id2, dist)
             closestp.SetPoint(i, outPoint)
             
         LandmarkTransform.SetSourceLandmarks(a)
         LandmarkTransform.SetTargetLandmarks(closestp)
         LandmarkTransform.Update()
         
         accumulate.Concatenate(LandmarkTransform.GetMatrix())
         
         iternum += 1
         if iternum >= MaxIterNum:
             break
         
         dist_err = 0
         for i in range(nb_points):
             a.GetPoint(i, p1)
             LandmarkTransform.InternalTransformPoint(p1, p2)
             b.SetPoint(i, p2)
             dist_err += npy.sqrt((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2 + (p1[2] - p2[2]) ** 2)
         dist_err /= nb_points
         print "iter = %d: %f" % (iternum, dist_err)
         '''
         matrix = accumulate.GetMatrix()
         T = ml.mat([matrix.GetElement(0, 3), matrix.GetElement(1, 3), matrix.GetElement(2, 3)]).T;
         R = ml.mat([[matrix.GetElement(0, 0), matrix.GetElement(0, 1), matrix.GetElement(0, 2)], 
                     [matrix.GetElement(1, 0), matrix.GetElement(1, 1), matrix.GetElement(1, 2)], 
                     [matrix.GetElement(2, 0), matrix.GetElement(2, 1), matrix.GetElement(2, 2)]]).I;
         if (fixed_bif >= 0) and (moving_bif >= 0):
             T[2] += (fixed_bif * fixed_res[2] - moving_bif * moving_res[2])
         saveTransform(wfile, T, R)
         '''
         b, a = a, b
     time2 = time.time()
     #wfile.close()
     # Get the result transformation parameters
     matrix = accumulate.GetMatrix()
     
     T = ml.mat([matrix.GetElement(0, 3), matrix.GetElement(1, 3), matrix.GetElement(2, 3)]).T
     R = ml.mat([[matrix.GetElement(0, 0), matrix.GetElement(0, 1), matrix.GetElement(0, 2)], 
                 [matrix.GetElement(1, 0), matrix.GetElement(1, 1), matrix.GetElement(1, 2)], 
                 [matrix.GetElement(2, 0), matrix.GetElement(2, 1), matrix.GetElement(2, 2)]]).I
     
     #T = ml.mat([0, 0, 0]).T
     #R = ml.mat([[1, 0, 0], [0, 1, 0], [0, 0, 1]]).T
     if (fixed_bif >= 0) and (moving_bif >= 0):
         T[2] += (fixed_bif * fixed_res[2] - moving_bif * moving_res[2] + delta)
     
     # Resample the moving contour
     moving_points = movingData.getPointSet('Contour').copy()
     moving_center = movingData.getPointSet('Centerline').copy()
     #new_trans_points, result_center_points = util.resliceTheResultPoints(moving_points, moving_center, 20, moving_res, fixed_res, discard, R, T)
     new_trans_points, result_center_points = moving_points, moving_center
     result_center_points[:, :3] = util.applyTransformForPoints(result_center_points[:, :3], moving_res, fixed_res, R, T, ml.zeros([3, 1], dtype = npy.float32))
     new_trans_points[:, :3] = util.applyTransformForPoints(new_trans_points[:, :3], moving_res, fixed_res, R, T, ml.zeros([3, 1], dtype = npy.float32))
     T = -T
     T = R * T
     
     transform = sitk.Transform(3, sitk.sitkAffine)
     para = R.reshape(1, -1).tolist()[0] + T.T.tolist()[0]
     transform.SetParameters(para)
     
     movingImage = movingData.getSimpleITKImage()
     fixedImage = fixedData.getSimpleITKImage()
     resultImage = sitk.Resample(movingImage, fixedImage, transform, sitk.sitkLinear, 0, sitk.sitkFloat32)
     
     if isTime:
         return sitk.GetArrayFromImage(resultImage), {'Contour': new_trans_points, 'Centerline': result_center_points}, para + [0, 0, 0], time2 - time1
     return sitk.GetArrayFromImage(resultImage), {'Contour': new_trans_points, 'Centerline': result_center_points}, para + [0, 0, 0]
示例#31
0
    def process(self, dataset, i):
        def autoDetectContour(point, cnt, start, end, delta):
            self.new_points = npy.append(self.new_points, point, 0)
            points = point[:, :-2]
            count = 0
            for j in range(start + delta, end + delta, delta):
                center = calCentroidFromContour(points).reshape(2)
                image = dataset['fix'].getData()[j, :, :].transpose().copy()
                image = (image - npy.min(image)) / (npy.max(image) -
                                                    npy.min(image)) * 255
                result = ac_segmentation(center, image)

                a1 = ac_area(points.transpose(), image.shape)
                a2 = ac_area(result, image.shape)
                rate = a2 * 1.0 / a1
                if rate >= min(1.5 + count * 0.2, 2.1) or rate <= 0.7:
                    temp_array = points.copy()
                    if cnt != 1 and rate > 0.7:
                        count += 1
                else:
                    temp_array = result.transpose().copy()
                    count = 0
                points = temp_array.copy()
                temp_array = npy.insert(temp_array, 2, [[j], [cnt]], 1)
                self.new_points = npy.append(self.new_points, temp_array, 0)

                sys.stdout.write(str(j) + ',')
                sys.stdout.flush()
            print ' '

        print 'Segment Data %s...' % self.ini.file.name_result[i]
        tmp = dataset['fix'].pointSet.data['Contour']
        tmp = tmp[tmp[:, 0] >= 0]

        self.new_points = npy.array([[-1, -1, -1, -1]], dtype=npy.float32)
        time1 = time.time()
        bottom = int(npy.round(npy.min(tmp[:, 2])))
        bif = int(db.getBifurcation(tmp) + 0.5)
        up = int(npy.round(npy.max(tmp[:, 2])))

        point_vital = [0] * 3
        point_vital[0] = tmp[(npy.round(tmp[:, -1]) == 0)
                             & (npy.round(tmp[:, 2]) == bottom)].copy()
        point_vital[1] = tmp[(npy.round(tmp[:, -1]) == 1)
                             & (npy.round(tmp[:, 2]) == up)].copy()
        point_vital[2] = tmp[(npy.round(tmp[:, -1]) == 2)
                             & (npy.round(tmp[:, 2]) == up)].copy()

        autoDetectContour(point_vital[0], 0, bottom, bif, 1)
        autoDetectContour(point_vital[1], 1, up, bif, -1)
        autoDetectContour(point_vital[2], 2, up, bif, -1)
        time2 = time.time()
        '''
        # Use centerline for contour
        j = 0
        for center in tmp:
            image = dataset['fix'].getData()[npy.round(center[2]), :, :].transpose().copy()
            image = (image - npy.min(image)) / (npy.max(image) - npy.min(image)) * 255
            result = ac_segmentation(center[:2], image)
            
            point_array = npy.insert(result.transpose(), 2, [[center[2]],[center[3]]], axis = 1)
            new_points = npy.append(new_points, point_array, 0)
            
            j += 1
            if j % 10 == 0:
                sys.stdout.write(str(j) + ',')
                sys.stdout.flush()
        '''
        print ' '
        print 'Done! Time for segmentation is %0.2fs' % (time2 - time1)
        pointset = {'Contour': self.new_points}
        pointset['Centerline'] = calCenterlineFromContour(pointset)
        print 'Saving Data %s...' % self.ini.file.name_result[i]
        new_data = db.BasicData(dataset['fix'].data,
                                db.ImageInfo(dataset['fix'].info.data),
                                pointset)
        db.saveMatData(
            self.savepath + self.ini.file.name_result[i] + '_mr.mat',
            [new_data], 0)
        print 'Done!'
        mean_dis, mean_whole, max_dis, max_whole = self.contourerror.analysis(
            new_data, dataset['fix'].getPointSet('Contour').copy())
        print 'Contour Error Done! Whole mean is %0.2fmm.' % mean_whole
        self.sheet1.write(0, i + 2, self.ini.file.name_result[i])
        for j in range(3):
            self.sheet1.write(j + 1, i + 2, mean_dis[j])
        self.sheet1.write(4, i + 2, mean_whole)
        self.sheet1.write(5, i + 2, time2 - time1)

        self.book.save(self.path + self.ini.file.savedir +
                       'Test_segmentation_final_refined.xls')

        # ICP with centerline
        print 'Register Data %s with ICP(centerline)...' % self.ini.file.name_result[
            i]
        time1 = time.time()
        data, point, para = self.icp.register(new_data, dataset['mov'], 1)
        time2 = time.time()
        print 'Done! Time for registration is %0.2fs' % (time2 - time1)
        resultData = db.ResultData(data,
                                   db.ImageInfo(dataset['fix'].info.data),
                                   point)
        resultData.info.addData('fix', 1)
        resultData.info.addData('move', 2)
        resultData.info.addData('transform', para)
        mean_dis, mean_whole, max_dis, max_whole = self.contourerror.analysis(
            resultData, dataset['fix'].getPointSet('Contour').copy())
        print 'Contour Error Done! Whole mean is %0.2fmm.' % mean_whole
        dice_index, dice_index_all = self.areaerror.analysis(
            resultData, dataset['fix'].getPointSet('Contour').copy())
        print 'Area Error Done! Whole Dice index is %0.3f.' % dice_index_all

        self.sheet2.write(0, i + 2, self.ini.file.name_result[i])
        for j in range(3):
            self.sheet2.write(j + 1, i + 2, mean_dis[j])
            self.sheet2.write(j + 5, i + 2, max_dis[j])
            self.sheet2.write(j + 9, i + 2, dice_index[j])

        self.sheet2.write(4, i + 2, mean_whole)
        self.sheet2.write(8, i + 2, max_whole)
        self.sheet2.write(12, i + 2, dice_index_all)
        self.sheet2.write(13, i + 2, time2 - time1)

        self.book.save(self.path + self.ini.file.savedir +
                       'Test_segmentation_final_refined2.xls')
        del data, point, resultData
示例#32
0
    def analysis(self,
                 data,
                 point_data_fix=None,
                 point_data_mov=None,
                 point_data_mask=None,
                 spacing_mov=None,
                 useResult=False):
        if point_data_fix is None:
            point_data_fix = self.gui.dataModel[
                data.getFixedIndex()].getPointSet('Contour').copy()
            point_data_mov = self.gui.dataModel[
                data.getMovingIndex()].getPointSet('Contour').copy()
            point_data_mask = self.gui.dataModel[
                data.getMovingIndex()].getPointSet('Mask').copy()
            spacing_mov = self.gui.dataModel[
                data.getMovingIndex()].getResolution().tolist()

        self.spacing = data.getResolution().tolist()
        point_data_fix = point_data_fix[point_data_fix[:, 0] >= 0]
        bif = db.getBifurcation(point_data_fix)
        point_data_fix = util.augmentPointset(point_data_fix,
                                              3,
                                              -1,
                                              bif,
                                              nn=20)
        point_data_fix[:, :3] *= self.spacing[:3]
        if point_data_mov is not None:
            point_data_mov = point_data_mov[point_data_mov[:, 0] >= 0]

        if not useResult:
            para = npy.array(data.info.getData('transform')).flatten()
            point_data_result = point_data_mov.copy()
            for point in point_data_mask:
                point_data_result = npy.delete(
                    point_data_result,
                    npy.where(
                        (npy.abs(point_data_result[:, 2] - point[2]) < 0.0001)
                        & (npy.round(point_data_result[:, -1]) == point[3])),
                    axis=0)
            point_data_result[:, :3] *= spacing_mov[:3]

            R = ml.mat(para[:9]).reshape(3, 3)
            T = ml.mat(para[9:12]).T
            if para.shape[0] > 12:
                C = ml.mat(para[12:]).T
            else:
                C = ml.zeros([3, 1], dtype=npy.float32)
            T = R.I * T
            T = -T
            point_data_result[:, :3] = util.applyTransformForPoints(
                point_data_result[:, :3], npy.array([1.0, 1, 1]),
                npy.array([1.0, 1, 1]), R, T, C)
        else:
            point_data_result = data.getPointSet('Contour').copy()
            point_data_result = point_data_result[point_data_result[:,
                                                                    -1] >= 0]
            point_data_result[:, :3] *= self.spacing[:3]

        targetPoints = [vtk.vtkPoints(), vtk.vtkPoints(), vtk.vtkPoints()]
        targetVertices = [
            vtk.vtkCellArray(),
            vtk.vtkCellArray(),
            vtk.vtkCellArray()
        ]
        target = [vtk.vtkPolyData(), vtk.vtkPolyData(), vtk.vtkPolyData()]
        Locator = [
            vtk.vtkCellLocator(),
            vtk.vtkCellLocator(),
            vtk.vtkCellLocator()
        ]

        label_dis = [3, 2, 1]

        for i in range(3):
            for x in point_data_fix[
                    npy.round(point_data_fix[:, 3]) != label_dis[i]]:
                id = targetPoints[i].InsertNextPoint(x[0], x[1], x[2])
                targetVertices[i].InsertNextCell(1)
                targetVertices[i].InsertCellPoint(id)
            target[i].SetPoints(targetPoints[i])
            target[i].SetVerts(targetVertices[i])

            Locator[i].SetDataSet(target[i])
            Locator[i].SetNumberOfCellsPerBucket(1)
            Locator[i].BuildLocator()
        '''
        Locator = vtk.vtkCellLocator()
        targetPoints = vtk.vtkPoints()
        targetVertices = vtk.vtkCellArray()
        target = vtk.vtkPolyData()
        
        for x in point_data_fix:
            id = targetPoints.InsertNextPoint(x[0], x[1], x[2])
            targetVertices.InsertNextCell(1)
            targetVertices.InsertCellPoint(id)
        
        target.SetPoints(targetPoints)
        target.SetVerts(targetVertices)
        
        Locator.SetDataSet(target)
        Locator.SetNumberOfCellsPerBucket(1)
        Locator.BuildLocator()
        '''

        id1 = id2 = vtk.mutable(0)
        dist = vtk.mutable(0.0)
        outPoint = [0.0, 0.0, 0.0]

        cnt_num = npy.array([0, 0, 0])
        mean_dis = npy.array([0.0, 0.0, 0.0])
        max_dis = npy.array([0.0, 0.0, 0.0])

        for pt in point_data_result:
            cnt = int(pt[-1] + 0.5)
            Locator[cnt].FindClosestPoint(pt[:3].tolist(), outPoint, id1, id2,
                                          dist)
            dis = npy.sqrt(npy.sum((npy.array(outPoint) - pt[:3])**2))
            mean_dis[cnt] += dis
            max_dis[cnt] = npy.max([max_dis[cnt], dis])
            cnt_num[cnt] += 1

        cnt_total = npy.sum(cnt_num)
        mean_whole = npy.sum(mean_dis) / cnt_total
        mean_dis /= cnt_num
        mean_dis[
            mean_dis != mean_dis] = 0  # Replace the NAN in the mean distance
        max_whole = npy.max(max_dis)

        if self.gui is not None:
            message = "Error on Vessel 0: %0.2fmm (Total %d slices)\nError on Vessel 1: %0.2fmm (Total %d slices)\nError on Vessel 2: %0.2fmm (Total %d slices)\nWhole Error: %0.2fmm (Total %d slices)\n" \
                % (mean_dis[0], cnt_num[0], mean_dis[1], cnt_num[1], mean_dis[2], cnt_num[2], mean_whole, cnt_total) + \
                "-----------------------------------------------------------------------------\n" + \
                "Max Error on Vessel 0: %0.2fmm\nMax Error on Vessel 1: %0.2fmm\nMax Error on Vessel 2: %0.2fmm\nTotal Max Error: %0.2fmm" \
                % (max_dis[0], max_dis[1], max_dis[2], npy.max(max_dis))
            self.gui.showErrorMessage("Centerline Registration Error", message)
        return mean_dis, mean_whole, max_dis, max_whole
示例#33
0
    def register(self,
                 fixedData,
                 movingData,
                 index=-1,
                 discard=False,
                 method="EM_TPS",
                 execute=True,
                 isTime=False):
        if index == -1:
            index = self.gui.getDataIndex({
                'Contour': 0,
                'Centerline': 1
            }, 'Select the object')
        if index is None:
            return None, None, None
        if index == 0:
            fixed_points = fixedData.getPointSet('Contour')
            moving_points = movingData.getPointSet('Contour')
        else:
            fixed_points = fixedData.getPointSet('Centerline')
            moving_points = movingData.getPointSet('Centerline')
        time1 = time.time()
        fixed_res = fixedData.getResolution().tolist()
        moving_res = movingData.getResolution().tolist()
        fixed_points = fixed_points.copy()[npy.where(fixed_points[:, -1] >= 0)]
        moving_points = moving_points.copy()[npy.where(
            moving_points[:, -1] >= 0)]
        # Use the bifurcation as the initial position
        fixed_bif = db.getBifurcation(fixed_points)
        moving_bif = db.getBifurcation(moving_points)
        if (fixed_bif < 0) or (moving_bif < 0):
            fixed_min = 0
        else:
            temp = moving_points[:, 2:]
            moving_delta = moving_bif - npy.min(
                temp[npy.where(npy.round(temp[:, 1]) == 0), 0])
        #fixed_min = 0

        # Augmentation of pointset
        fixed = fixed_points.copy()
        tmp_fix = fixedData.getPointSet('Centerline')
        tmp_fix = tmp_fix[tmp_fix[:, -1] >= 0].copy()
        ctrl_pts = gutil.getControlPoints(tmp_fix, 1.0 / fixed_res[2])
        moving = moving_points.copy()

        fixed = fixed[:, :3]
        moving = moving[:, :3]
        fixed[:, :3] *= fixed_res[:3]
        ctrl_pts *= fixed_res[:3]
        ctrl_pts_backup = ctrl_pts.copy()
        moving[:, :3] *= moving_res[:3]
        if (fixed_bif >= 0) and (moving_bif >= 0):
            fixed[:,
                  2] -= (fixed_bif * fixed_res[2] - moving_bif * moving_res[2])
            ctrl_pts[:, 2] -= (fixed_bif * fixed_res[2] -
                               moving_bif * moving_res[2])
        #print fixed.shape[0], moving.shape[0]

        eg.initial_data(fixed, moving, ctrl_pts)

        if execute:
            code = eg.run_executable(method=method)
            #print code
            if code != 0:
                print "GMM Fail!"
                return None, None, None

        trans, para, para2 = eg.get_final_result(methodname=method)
        time2 = time.time()

        # Clear the temp files
        #eg.clear_temp_file()

        # Get the result transformation parameters
        if method == 'rigid':
            S1 = ml.eye(3, dtype=npy.float32) * para2[3]
            C = npy.asmatrix(para2[:3]).T

            C2 = npy.asmatrix(para2[4:7]).T
            T0 = npy.asmatrix(para[4:]).T
            R = util.quaternion2rotation(para[:4])

            T = S1 * T0 + C2 - C
            if (fixed_bif >= 0) and (moving_bif >= 0):
                T[2] += (fixed_bif * fixed_res[2] - moving_bif * moving_res[2])

            moving_points = movingData.getPointSet('Contour').copy()
            moving_center = movingData.getPointSet('Centerline').copy()
            #new_trans_points, result_center_points = util.resliceTheResultPoints(moving_points, moving_center, 20, moving_res, fixed_res, discard, R, T, C)
            new_trans_points = util.applyTransformForPoints(
                moving_points, moving_res, fixed_res, R, T, C)
            result_center_points = util.applyTransformForPoints(
                moving_center, moving_res, fixed_res, R, T, C)

            T = -T
            T = R * T
            """
            # Copy the output points of GMMREG for test
            new_trans_points = trans
            
            if (fixed_bif >= 0) and (moving_bif >= 0):
                new_trans_points[:, 2] += (fixed_bif * fixed_res[2] - moving_bif * moving_res[2])
                
            new_trans_points[:, :3] /= fixed_res[:3]
            new_trans_points = npy.insert(new_trans_points, [new_trans_points.shape[1]], moving_points[:, -1].reshape(-1, 1), axis = 1)
            new_trans_points = npy.append(new_trans_points, npy.array([[-1, -1, -1, -1]]), axis = 0)
            #result_center_points = movingData.getPointSet('Centerline').copy()
            result_center_points = movingData.getPointSet('Contour').copy()  
            """

            transform = sitk.Transform(3, sitk.sitkAffine)
            para = R.reshape(1, -1).tolist()[0] + T.T.tolist()[0]
            transform.SetParameters(para)
            transform.SetFixedParameters(C.T.tolist()[0])

            #movingImage = movingData.getSimpleITKImage()
            #fixedImage = fixedData.getSimpleITKImage()
            #resultImage = sitk.Resample(movingImage, fixedImage, transform, sitk.sitkLinear, 0, sitk.sitkFloat32)

            if isTime:
                #return sitk.GetArrayFromImage(resultImage), {'Contour': new_trans_points, 'Centerline': result_center_points}, para + C.T.tolist()[0], time2 - time1
                return movingData.getData().copy(), {
                    'Contour': new_trans_points,
                    'Centerline': result_center_points
                }, para + C.T.tolist()[0], time2 - time1
            #return sitk.GetArrayFromImage(resultImage), {'Contour': new_trans_points, 'Centerline': result_center_points}, para + C.T.tolist()[0]
            return movingData.getData().copy(), {
                'Contour': new_trans_points,
                'Centerline': result_center_points
            }, para + C.T.tolist()[0]

        else:  # EM_TPS
            moving_points = movingData.getPointSet('Contour').copy()
            moving_points = moving_points[npy.where(moving_points[:, 0] >= 0)]
            moving = moving_points[:, :3].copy()
            moving *= moving_res[:3]
            m = moving.shape[0]
            n = ctrl_pts.shape[0]

            M = ml.mat(moving.copy())

            C2 = npy.asmatrix(para2[4:7])
            C2 = ml.repmat(C2, m, 1)

            C3 = npy.asmatrix(para2[7:])
            C3 = ml.repmat(C3, n, 1)
            ctrl_pts -= C3
            ctrl_pts /= para2[3]

            C = npy.asmatrix(para2[:3])
            C = ml.repmat(C, m, 1)
            moving -= C
            moving /= para2[3]

            basis = ml.zeros([m, n], dtype=npy.float32)
            basis[:, 0] = 1
            basis[:, 1:4] = moving

            U = gutil.ComputeTPSKernel(moving, ctrl_pts)
            basis[:, 4:] = U * ml.mat(trans)
            #print npy.array(basis)

            T = basis * ml.mat(para)
            T *= para2[3]
            T += C2 - C

            if (fixed_bif >= 0) and (moving_bif >= 0):
                T[:,
                  2] += (fixed_bif * fixed_res[2] - moving_bif * moving_res[2])

            M += T
            new_trans_points = npy.array(M).copy()
            new_trans_points[:, :3] /= fixed_res[:3]
            new_trans_points = npy.insert(new_trans_points,
                                          [new_trans_points.shape[1]],
                                          moving_points[:, -1].reshape(-1, 1),
                                          axis=1)
            new_trans_points = npy.append(new_trans_points,
                                          npy.array([[-1, -1, -1, -1]]),
                                          axis=0)

            moving_points = movingData.getPointSet('Centerline').copy()
            moving_points = moving_points[npy.where(moving_points[:, 0] >= 0)]
            moving = moving_points[:, :3].copy()
            moving *= moving_res[:3]
            m = moving.shape[0]

            M = ml.mat(moving.copy())

            C2 = npy.asmatrix(para2[4:7])
            C2 = ml.repmat(C2, m, 1)

            C = npy.asmatrix(para2[:3])
            C = ml.repmat(C, m, 1)
            moving -= C
            moving /= para2[3]

            basis = ml.zeros([m, n], dtype=npy.float32)
            basis[:, 0] = 1
            basis[:, 1:4] = moving

            U = gutil.ComputeTPSKernel(moving, ctrl_pts)
            basis[:, 4:] = U * ml.mat(trans)
            #print npy.array(basis)

            T = basis * ml.mat(para)
            T *= para2[3]
            T += C2 - C

            if (fixed_bif >= 0) and (moving_bif >= 0):
                T[:,
                  2] += (fixed_bif * fixed_res[2] - moving_bif * moving_res[2])

            M += T
            result_center_points = npy.array(M).copy()
            result_center_points[:, :3] /= fixed_res[:3]
            result_center_points = npy.insert(result_center_points,
                                              [result_center_points.shape[1]],
                                              moving_points[:,
                                                            -1].reshape(-1, 1),
                                              axis=1)
            result_center_points = npy.append(result_center_points,
                                              npy.array([[-1, -1, -1, -1]]),
                                              axis=0)
            #print result_center_points

            moving = ctrl_pts_backup.copy()
            m = moving.shape[0]
            M = ml.mat(moving.copy())

            C = npy.asmatrix(para2[:3])
            C = ml.repmat(C, m, 1)
            moving -= C
            moving /= para2[3]

            C2 = npy.asmatrix(para2[4:7])
            C2 = ml.repmat(C2, m, 1)

            basis = ml.zeros([m, n], dtype=npy.float32)
            basis[:, 0] = 1
            basis[:, 1:4] = moving

            U = gutil.ComputeTPSKernel(moving, ctrl_pts)
            basis[:, 4:] = U * ml.mat(trans)
            #print npy.array(basis)

            T = basis * ml.mat(para)
            T *= para2[3]
            T += C2 - C

            if (fixed_bif >= 0) and (moving_bif >= 0):
                T[:,
                  2] += (fixed_bif * fixed_res[2] - moving_bif * moving_res[2])

            M += T
            result_ctrl = npy.array(M).copy()
            #print result_ctrl

            image_type = fixedData.getITKImageType()
            transform_type = itk.ThinPlateSplineKernelTransform.D3
            transform = transform_type.New()
            pointset_type = itk.PointSet.PD33S
            source_pointset = pointset_type.New()
            target_pointset = pointset_type.New()
            count = 0
            for point in ctrl_pts_backup:
                tmp_point = itk.Point.D3()
                tmp_point[0] = point[0]
                tmp_point[1] = point[1]
                tmp_point[2] = point[2]
                source_pointset.SetPoint(count, tmp_point)
                count += 1
            count = 0
            for point in ctrl_pts_backup:
                tmp_point = itk.Point.D3()
                tmp_point[0] = point[0]
                tmp_point[1] = point[1]
                tmp_point[2] = point[2]
                target_pointset.SetPoint(count, tmp_point)
                count += 1

            transform.SetSourceLandmarks(source_pointset)
            transform.SetTargetLandmarks(target_pointset)
            transform.ComputeWMatrix()
            """
            # Test for TPS Transform
            moving_points = movingData.getPointSet('Centerline').copy()
            moving_points = moving_points[npy.where(moving_points[:, 0] >= 0)]
            moving = moving_points[:, :3].copy()
            moving *= moving_res[:3]
            for point in moving:
                tmp_point = itk.Point.D3()
                tmp_point[0] = point[0]
                tmp_point[1] = point[1]
                tmp_point[2] = point[2]
                rst_point = transform.TransformPoint(tmp_point)
                point[0] = rst_point[0]
                point[1] = rst_point[1]
                point[2] = rst_point[2]
            moving /= fixed_res[:3]
            print moving
            """

            #            image_type = fixedData.getITKImageType()
            #            resampler = itk.ResampleImageFilter[image_type, image_type].New()
            #            movingImage = movingData.getITKImage()
            #            fixedImage = fixedData.getITKImage()
            #
            #            resampler.SetTransform(transform)
            #            resampler.SetInput(movingImage)
            #
            #            region = fixedImage.GetLargestPossibleRegion()
            #
            #            resampler.SetSize(region.GetSize())
            #            resampler.SetOutputSpacing(fixedImage.GetSpacing())
            #            resampler.SetOutputDirection(fixedImage.GetDirection())
            #            resampler.SetOutputOrigin(fixedImage.GetOrigin())
            #            resampler.SetDefaultPixelValue(0)
            #            resampler.Update()
            #
            #            outputImage = resampler.GetOutput()
            #            image = itk.PyBuffer[image_type].GetArrayFromImage(outputImage)
            if isTime:
                return movingData.getData().copy(), {
                    'Contour': new_trans_points,
                    'Centerline': result_center_points
                }, [0, 0, 0], time2 - time1
            return movingData.getData().copy(), {
                'Contour': new_trans_points,
                'Centerline': result_center_points
            }, [0, 0, 0]
示例#34
0
    def process(self, dataset, i):
        # ICP with centerline
        print 'Register Data %s with ICP...' % self.ini.file.name_result[i]
        tmp = dataset['mov'].pointSet.data['Contour'].copy()
        for sd in range(0, 16):
            mean_dis_all = npy.zeros([4, 3], dtype=npy.float32)
            mean_whole_all = npy.zeros([4, 1], dtype=npy.float32)
            if sd > 0:
                repeat = self.repeat
            else:
                repeat = 1
            for i in range(repeat):
                dataset['mov'].pointSet.data['Contour'] = AddNoise(
                    tmp,
                    float(sd) / 5)
                dataset['mov'].pointSet.data[
                    'Centerline'] = calCenterlineFromContour(
                        dataset['mov'].pointSet.data)

                # Centerline label
                data, point, para = self.icp.register(dataset['fix'],
                                                      dataset['mov'], 1)
                resultData = db.ResultData(
                    data, db.ImageInfo(dataset['fix'].info.data), point)
                resultData.info.addData('fix', 1)
                resultData.info.addData('move', 2)
                resultData.info.addData('transform', para)

                mean_dis, mean_whole, max_dis, max_whole = self.surfaceerror.analysis(
                    resultData, dataset['fix'].getPointSet('Contour').copy(),
                    dataset['mov'].getPointSet('Contour').copy(),
                    dataset['mov'].getPointSet('Mask').copy(),
                    dataset['mov'].getResolution().tolist())
                mean_dis_all[0, :] += mean_dis
                mean_whole_all[0] += mean_whole
                del data, point, resultData, para

                # Contour label
                data, point, para = self.icp.register(dataset['fix'],
                                                      dataset['mov'],
                                                      0,
                                                      op=True)
                resultData = db.ResultData(
                    data, db.ImageInfo(dataset['fix'].info.data), point)
                resultData.info.addData('fix', 1)
                resultData.info.addData('move', 2)
                resultData.info.addData('transform', para)

                mean_dis, mean_whole, max_dis, max_whole = self.surfaceerror.analysis(
                    resultData, dataset['fix'].getPointSet('Contour').copy(),
                    dataset['mov'].getPointSet('Contour').copy(),
                    dataset['mov'].getPointSet('Mask').copy(),
                    dataset['mov'].getResolution().tolist())
                mean_dis_all[1, :] += mean_dis
                mean_whole_all[1] += mean_whole
                del data, point, resultData, para

                # Centerline no-label
                data, point, para = self.icp.register(dataset['fix'],
                                                      dataset['mov'],
                                                      1,
                                                      op=True)
                resultData = db.ResultData(
                    data, db.ImageInfo(dataset['fix'].info.data), point)
                resultData.info.addData('fix', 1)
                resultData.info.addData('move', 2)
                resultData.info.addData('transform', para)

                mean_dis, mean_whole, max_dis, max_whole = self.surfaceerror.analysis(
                    resultData, dataset['fix'].getPointSet('Contour').copy(),
                    dataset['mov'].getPointSet('Contour').copy(),
                    dataset['mov'].getPointSet('Mask').copy(),
                    dataset['mov'].getResolution().tolist())
                mean_dis_all[2, :] += mean_dis
                mean_whole_all[2] += mean_whole
                del data, point, resultData, para

                # Contour no-label
                data, point, para = self.icp.register(dataset['fix'],
                                                      dataset['mov'], 0)
                resultData = db.ResultData(
                    data, db.ImageInfo(dataset['fix'].info.data), point)
                resultData.info.addData('fix', 1)
                resultData.info.addData('move', 2)
                resultData.info.addData('transform', para)

                mean_dis, mean_whole, max_dis, max_whole = self.surfaceerror.analysis(
                    resultData, dataset['fix'].getPointSet('Contour').copy(),
                    dataset['mov'].getPointSet('Contour').copy(),
                    dataset['mov'].getPointSet('Mask').copy(),
                    dataset['mov'].getResolution().tolist())
                mean_dis_all[3, :] += mean_dis
                mean_whole_all[3] += mean_whole
                del data, point, resultData, para

                sys.stdout.write(str(i) + ',')
                sys.stdout.flush()

            mean_dis_all /= repeat
            mean_whole_all /= repeat
            print ' '
            print 'Noise level %fmm Done!' % (float(sd) / 5)
            print 'Contour Error Done! Whole mean is %0.2fmm vs %0.2fmm.' % (
                mean_whole_all[0], mean_whole_all[1])
            for i in range(4):
                self.error[i, sd, :3] += mean_dis_all[i, :]
                self.error[i, sd, 3] += mean_whole_all[i]
示例#35
0
    def register(self,
                 fixedData,
                 movingData,
                 index=-1,
                 discard=False,
                 delta=0,
                 fov=9999999.0,
                 down_fix=1,
                 down_mov=1,
                 occ=9999999.0,
                 useMask=False,
                 isTime=False,
                 MaxRate=0.2,
                 aug=False,
                 distance_fix=0.3,
                 distance_mov=0.1,
                 w_wrong=1.5):
        time1 = time.time()
        if index == -1:
            index = self.gui.getDataIndex({
                'Contour': 0,
                'Centerline': 1
            }, 'Select the object')
        if index is None:
            return None, None, None
        if index == 0:
            fixed_points = fixedData.getPointSet('Contour').copy()
            moving_points = movingData.getPointSet('Contour').copy()
        else:
            fixed_points = fixedData.getPointSet('Centerline').copy()
            moving_points = movingData.getPointSet('Centerline').copy()

        fixed_bif = db.getBifurcation(fixed_points)
        moving_bif = db.getBifurcation(moving_points)

        if useMask:
            mask_points = movingData.getPointSet('Mask')
            for point in mask_points:
                moving_points = npy.delete(
                    moving_points,
                    npy.where(
                        (npy.abs(moving_points[:, 2] - point[2]) < 0.0001)
                        & (npy.round(moving_points[:, -1]) == point[3])),
                    axis=0)

        fixed_res = fixedData.getResolution().tolist()
        moving_res = movingData.getResolution().tolist()
        fixed_points = fixed_points[npy.where(fixed_points[:, 0] >= 0)]
        moving_points = moving_points[npy.where(moving_points[:, 0] >= 0)]

        # Use the bifurcation as the initial position
        if (fixed_bif < 0) or (moving_bif < 0):
            fixed_min = 0

        # Augmentation of pointset
        fixed = fixed_points.copy()
        moving = moving_points.copy()

        if index == 1 and aug:
            fixed = util.augmentCenterline(fixed, 1, 10)
            moving = util.augmentCenterline(moving, 1, 10)
            fix_dis = util.getAxisSin(fixed, 3 / fixed_res[2]) * distance_fix
            mov_dis = util.getAxisSin(moving, 3 / moving_res[2]) * distance_mov
            fixed = util.resampleCenterline(fixed, fix_dis / fixed_res[2])
            moving = util.resampleCenterline(moving, mov_dis / moving_res[2])

        fixed = fixed[npy.cast[npy.int32](npy.abs(fixed[:, 2] - fixed_bif)) %
                      down_fix == 0]
        moving = moving[npy.cast[npy.int32](npy.abs(moving[:, 2] -
                                                    moving_bif)) %
                        down_mov == 0]

        fixed[:, :3] *= fixed_res[:3]
        moving[:, :3] *= moving_res[:3]

        if (fixed_bif >= 0) and (moving_bif >= 0):
            fixed[:, 2] -= (fixed_bif * fixed_res[2] -
                            moving_bif * moving_res[2] + delta)

        # Prepare for ICP
        LandmarkTransform = vtk.vtkLandmarkTransform()
        LandmarkTransform.SetModeToRigidBody()
        MaxIterNum = 50
        #MaxNum = 600
        MaxNum = int(MaxRate * moving.shape[0] + 0.5)

        targetPoints = [vtk.vtkPoints(), vtk.vtkPoints(), vtk.vtkPoints()]
        targetVertices = [
            vtk.vtkCellArray(),
            vtk.vtkCellArray(),
            vtk.vtkCellArray()
        ]
        target = [vtk.vtkPolyData(), vtk.vtkPolyData(), vtk.vtkPolyData()]
        Locator = [
            vtk.vtkCellLocator(),
            vtk.vtkCellLocator(),
            vtk.vtkCellLocator()
        ]

        for i in range(3):
            for x in fixed[npy.round(fixed[:, 3]) == i]:
                id = targetPoints[i].InsertNextPoint(x[0], x[1], x[2])
                targetVertices[i].InsertNextCell(1)
                targetVertices[i].InsertCellPoint(id)
            target[i].SetPoints(targetPoints[i])
            target[i].SetVerts(targetVertices[i])

            Locator[i].SetDataSet(target[i])
            Locator[i].SetNumberOfCellsPerBucket(1)
            Locator[i].BuildLocator()

        step = 1
        if moving.shape[0] > MaxNum:
            ind = moving[:, 2].argsort()
            moving = moving[ind, :]
            step = moving.shape[0] / MaxNum
        nb_points = moving.shape[0] / step

        accumulate = vtk.vtkTransform()
        accumulate.PostMultiply()

        points1 = vtk.vtkPoints()
        points1.SetNumberOfPoints(nb_points)

        label = npy.zeros([MaxNum * 2], dtype=npy.int8)

        j = 0
        for i in range(nb_points):
            points1.SetPoint(i, moving[j][0], moving[j][1], moving[j][2])
            label[i] = moving[j][3]
            j += step

        closestp = vtk.vtkPoints()
        closestp.SetNumberOfPoints(nb_points)
        points2 = vtk.vtkPoints()
        points2.SetNumberOfPoints(nb_points)

        id1 = id2 = vtk.mutable(0)
        dist = vtk.mutable(0.0)
        outPoint = [0.0, 0.0, 0.0]
        p1 = [0.0, 0.0, 0.0]
        p2 = [0.0, 0.0, 0.0]
        iternum = 0
        a = points1
        b = points2
        w_mat = [[1, w_wrong, w_wrong], [w_wrong, 1, 99999999],
                 [w_wrong, 99999999, 1]]

        while True:
            for i in range(nb_points):
                min_dist = 99999999
                min_outPoint = [0.0, 0.0, 0.0]
                for j in range(3):
                    Locator[j].FindClosestPoint(a.GetPoint(i), outPoint, id1,
                                                id2, dist)
                    dis = npy.sqrt(
                        npy.sum((npy.array(outPoint) - a.GetPoint(i))**2))
                    if dis * w_mat[label[i]][j] < min_dist:
                        min_dist = dis * w_mat[label[i]][j]
                        min_outPoint = copy.deepcopy(outPoint)

                closestp.SetPoint(i, min_outPoint)

            LandmarkTransform.SetSourceLandmarks(a)
            LandmarkTransform.SetTargetLandmarks(closestp)
            LandmarkTransform.Update()

            accumulate.Concatenate(LandmarkTransform.GetMatrix())

            iternum += 1
            if iternum >= MaxIterNum:
                break

            for i in range(nb_points):
                a.GetPoint(i, p1)
                LandmarkTransform.InternalTransformPoint(p1, p2)
                b.SetPoint(i, p2)
            b, a = a, b
        time2 = time.time()

        # Get the result transformation parameters
        matrix = accumulate.GetMatrix()

        T = ml.mat([
            matrix.GetElement(0, 3),
            matrix.GetElement(1, 3),
            matrix.GetElement(2, 3)
        ]).T
        R = ml.mat([[
            matrix.GetElement(0, 0),
            matrix.GetElement(0, 1),
            matrix.GetElement(0, 2)
        ],
                    [
                        matrix.GetElement(1, 0),
                        matrix.GetElement(1, 1),
                        matrix.GetElement(1, 2)
                    ],
                    [
                        matrix.GetElement(2, 0),
                        matrix.GetElement(2, 1),
                        matrix.GetElement(2, 2)
                    ]]).I

        if (fixed_bif >= 0) and (moving_bif >= 0):
            T[2] += (fixed_bif * fixed_res[2] - moving_bif * moving_res[2] +
                     delta)

        # Resample the moving contour
        moving_points = movingData.getPointSet('Contour').copy()
        moving_center = movingData.getPointSet('Centerline').copy()
        new_trans_points, result_center_points = moving_points, moving_center
        result_center_points[:, :3] = util.applyTransformForPoints(
            result_center_points[:, :3], moving_res, fixed_res, R, T,
            ml.zeros([3, 1], dtype=npy.float32))
        new_trans_points[:, :3] = util.applyTransformForPoints(
            new_trans_points[:, :3], moving_res, fixed_res, R, T,
            ml.zeros([3, 1], dtype=npy.float32))
        T = -T
        T = R * T

        transform = sitk.Transform(3, sitk.sitkAffine)
        para = R.reshape(1, -1).tolist()[0] + T.T.tolist()[0]
        transform.SetParameters(para)

        movingImage = movingData.getSimpleITKImage()
        fixedImage = fixedData.getSimpleITKImage()
        resultImage = sitk.Resample(movingImage, fixedImage, transform,
                                    sitk.sitkLinear, 0, sitk.sitkFloat32)

        if isTime:
            return sitk.GetArrayFromImage(resultImage), {
                'Contour': new_trans_points,
                'Centerline': result_center_points
            }, para + [0, 0, 0], time2 - time1
        return sitk.GetArrayFromImage(resultImage), {
            'Contour': new_trans_points,
            'Centerline': result_center_points
        }, para + [0, 0, 0]
示例#36
0
 def register(self, fixedData, movingData, index = -1, discard = False, delta = 0, fov = 9999999.0,
         down_fix = 1, down_mov = 1, occ = 9999999.0, op = False, useMask = False, isTime = False, MaxRate = 0.2,
         aug = False, distance_fix = 0.3, distance_mov = 0.1, w_wrong = 1.5, truth_mov = None):
     time1 = time.time()
     if index == -1:
         index = self.gui.getDataIndex({'Contour': 0, 'Centerline': 1}, 'Select the object')
     if index is None:
         return None, None, None
     if index == 0:
         fixed_points = fixedData.getPointSet('Contour').copy()
         moving_points = movingData.getPointSet('Contour').copy()
     else:
         fixed_points = fixedData.getPointSet('Centerline').copy()
         moving_points = movingData.getPointSet('Centerline').copy()
     if truth_mov is None:
         truth_mov = moving_points.copy()
     
     fixed_bif = db.getBifurcation(fixed_points)
     moving_bif = db.getBifurcation(moving_points)
     
     if useMask:
         mask_points = movingData.getPointSet('Mask')
         for point in mask_points:
             moving_points = npy.delete(moving_points, npy.where((npy.abs(moving_points[:, 2] - point[2]) < 0.0001) & (npy.round(moving_points[:, -1]) == point[3])), axis = 0)
         
     fixed_res = fixedData.getResolution().tolist()
     moving_res = movingData.getResolution().tolist()
     fixed_points = fixed_points[npy.where(fixed_points[:, 0] >= 0)]
     moving_points = moving_points[npy.where(moving_points[:, 0] >= 0)]
     
     # Use the bifurcation as the initial position
     if (fixed_bif < 0) or (moving_bif < 0):
         fixed_min = 0
     
     # Augmentation of pointset
     fixed = fixed_points.copy()
     moving = moving_points.copy()
     
     if index == 1 and aug:
         fixed = util.augmentCenterline(fixed, 1, 10)
         moving = util.augmentCenterline(moving, 1, 10)
         fix_dis = util.getAxisSin(fixed, 3 / fixed_res[2]) * distance_fix
         mov_dis = util.getAxisSin(moving, 3 / moving_res[2]) * distance_mov
         fixed = util.resampleCenterline(fixed, fix_dis / fixed_res[2])
         moving = util.resampleCenterline(moving, mov_dis / moving_res[2])
     
     fixed = fixed[npy.cast[npy.int32](npy.abs(fixed[:, 2] - fixed_bif)) % down_fix == 0]
     moving = moving[npy.cast[npy.int32](npy.abs(moving[:, 2] - moving_bif)) % down_mov == 0]
     
     fixed[:, :3] *= fixed_res[:3]
     moving[:, :3] *= moving_res[:3]
     
     new_trans_points = truth_mov
     result_center_points = movingData.getPointSet('Centerline').copy()
     new_trans_points = new_trans_points[new_trans_points[:, 3] >= 0]
     result_center_points = result_center_points[result_center_points[:, 3] >= 0]
     new_trans_points[:, :3] *= moving_res[:3]
     result_center_points[:, :3] *= moving_res[:3]
     
     if (fixed_bif >= 0) and (moving_bif >= 0):
         fixed[:, 2] -= (fixed_bif * fixed_res[2] - moving_bif * moving_res[2] + delta)
     
     # Prepare for ICP
     
     MaxIterNum = 50
     #MaxNum = 600
     MaxNum = int(MaxRate * moving.shape[0] + 0.5)
     
     targetPoints = [vtk.vtkPoints(), vtk.vtkPoints(), vtk.vtkPoints()]
     targetVertices = [vtk.vtkCellArray(), vtk.vtkCellArray(), vtk.vtkCellArray()]
     target = [vtk.vtkPolyData(), vtk.vtkPolyData(), vtk.vtkPolyData()]
     Locator = [vtk.vtkCellLocator(), vtk.vtkCellLocator(), vtk.vtkCellLocator()]
     
     for i in range(3):
         for x in fixed[npy.round(fixed[:, 3]) == i]:
             id = targetPoints[i].InsertNextPoint(x[0], x[1], x[2])
             targetVertices[i].InsertNextCell(1)
             targetVertices[i].InsertCellPoint(id)
         target[i].SetPoints(targetPoints[i])
         target[i].SetVerts(targetVertices[i])
         
         Locator[i].SetDataSet(target[i])
         Locator[i].SetNumberOfCellsPerBucket(1)
         Locator[i].BuildLocator()
     
     step = 1
     if moving.shape[0] > MaxNum:
         ind = moving[:, 2].argsort()
         moving = moving[ind, :]
         step = moving.shape[0] / MaxNum
     nb_points = moving.shape[0] / step
     
     points1 = vtk.vtkPoints()
     points1.SetNumberOfPoints(nb_points)
     
     label = npy.zeros([MaxNum * 2], dtype = npy.int8)
     
     j = 0
     for i in range(nb_points):
         points1.SetPoint(i, moving[j][0], moving[j][1], moving[j][2])
         label[i] = moving[j][3]
         j += step
     
     closestp = vtk.vtkPoints()
     closestp.SetNumberOfPoints(nb_points)
     points2 = vtk.vtkPoints()
     points2.SetNumberOfPoints(nb_points)
     
     id1 = id2 = vtk.mutable(0)
     dist = vtk.mutable(0.0)
     outPoint = [0.0, 0.0, 0.0]
     p1 = [0.0, 0.0, 0.0]
     p2 = [0.0, 0.0, 0.0]
     iternum = 0
     a = points1
     b = points2
     if (op and index == 0) or (not op and index == 1):
         w_mat = [[1, w_wrong, w_wrong], [w_wrong, 1, 99999999], [w_wrong, 99999999, 1]]
     else:
         w_mat = [[1, 1, 1], [1, 1, 1], [1, 1, 1]]
     
     accumulate = vtk.vtkTransform()
     accumulate.PostMultiply()
     LandmarkTransform = vtk.vtkLandmarkTransform()
     LandmarkTransform.SetModeToRigidBody()
     
     while True:
         for i in range(nb_points):
             min_dist = 99999999
             min_outPoint = [0.0, 0.0, 0.0]
             for j in range(3):
                 Locator[j].FindClosestPoint(a.GetPoint(i), outPoint, id1, id2, dist)
                 dis = npy.sqrt(npy.sum((npy.array(outPoint) - a.GetPoint(i)) ** 2))
                 if dis * w_mat[label[i]][j] < min_dist:
                     min_dist = dis * w_mat[label[i]][j]
                     min_outPoint = copy.deepcopy(outPoint)
                 
             closestp.SetPoint(i, min_outPoint)
             
         LandmarkTransform.SetSourceLandmarks(a)
         LandmarkTransform.SetTargetLandmarks(closestp)
         LandmarkTransform.Update()
         accumulate.Concatenate(LandmarkTransform.GetMatrix())
             
         iternum += 1
         
         for i in range(nb_points):
             a.GetPoint(i, p1)
             LandmarkTransform.InternalTransformPoint(p1, p2)
             b.SetPoint(i, p2)
         b, a = a, b
         
         if iternum >= MaxIterNum:
             break
     
     matrix = accumulate.GetMatrix()
     
     T = ml.mat([matrix.GetElement(0, 3), matrix.GetElement(1, 3), matrix.GetElement(2, 3)]).T
     R = ml.mat([[matrix.GetElement(0, 0), matrix.GetElement(0, 1), matrix.GetElement(0, 2)], 
                 [matrix.GetElement(1, 0), matrix.GetElement(1, 1), matrix.GetElement(1, 2)], 
                 [matrix.GetElement(2, 0), matrix.GetElement(2, 1), matrix.GetElement(2, 2)]]).I
     result_center_points[:, :3] = util.applyTransformForPoints(result_center_points[:, :3], npy.array([1.0, 1, 1]), npy.array([1.0, 1, 1]), R, T, ml.zeros([3, 1], dtype = npy.float32))
     new_trans_points[:, :3] = util.applyTransformForPoints(new_trans_points[:, :3], npy.array([1.0, 1, 1]), npy.array([1.0, 1, 1]), R, T, ml.zeros([3, 1], dtype = npy.float32))
     
     LandmarkTransform = vtk.vtkThinPlateSplineTransform()
     LandmarkTransform.SetBasisToR()
     iternum = 0
     # Non-rigid
     while True:
         for i in range(nb_points):
             min_dist = 99999999
             min_outPoint = [0.0, 0.0, 0.0]
             for j in range(3):
                 Locator[j].FindClosestPoint(a.GetPoint(i), outPoint, id1, id2, dist)
                 dis = npy.sqrt(npy.sum((npy.array(outPoint) - a.GetPoint(i)) ** 2))
                 if dis * w_mat[label[i]][j] < min_dist:
                     min_dist = dis * w_mat[label[i]][j]
                     min_outPoint = copy.deepcopy(outPoint)
                 
             closestp.SetPoint(i, min_outPoint)
             
         LandmarkTransform.SetSourceLandmarks(a)
         LandmarkTransform.SetTargetLandmarks(closestp)
         LandmarkTransform.Update()
         
         '''
         for i in range(result_center_points.shape[0]):
             LandmarkTransform.InternalTransformPoint([result_center_points[i, 0], result_center_points[i, 1], result_center_points[i, 2]], p2)
             result_center_points[i, :3] = p2
         '''
         for i in range(new_trans_points.shape[0]):
             LandmarkTransform.InternalTransformPoint([new_trans_points[i, 0], new_trans_points[i, 1], new_trans_points[i, 2]], p2)
             new_trans_points[i, :3] = p2
             
         iternum += 1
         if iternum >= 1:
             break
         
         for i in range(nb_points):
             a.GetPoint(i, p1)
             LandmarkTransform.InternalTransformPoint(p1, p2)
             b.SetPoint(i, p2)
         b, a = a, b
     
     time2 = time.time()
     
     if (fixed_bif >= 0) and (moving_bif >= 0):
         new_trans_points[:, 2] += (fixed_bif * fixed_res[2] - moving_bif * moving_res[2] + delta)
         result_center_points[:, 2] += (fixed_bif * fixed_res[2] - moving_bif * moving_res[2] + delta)
     new_trans_points[:, :3] /= fixed_res[:3]
     result_center_points[:, :3] /= fixed_res[:3]
     resultImage = movingData.getData().copy()
     
     sa = SurfaceErrorAnalysis(None)
     dataset = db.BasicData(npy.array([[[0]]]), fixedData.getInfo(), {'Contour': new_trans_points, 'Centerline': result_center_points})
     mean_dis, mean_whole, max_dis, max_whole = sa.analysis(dataset, point_data_fix = fixedData.getPointSet('Contour').copy(), useResult = True)
     del dataset
     print mean_dis
     print mean_whole
     
     if isTime:
         return resultImage, {'Contour': new_trans_points, 'Centerline': result_center_points}, [mean_dis, mean_whole], time2 - time1
     return resultImage, {'Contour': new_trans_points, 'Centerline': result_center_points}, [mean_dis, mean_whole]
示例#37
0
 def analysis(self, data, point_data_fix = None, all = False):
     if point_data_fix is None:
         point_data_fix = self.gui.dataModel[data.getFixedIndex()].getPointSet('Contour').copy()
     point_data_result = data.getPointSet('Contour').copy()
     self.spacing = data.getResolution().tolist()
     self.spacing[2] = 1.0 # The resolution of z axis is nothing to do with the analysis
     point_data_fix[:, :3] *= self.spacing[:3]
     point_data_result[:, :3] *= self.spacing[:3]
     
     cnt_num = npy.array([0, 0, 0])
     mean_dis = npy.array([0.0, 0.0, 0.0])
     max_dis = npy.array([0.0, 0.0, 0.0])
     square_sum_dis = npy.array([0.0, 0.0, 0.0])
     if all:
         result = [{}, {}, {}]
         bif = db.getBifurcation(point_data_fix)
     
     for cnt in range(3):
         temp_result = point_data_result[npy.where(npy.round(point_data_result[:, -1]) == cnt)]
         temp_fix = point_data_fix[npy.where(npy.round(point_data_fix[:, -1]) == cnt)]
         if not temp_result.shape[0] or not temp_fix.shape[0]:
             continue
         zmin = int(npy.max([npy.min(temp_result[:, 2]), npy.min(temp_fix[:, 2])]) + 0.5)
         zmax = int(npy.min([npy.max(temp_result[:, 2]), npy.max(temp_fix[:, 2])]) + 0.5)
         
         for z in range(zmin, zmax + 1):
             data_fix = temp_fix[npy.where(npy.round(temp_fix[:, 2]) == z)]
             data_result = temp_result[npy.where(npy.round(temp_result[:, 2]) == z)]
             if data_fix is not None and data_result is not None:
                 if data_fix.shape[0] == 0 or data_result.shape[0] == 0:
                     continue
                 cnt_num[cnt] += 1
                 #center_fix = npy.mean(data_fix[:, :2], axis = 0)
                 center_fix = calCentroidFromContour(data_fix[:, :2])[0]
                 #center_result = npy.mean(data_result[:, :2], axis = 0)
                 center_result = calCentroidFromContour(data_result[:, :2])[0]
                 points_fix = getPointsOntheSpline(data_fix, center_fix, 900)
                 points_result = getPointsOntheSpline(data_result, center_result, 900)
                 
                 i = j = 0
                 for k in range(-44, 46):
                     angle = k * 4 / 180.0 * npy.pi
                     while i < 900 and points_fix[i, 2] < angle:
                         i += 1
                     if i == 900 or (i > 0 and angle - points_fix[i - 1, 2] < points_fix[i, 2] - angle):
                         ind_fix = i - 1
                     else:
                         ind_fix = i
                     while j < 900 and points_result[j, 2] < angle:
                         j += 1
                     if j == 900 or (j > 0 and angle - points_result[j - 1, 2] < points_result[j, 2] - angle):
                         ind_result = j - 1
                     else:
                         ind_result = j
                     temp_dis = npy.hypot(points_fix[ind_fix, 0] - points_result[ind_result, 0], points_fix[ind_fix, 1] - points_result[ind_result, 1])
                     max_dis[cnt] = npy.max([max_dis[cnt], temp_dis])
                     mean_dis[cnt] += temp_dis
                     square_sum_dis[cnt] += temp_dis ** 2
                     if all:
                         result[cnt][z - bif] = result[cnt].get(z - bif, 0) + temp_dis
     
     cnt_total = npy.sum(cnt_num)
     sd = npy.sqrt(npy.max([(square_sum_dis - mean_dis ** 2 / (90 * cnt_num)) / (90 * cnt_num - 1), [0, 0, 0]], axis = 0))
     sd[sd != sd] = 0
     sd_all = npy.sqrt(npy.max([(npy.sum(square_sum_dis) - npy.sum(mean_dis) ** 2 / (90 * cnt_total)) / (90 * cnt_total - 1), 0]))
     
     mean_dis /= 90
     mean_whole = npy.sum(mean_dis)
     mean_dis /= cnt_num
     mean_dis[mean_dis != mean_dis] = 0 # Replace the NAN in the mean distance
     
     if self.gui is not None:
         message = "Error on Vessel 0: %0.2fmm (SD = %0.2fmm, Total %d slices)\nError on Vessel 1: %0.2fmm (SD = %0.2fmm, Total %d slices)\nError on Vessel 2: %0.2fmm (SD = %0.2fmm, Total %d slices)\nWhole Error: %0.2fmm (SD = %0.2fmm, Total %d slices)\n" \
             % (mean_dis[0], sd[0], cnt_num[0], mean_dis[1], sd[1], cnt_num[1], mean_dis[2], sd[2], cnt_num[2], mean_whole / cnt_total, sd_all, cnt_total) + \
             "-----------------------------------------------------------------------------\n" + \
             "Max Error on Vessel 0: %0.2fmm\nMax Error on Vessel 1: %0.2fmm\nMax Error on Vessel 2: %0.2fmm\nTotal Max Error: %0.2fmm" \
             % (max_dis[0], max_dis[1], max_dis[2], npy.max(max_dis));
         self.gui.showErrorMessage("Contour Registration Error", message)
         
     if not all:
         return mean_dis, mean_whole / cnt_total, max_dis, npy.max(max_dis)
     else:
         for cnt in range(3):
             for x in result[cnt].keys():
                 result[cnt][x] /= 90
         return mean_dis, mean_whole / cnt_total, max_dis, npy.max(max_dis), result
示例#38
0
def writeImageFile(image, file_name):
    data_model = [image]
    db.saveRawData(get_exe_path() + "/" + file_name, data_model, 0)
    del data_model
示例#39
0
def readImageFile(file_name):
    image, info, point = db.loadRawData(get_exe_path() + "/" + file_name)
    return image
 def process(self, dataset, i):
     def autoDetectContour(point, cnt, start, end, delta, res):
         self.new_points = npy.append(self.new_points, point, 0)
         points = point[:, :-2]
         d = 20
         count = 0
         for i in range(start + delta, end + delta, delta):
             center = calCentroidFromContour(points).reshape(2)
             image = dataset['fix'].getData()[i, :, :].transpose().copy()
             image = (image - npy.min(image)) / (npy.max(image) - npy.min(image)) * 255
             down = npy.max([npy.ceil(center[0] - d / res[0]), 0])
             up = npy.min([npy.floor(center[0] + d / res[0]), image.shape[0]])
             left = npy.max([npy.ceil(center[1] - d / res[1]), 0])
             right = npy.min([npy.floor(center[1] + d / res[1]), image.shape[1]])
             crop_image = image[down : up, left : right]
             center -= [down, left]
             
             result = ac_segmentation(center, crop_image)
             
             a1 = ac_area(points.transpose(), image.shape)
             a2 = ac_area(result, crop_image.shape)
             rate = a2 * 1.0 / a1
             if rate >= min(1.5 + count * 0.2, 2.1) or rate <= 0.7:
                 temp_array = points.copy()
                 if cnt != 1 and rate > 0.7:
                     count += 1
             else:
                 temp_array = result.transpose().copy()
                 temp_array[:, :2] += [down, left]
                 count = 0
             points = temp_array.copy()
             
             
             temp_array = npy.insert(temp_array, 2, [[i], [cnt]], 1)
             self.new_points = npy.append(self.new_points, temp_array, 0)
             
             sys.stdout.write(str(i) + ',')
             sys.stdout.flush()
         print ' '
         
     # Segmentation of data
     print 'Segment Data %s...' % self.ini.file.name_result[i]
     tmp = dataset['fix'].pointSet.data['Contour']
     tmp = tmp[tmp[:, 0] >= 0]
     
     self.new_points = npy.array([[-1, -1, -1, -1]], dtype = npy.float32)
     time1 = time.time()
     bottom = int(npy.round(npy.min(tmp[:, 2])))
     bif = int(db.getBifurcation(tmp) + 0.5)
     up = int(npy.round(npy.max(tmp[:, 2])))
     
     point_vital = [0] * 3
     point_vital[0] = tmp[(npy.round(tmp[:, -1]) == 0) & (npy.round(tmp[:, 2]) == bottom)].copy()
     point_vital[1] = tmp[(npy.round(tmp[:, -1]) == 1) & (npy.round(tmp[:, 2]) == up)].copy()
     point_vital[2] = tmp[(npy.round(tmp[:, -1]) == 2) & (npy.round(tmp[:, 2]) == up)].copy()
         
     autoDetectContour(point_vital[0], 0, bottom, bif, 1, dataset['fix'].getResolution().tolist())
     autoDetectContour(point_vital[1], 1, up, bif, -1, dataset['fix'].getResolution().tolist())
     autoDetectContour(point_vital[2], 2, up, bif, -1, dataset['fix'].getResolution().tolist())
     print ' '
     print 'Finish segmentation of MR. '
     true_fixed_points = dataset['fix'].pointSet.data['Contour'].copy()
     dataset['fix'].pointSet.data['Contour'] = self.new_points
     dataset['fix'].pointSet.data['Centerline'] = calCenterlineFromContour(dataset['fix'].pointSet.data)
     
     hybrid = NonrigidHybridRegistration(None)
     print 'Register Data %s with Hybrid Method...' % (self.ini.file.name_result[i])
     data, point, para = hybrid.register(dataset['fix'], dataset['mov'], regPara = self.regPara, true_fixed_points = true_fixed_points)
     print 'Done!'
     
     for k in range(len(self.regPara)):
         self.sheet1.write(k + 1, i + 2, float(para[k, 0]))
         self.sheet2.write(k + 1, i + 2, float(para[k, 1]))
         self.sheet3.write(k + 1, i + 2, float(para[k, 2]))
     
     self.sheet1.write(0, i + 2, self.ini.file.name_result[i])
     self.sheet2.write(0, i + 2, self.ini.file.name_result[i])
     self.sheet3.write(0, i + 2, self.ini.file.name_result[i])
     self.book.save(self.path + self.ini.file.savedir + 'nonrigid' + str(self.first) + '.xls')
     del para
     del hybrid
     del true_fixed_points
 def analysis(self, data, point_data_fix = None, area = False):
     if point_data_fix is None:
         point_data_fix = self.gui.dataModel[data.getFixedIndex()].getPointSet('Contour').copy()
     point_data_result = data.getPointSet('Contour').copy()
     self.spacing = data.getResolution().tolist()
     point_data_fix[:, :2] *= self.spacing[:2]
     point_data_result[:, :2] *= self.spacing[:2]
     
     center_data = calCenterlineFromContour({'Contour': point_data_fix})
     ind = center_data[:, 2].argsort()
     center_data = center_data[ind]
     center_data_z = center_data[:, 2].copy()
     fixed_bif = db.getBifurcation(center_data)
     bif_point = center_data[npy.round(center_data[:, 2]) == fixed_bif - 1]
     center_data[:, :3] *= self.spacing[:3]
     bif_point[:, :3] *= self.spacing[:3]
     
     spline = [None, None, None]
     for cnt in range(3):
         spline[cnt] = [None, None, None]
         xx = center_data_z[npy.round(center_data[:, -1]) == cnt]
         yy = center_data[npy.round(center_data[:, -1]) == cnt]
         if cnt > 0:
             xx = npy.append(fixed_bif - 1, xx)
             yy = npy.append(bif_point, yy, axis = 0)
         
         for i in range(3):
             spline[cnt][i] = itp.InterpolatedUnivariateSpline(xx, yy[:, i])
     
     cnt_num = npy.array([0, 0, 0])
     mean_dis = npy.array([0.0, 0.0, 0.0])
     max_dis = npy.array([0.0, 0.0, 0.0])
     square_sum_dis = npy.array([0.0, 0.0, 0.0])
     if area:
         area_mr = npy.array([0.0, 0.0, 0.0])
         area_us = npy.array([0.0, 0.0, 0.0])
     
     for cnt in range(3):
         temp_result = point_data_result[npy.where(npy.round(point_data_result[:, -1]) == cnt)]
         temp_fix = point_data_fix[npy.where(npy.round(point_data_fix[:, -1]) == cnt)]
         if not temp_result.shape[0] or not temp_fix.shape[0]:
             continue
         zmin = int(npy.max([npy.min(temp_result[:, 2]), npy.min(temp_fix[:, 2])]) + 0.5)
         zmax = int(npy.min([npy.max(temp_result[:, 2]), npy.max(temp_fix[:, 2])]) + 0.5)
         
         for z in range(zmin, zmax + 1):
             data_fix = temp_fix[npy.where(npy.round(temp_fix[:, 2]) == z)]
             data_result = temp_result[npy.where(npy.round(temp_result[:, 2]) == z)]
             if data_fix is not None and data_result is not None:
                 if data_fix.shape[0] == 0 or data_result.shape[0] == 0:
                     continue
                 cnt_num[cnt] += 1
                 #center_fix = npy.mean(data_fix[:, :2], axis = 0)
                 center_fix, area_fix = calCentroidFromContour(data_fix[:, :2], True)
                 center_fix = center_fix[0]
                 #center_result = npy.mean(data_result[:, :2], axis = 0)
                 center_result, area_result = calCentroidFromContour(data_result[:, :2], True)
                 center_result = center_result[0]
                 if area:
                     area_mr[cnt] += area_fix
                     area_us[cnt] += area_result
                 points_fix = getPointsOntheSpline(data_fix, center_fix, 900)
                 points_result = getPointsOntheSpline(data_result, center_result, 900)
                 
                 normal = npy.array([None, None, None])
                 
                 for i in range(3):
                     normal[i] = spline[cnt][i].derivatives(z)[1]
                 w1 = normal[2] ** 2 / npy.sum(normal ** 2) # cos(alpha) ^ 2
                 theta0 = npy.arctan2(normal[1], normal[0])
                 
                 i = j = 0
                 for k in range(-44, 46):
                     angle = k * 4 / 180.0 * npy.pi
                     while i < 900 and points_fix[i, 2] < angle:
                         i += 1
                     if i == 900 or (i > 0 and angle - points_fix[i - 1, 2] < points_fix[i, 2] - angle):
                         ind_fix = i - 1
                     else:
                         ind_fix = i
                     while j < 900 and points_result[j, 2] < angle:
                         j += 1
                     if j == 900 or (j > 0 and angle - points_result[j - 1, 2] < points_result[j, 2] - angle):
                         ind_result = j - 1
                     else:
                         ind_result = j
                         
                     weigh = npy.sqrt(npy.sin(angle - theta0) ** 2 + npy.cos(angle - theta0) ** 2 / w1)
                     temp_dis = npy.hypot(points_fix[ind_fix, 0] - points_result[ind_result, 0], points_fix[ind_fix, 1] - points_result[ind_result, 1]) / weigh
                     #if area:
                     #    temp_dis /= max([area_result / area_fix, area_fix / area_result])
                     max_dis[cnt] = npy.max([max_dis[cnt], temp_dis])
                     mean_dis[cnt] += temp_dis
     
     cnt_total = npy.sum(cnt_num)
     
     mean_dis /= 90
     
     if area:
         for cnt in range(3):
             if area_mr[cnt] < area_us[cnt]:
                 rate = area_us[cnt] / area_mr[cnt]
             else:
                 rate = area_us[cnt] / area_mr[cnt]
             mean_dis[cnt] /= rate
     
     mean_whole = npy.sum(mean_dis)
     mean_dis /= cnt_num
     mean_dis[mean_dis != mean_dis] = 0 # Replace the NAN in the mean distance
     
     if self.gui is not None:
         message = "Error on Vessel 0: %0.2fmm (Total %d slices)\nError on Vessel 1: %0.2fmm (Total %d slices)\nError on Vessel 2: %0.2fmm (Total %d slices)\nWhole Error: %0.2fmm (Total %d slices)\n" \
             % (mean_dis[0], cnt_num[0], mean_dis[1], cnt_num[1], mean_dis[2], cnt_num[2], mean_whole / cnt_total, cnt_total) + \
             "-----------------------------------------------------------------------------\n" + \
             "Max Error on Vessel 0: %0.2fmm\nMax Error on Vessel 1: %0.2fmm\nMax Error on Vessel 2: %0.2fmm\nTotal Max Error: %0.2fmm" \
             % (max_dis[0], max_dis[1], max_dis[2], npy.max(max_dis));
         self.gui.showErrorMessage("Weighted Contour Registration Error", message)
     return mean_dis, mean_whole / cnt_total, max_dis, npy.max(max_dis)
示例#42
0
    def process(self, dataset, i):
        # ICP with contour without label
        print 'Register Data %s with ICP(contour) without label...' % self.ini.file.name_result[
            i]
        data, point, para, time = self.icp.register(dataset['fix'],
                                                    dataset['mov'],
                                                    0,
                                                    op=False,
                                                    isTime=True)
        resultData = db.ResultData(data,
                                   db.ImageInfo(dataset['fix'].info.data),
                                   point)
        resultData.info.addData('fix', 1)
        resultData.info.addData('move', 2)
        resultData.info.addData('transform', para)
        print 'Done!'
        mean_dis, mean_whole, max_dis, max_whole = self.surfaceerror.analysis(
            resultData, dataset['fix'].getPointSet('Contour').copy(),
            dataset['mov'].getPointSet('Contour').copy(),
            dataset['mov'].getPointSet('Mask').copy(),
            dataset['mov'].getResolution().tolist())
        print 'Contour Error Done! Whole mean is %0.2fmm.' % mean_whole
        dice_index, dice_index_all = self.areaerror.analysis(
            resultData, dataset['fix'].getPointSet('Contour').copy())
        print 'Area Error Done! Whole Dice index is %0.3f.' % dice_index_all

        self.sheet1.write(0, i + 2, self.ini.file.name_result[i])
        for j in range(3):
            self.sheet1.write(j + 1, i + 2, mean_dis[j])
            self.sheet1.write(j + 5, i + 2, max_dis[j])
            self.sheet1.write(j + 9, i + 2, dice_index[j])
        self.sheet1.write(4, i + 2, mean_whole)
        self.sheet1.write(8, i + 2, max_whole)
        self.sheet1.write(12, i + 2, dice_index_all)
        self.sheet1.write(13, i + 2, time)
        self.book.save(self.path + self.ini.file.savedir + 'snap_feature.xls')
        del data, point, resultData

        # ICP with centerline without label
        print 'Register Data %s with ICP(centerline) without label...' % self.ini.file.name_result[
            i]
        data, point, para, time = self.icp.register(dataset['fix'],
                                                    dataset['mov'],
                                                    1,
                                                    op=True,
                                                    isTime=True)
        resultData = db.ResultData(data,
                                   db.ImageInfo(dataset['fix'].info.data),
                                   point)
        resultData.info.addData('fix', 1)
        resultData.info.addData('move', 2)
        resultData.info.addData('transform', para)
        print 'Done!'
        mean_dis, mean_whole, max_dis, max_whole = self.surfaceerror.analysis(
            resultData, dataset['fix'].getPointSet('Contour').copy(),
            dataset['mov'].getPointSet('Contour').copy(),
            dataset['mov'].getPointSet('Mask').copy(),
            dataset['mov'].getResolution().tolist())
        print 'Contour Error Done! Whole mean is %0.2fmm.' % mean_whole
        dice_index, dice_index_all = self.areaerror.analysis(
            resultData, dataset['fix'].getPointSet('Contour').copy())
        print 'Area Error Done! Whole Dice index is %0.3f.' % dice_index_all

        self.sheet2.write(0, i + 2, self.ini.file.name_result[i])
        for j in range(3):
            self.sheet2.write(j + 1, i + 2, mean_dis[j])
            self.sheet2.write(j + 5, i + 2, max_dis[j])
            self.sheet2.write(j + 9, i + 2, dice_index[j])
        self.sheet2.write(4, i + 2, mean_whole)
        self.sheet2.write(8, i + 2, max_whole)
        self.sheet2.write(12, i + 2, dice_index_all)
        self.sheet2.write(13, i + 2, time)
        self.book.save(self.path + self.ini.file.savedir + 'snap_feature.xls')
        del data, point, resultData

        # ICP with contour with label
        print 'Register Data %s with ICP(contour) with label...' % self.ini.file.name_result[
            i]
        data, point, para, time = self.icp.register(dataset['fix'],
                                                    dataset['mov'],
                                                    0,
                                                    op=True,
                                                    isTime=True)
        resultData = db.ResultData(data,
                                   db.ImageInfo(dataset['fix'].info.data),
                                   point)
        resultData.info.addData('fix', 1)
        resultData.info.addData('move', 2)
        resultData.info.addData('transform', para)
        print 'Done!'
        mean_dis, mean_whole, max_dis, max_whole = self.surfaceerror.analysis(
            resultData, dataset['fix'].getPointSet('Contour').copy(),
            dataset['mov'].getPointSet('Contour').copy(),
            dataset['mov'].getPointSet('Mask').copy(),
            dataset['mov'].getResolution().tolist())
        print 'Contour Error Done! Whole mean is %0.2fmm.' % mean_whole
        dice_index, dice_index_all = self.areaerror.analysis(
            resultData, dataset['fix'].getPointSet('Contour').copy())
        print 'Area Error Done! Whole Dice index is %0.3f.' % dice_index_all

        self.sheet3.write(0, i + 2, self.ini.file.name_result[i])
        for j in range(3):
            self.sheet3.write(j + 1, i + 2, mean_dis[j])
            self.sheet3.write(j + 5, i + 2, max_dis[j])
            self.sheet3.write(j + 9, i + 2, dice_index[j])
        self.sheet3.write(4, i + 2, mean_whole)
        self.sheet3.write(8, i + 2, max_whole)
        self.sheet3.write(12, i + 2, dice_index_all)
        self.sheet3.write(13, i + 2, time)
        self.book.save(self.path + self.ini.file.savedir + 'snap_feature.xls')
        del data, point, resultData

        # ICP with centerline with label
        print 'Register Data %s with ICP(centerline) with label...' % self.ini.file.name_result[
            i]
        data, point, para, time = self.icp.register(dataset['fix'],
                                                    dataset['mov'],
                                                    1,
                                                    op=False,
                                                    isTime=True)
        resultData = db.ResultData(data,
                                   db.ImageInfo(dataset['fix'].info.data),
                                   point)
        resultData.info.addData('fix', 1)
        resultData.info.addData('move', 2)
        resultData.info.addData('transform', para)
        print 'Done!'
        mean_dis, mean_whole, max_dis, max_whole = self.surfaceerror.analysis(
            resultData, dataset['fix'].getPointSet('Contour').copy(),
            dataset['mov'].getPointSet('Contour').copy(),
            dataset['mov'].getPointSet('Mask').copy(),
            dataset['mov'].getResolution().tolist())
        print 'Contour Error Done! Whole mean is %0.2fmm.' % mean_whole
        dice_index, dice_index_all = self.areaerror.analysis(
            resultData, dataset['fix'].getPointSet('Contour').copy())
        print 'Area Error Done! Whole Dice index is %0.3f.' % dice_index_all

        self.sheet4.write(0, i + 2, self.ini.file.name_result[i])
        for j in range(3):
            self.sheet4.write(j + 1, i + 2, mean_dis[j])
            self.sheet4.write(j + 5, i + 2, max_dis[j])
            self.sheet4.write(j + 9, i + 2, dice_index[j])
        self.sheet4.write(4, i + 2, mean_whole)
        self.sheet4.write(8, i + 2, max_whole)
        self.sheet4.write(12, i + 2, dice_index_all)
        self.sheet4.write(13, i + 2, time)
        self.book.save(self.path + self.ini.file.savedir + 'time_feature.xls')
        del data, point, resultData
示例#43
0
    def analysis(self, data, point_data_fix=None, all=False):
        if point_data_fix is None:
            point_data_fix = self.gui.dataModel[
                data.getFixedIndex()].getPointSet('Contour').copy()
        point_data_result = data.getPointSet('Contour').copy()
        self.spacing = data.getResolution().tolist()
        self.spacing[
            2] = 1.0  # The resolution of z axis is nothing to do with the analysis
        point_data_fix[:, :3] *= self.spacing[:3]
        point_data_result[:, :3] *= self.spacing[:3]

        cnt_num = npy.array([0, 0, 0])
        mean_dis = npy.array([0.0, 0.0, 0.0])
        max_dis = npy.array([0.0, 0.0, 0.0])
        square_sum_dis = npy.array([0.0, 0.0, 0.0])
        if all:
            result = [{}, {}, {}]
            bif = db.getBifurcation(point_data_fix)

        for cnt in range(3):
            temp_result = point_data_result[npy.where(
                npy.round(point_data_result[:, -1]) == cnt)]
            temp_fix = point_data_fix[npy.where(
                npy.round(point_data_fix[:, -1]) == cnt)]
            if not temp_result.shape[0] or not temp_fix.shape[0]:
                continue
            zmin = int(
                npy.max([npy.min(temp_result[:, 2]),
                         npy.min(temp_fix[:, 2])]) + 0.5)
            zmax = int(
                npy.min([npy.max(temp_result[:, 2]),
                         npy.max(temp_fix[:, 2])]) + 0.5)

            for z in range(zmin, zmax + 1):
                data_fix = temp_fix[npy.where(npy.round(temp_fix[:, 2]) == z)]
                data_result = temp_result[npy.where(
                    npy.round(temp_result[:, 2]) == z)]
                if data_fix is not None and data_result is not None:
                    if data_fix.shape[0] == 0 or data_result.shape[0] == 0:
                        continue
                    cnt_num[cnt] += 1
                    #center_fix = npy.mean(data_fix[:, :2], axis = 0)
                    center_fix = calCentroidFromContour(data_fix[:, :2])[0]
                    #center_result = npy.mean(data_result[:, :2], axis = 0)
                    center_result = calCentroidFromContour(
                        data_result[:, :2])[0]
                    points_fix = getPointsOntheSpline(data_fix, center_fix,
                                                      900)
                    points_result = getPointsOntheSpline(
                        data_result, center_result, 900)

                    i = j = 0
                    for k in range(-44, 46):
                        angle = k * 4 / 180.0 * npy.pi
                        while i < 900 and points_fix[i, 2] < angle:
                            i += 1
                        if i == 900 or (i > 0 and angle - points_fix[i - 1, 2]
                                        < points_fix[i, 2] - angle):
                            ind_fix = i - 1
                        else:
                            ind_fix = i
                        while j < 900 and points_result[j, 2] < angle:
                            j += 1
                        if j == 900 or (j > 0
                                        and angle - points_result[j - 1, 2] <
                                        points_result[j, 2] - angle):
                            ind_result = j - 1
                        else:
                            ind_result = j
                        temp_dis = npy.hypot(
                            points_fix[ind_fix, 0] -
                            points_result[ind_result, 0],
                            points_fix[ind_fix, 1] -
                            points_result[ind_result, 1])
                        max_dis[cnt] = npy.max([max_dis[cnt], temp_dis])
                        mean_dis[cnt] += temp_dis
                        square_sum_dis[cnt] += temp_dis**2
                        if all:
                            result[cnt][z - bif] = result[cnt].get(
                                z - bif, 0) + temp_dis

        cnt_total = npy.sum(cnt_num)
        sd = npy.sqrt(
            npy.max([(square_sum_dis - mean_dis**2 / (90 * cnt_num)) /
                     (90 * cnt_num - 1), [0, 0, 0]],
                    axis=0))
        sd[sd != sd] = 0
        sd_all = npy.sqrt(
            npy.max([(npy.sum(square_sum_dis) - npy.sum(mean_dis)**2 /
                      (90 * cnt_total)) / (90 * cnt_total - 1), 0]))

        mean_dis /= 90
        mean_whole = npy.sum(mean_dis)
        mean_dis /= cnt_num
        mean_dis[
            mean_dis != mean_dis] = 0  # Replace the NAN in the mean distance

        if self.gui is not None:
            message = "Error on Vessel 0: %0.2fmm (SD = %0.2fmm, Total %d slices)\nError on Vessel 1: %0.2fmm (SD = %0.2fmm, Total %d slices)\nError on Vessel 2: %0.2fmm (SD = %0.2fmm, Total %d slices)\nWhole Error: %0.2fmm (SD = %0.2fmm, Total %d slices)\n" \
                % (mean_dis[0], sd[0], cnt_num[0], mean_dis[1], sd[1], cnt_num[1], mean_dis[2], sd[2], cnt_num[2], mean_whole / cnt_total, sd_all, cnt_total) + \
                "-----------------------------------------------------------------------------\n" + \
                "Max Error on Vessel 0: %0.2fmm\nMax Error on Vessel 1: %0.2fmm\nMax Error on Vessel 2: %0.2fmm\nTotal Max Error: %0.2fmm" \
                % (max_dis[0], max_dis[1], max_dis[2], npy.max(max_dis))
            self.gui.showErrorMessage("Contour Registration Error", message)

        if not all:
            return mean_dis, mean_whole / cnt_total, max_dis, npy.max(max_dis)
        else:
            for cnt in range(3):
                for x in result[cnt].keys():
                    result[cnt][x] /= 90
            return mean_dis, mean_whole / cnt_total, max_dis, npy.max(
                max_dis), result
    def register(self, fixedData, movingData, index = -1, discard = False, method = "EM_TPS", execute = True, isTime = False):
        if index == -1:
            index = self.gui.getDataIndex({'Contour': 0, 'Centerline': 1}, 'Select the object')
        if index is None:
            return None, None, None
        if index == 0:
            fixed_points = fixedData.getPointSet('Contour')
            moving_points = movingData.getPointSet('Contour')
        else:
            fixed_points = fixedData.getPointSet('Centerline')
            moving_points = movingData.getPointSet('Centerline')
        time1 = time.time()
        fixed_res = fixedData.getResolution().tolist()
        moving_res = movingData.getResolution().tolist()
        fixed_points = fixed_points.copy()[npy.where(fixed_points[:, -1] >= 0)]
        moving_points = moving_points.copy()[npy.where(moving_points[:, -1] >= 0)]
        # Use the bifurcation as the initial position
        fixed_bif = db.getBifurcation(fixed_points)
        moving_bif = db.getBifurcation(moving_points)
        if (fixed_bif < 0) or (moving_bif < 0):
            fixed_min = 0
        else:
            temp = moving_points[:, 2:]
            moving_delta = moving_bif - npy.min(temp[npy.where(npy.round(temp[:, 1]) == 0), 0])
        #fixed_min = 0
        
        # Augmentation of pointset
        fixed = fixed_points.copy()
        tmp_fix = fixedData.getPointSet('Centerline')
        tmp_fix = tmp_fix[tmp_fix[:, -1] >= 0].copy()
        ctrl_pts = gutil.getControlPoints(tmp_fix, 1.0 / fixed_res[2])
        moving = moving_points.copy()
        
        fixed = fixed[:, :3]
        moving = moving[:, :3]
        fixed[:, :3] *= fixed_res[:3]
        ctrl_pts *= fixed_res[:3]
        ctrl_pts_backup = ctrl_pts.copy()
        moving[:, :3] *= moving_res[:3]
        if (fixed_bif >= 0) and (moving_bif >= 0):
            fixed[:, 2] -= (fixed_bif * fixed_res[2] - moving_bif * moving_res[2])
            ctrl_pts[:, 2] -= (fixed_bif * fixed_res[2] - moving_bif * moving_res[2])
        #print fixed.shape[0], moving.shape[0]
        
        eg.initial_data(fixed, moving, ctrl_pts)
        
        if execute:
            code = eg.run_executable(method = method)
            #print code
            if code != 0:
                print "GMM Fail!"
                return None, None, None
        
        trans, para, para2 = eg.get_final_result(methodname = method)
        time2 = time.time()
        
        # Clear the temp files
        #eg.clear_temp_file()
        
        # Get the result transformation parameters
        if method == 'rigid':
            S1 = ml.eye(3, dtype = npy.float32) * para2[3]
            C = npy.asmatrix(para2[:3]).T
            
            C2 = npy.asmatrix(para2[4:7]).T
            T0 = npy.asmatrix(para[4:]).T
            R = util.quaternion2rotation(para[:4])
            
            T = S1 * T0 + C2 - C
            if (fixed_bif >= 0) and (moving_bif >= 0):
                T[2] += (fixed_bif * fixed_res[2] - moving_bif * moving_res[2])
            
            moving_points = movingData.getPointSet('Contour').copy()
            moving_center = movingData.getPointSet('Centerline').copy()                
            #new_trans_points, result_center_points = util.resliceTheResultPoints(moving_points, moving_center, 20, moving_res, fixed_res, discard, R, T, C)
            new_trans_points = util.applyTransformForPoints(moving_points, moving_res, fixed_res, R, T, C)
            result_center_points = util.applyTransformForPoints(moving_center, moving_res, fixed_res, R, T, C)
            
            
            T = -T
            T = R * T
            
            """
            # Copy the output points of GMMREG for test
            new_trans_points = trans
            
            if (fixed_bif >= 0) and (moving_bif >= 0):
                new_trans_points[:, 2] += (fixed_bif * fixed_res[2] - moving_bif * moving_res[2])
                
            new_trans_points[:, :3] /= fixed_res[:3]
            new_trans_points = npy.insert(new_trans_points, [new_trans_points.shape[1]], moving_points[:, -1].reshape(-1, 1), axis = 1)
            new_trans_points = npy.append(new_trans_points, npy.array([[-1, -1, -1, -1]]), axis = 0)
            #result_center_points = movingData.getPointSet('Centerline').copy()
            result_center_points = movingData.getPointSet('Contour').copy()  
            """
            
            transform = sitk.Transform(3, sitk.sitkAffine)
            para = R.reshape(1, -1).tolist()[0] + T.T.tolist()[0]
            transform.SetParameters(para)
            transform.SetFixedParameters(C.T.tolist()[0])
            
            #movingImage = movingData.getSimpleITKImage()
            #fixedImage = fixedData.getSimpleITKImage()
            #resultImage = sitk.Resample(movingImage, fixedImage, transform, sitk.sitkLinear, 0, sitk.sitkFloat32)
            
            if isTime:
                #return sitk.GetArrayFromImage(resultImage), {'Contour': new_trans_points, 'Centerline': result_center_points}, para + C.T.tolist()[0], time2 - time1
                return movingData.getData().copy(), {'Contour': new_trans_points, 'Centerline': result_center_points}, para + C.T.tolist()[0], time2 - time1
            #return sitk.GetArrayFromImage(resultImage), {'Contour': new_trans_points, 'Centerline': result_center_points}, para + C.T.tolist()[0]
            return movingData.getData().copy(), {'Contour': new_trans_points, 'Centerline': result_center_points}, para + C.T.tolist()[0]
            
        else: # EM_TPS
            moving_points = movingData.getPointSet('Contour').copy()
            moving_points = moving_points[npy.where(moving_points[:, 0] >= 0)]
            moving = moving_points[:, :3].copy()
            moving *= moving_res[:3]
            m = moving.shape[0]
            n = ctrl_pts.shape[0]
            
            M = ml.mat(moving.copy())
            
            C2 = npy.asmatrix(para2[4:7])
            C2 = ml.repmat(C2, m, 1)
            
            C3 = npy.asmatrix(para2[7:])
            C3 = ml.repmat(C3, n, 1)
            ctrl_pts -= C3
            ctrl_pts /= para2[3]
            
            C = npy.asmatrix(para2[:3])
            C = ml.repmat(C, m, 1)
            moving -= C
            moving /= para2[3]
            
            basis = ml.zeros([m, n], dtype = npy.float32)
            basis[:, 0] = 1
            basis[:, 1:4] = moving
            
            U = gutil.ComputeTPSKernel(moving, ctrl_pts)
            basis[:, 4:] = U * ml.mat(trans)
            #print npy.array(basis)
            
            T = basis * ml.mat(para)
            T *= para2[3]
            T += C2 - C
            
            
            if (fixed_bif >= 0) and (moving_bif >= 0):
                T[:, 2] += (fixed_bif * fixed_res[2] - moving_bif * moving_res[2])
            
            M += T
            new_trans_points = npy.array(M).copy()
            new_trans_points[:, :3] /= fixed_res[:3]
            new_trans_points = npy.insert(new_trans_points, [new_trans_points.shape[1]], moving_points[:, -1].reshape(-1, 1), axis = 1)
            new_trans_points = npy.append(new_trans_points, npy.array([[-1, -1, -1, -1]]), axis = 0)
            
            moving_points = movingData.getPointSet('Centerline').copy()
            moving_points = moving_points[npy.where(moving_points[:, 0] >= 0)]
            moving = moving_points[:, :3].copy()
            moving *= moving_res[:3]
            m = moving.shape[0]

            M = ml.mat(moving.copy())
            
            C2 = npy.asmatrix(para2[4:7])
            C2 = ml.repmat(C2, m, 1)
            
            C = npy.asmatrix(para2[:3])
            C = ml.repmat(C, m, 1)
            moving -= C
            moving /= para2[3]
            
            basis = ml.zeros([m, n], dtype = npy.float32)
            basis[:, 0] = 1
            basis[:, 1:4] = moving
            
            U = gutil.ComputeTPSKernel(moving, ctrl_pts)
            basis[:, 4:] = U * ml.mat(trans)
            #print npy.array(basis)
            
            T = basis * ml.mat(para)
            T *= para2[3]
            T += C2 - C
            
            if (fixed_bif >= 0) and (moving_bif >= 0):
                T[:, 2] += (fixed_bif * fixed_res[2] - moving_bif * moving_res[2])
            
            M += T
            result_center_points = npy.array(M).copy()
            result_center_points[:, :3] /= fixed_res[:3]
            result_center_points = npy.insert(result_center_points, [result_center_points.shape[1]], moving_points[:, -1].reshape(-1, 1), axis = 1)
            result_center_points = npy.append(result_center_points, npy.array([[-1, -1, -1, -1]]), axis = 0)
            #print result_center_points
            
            moving = ctrl_pts_backup.copy()
            m = moving.shape[0]
            M = ml.mat(moving.copy())
            
            C = npy.asmatrix(para2[:3])
            C = ml.repmat(C, m, 1)
            moving -= C
            moving /= para2[3]

            C2 = npy.asmatrix(para2[4:7])
            C2 = ml.repmat(C2, m, 1)
            
            basis = ml.zeros([m, n], dtype = npy.float32)
            basis[:, 0] = 1
            basis[:, 1:4] = moving
            
            U = gutil.ComputeTPSKernel(moving, ctrl_pts)
            basis[:, 4:] = U * ml.mat(trans)
            #print npy.array(basis)
            
            T = basis * ml.mat(para)
            T *= para2[3]
            T += C2 - C
            
            if (fixed_bif >= 0) and (moving_bif >= 0):
                T[:, 2] += (fixed_bif * fixed_res[2] - moving_bif * moving_res[2])
            
            M += T
            result_ctrl = npy.array(M).copy()
            #print result_ctrl
            
            image_type = fixedData.getITKImageType()
            transform_type = itk.ThinPlateSplineKernelTransform.D3
            transform = transform_type.New()
            pointset_type = itk.PointSet.PD33S
            source_pointset = pointset_type.New()
            target_pointset = pointset_type.New()
            count = 0
            for point in ctrl_pts_backup:
                tmp_point = itk.Point.D3()
                tmp_point[0] = point[0]
                tmp_point[1] = point[1]
                tmp_point[2] = point[2]
                source_pointset.SetPoint(count, tmp_point)
                count += 1
            count = 0
            for point in ctrl_pts_backup:
                tmp_point = itk.Point.D3()
                tmp_point[0] = point[0]
                tmp_point[1] = point[1]
                tmp_point[2] = point[2]
                target_pointset.SetPoint(count, tmp_point)
                count += 1
                
            transform.SetSourceLandmarks(source_pointset)
            transform.SetTargetLandmarks(target_pointset)
            transform.ComputeWMatrix()
            
            """
            # Test for TPS Transform
            moving_points = movingData.getPointSet('Centerline').copy()
            moving_points = moving_points[npy.where(moving_points[:, 0] >= 0)]
            moving = moving_points[:, :3].copy()
            moving *= moving_res[:3]
            for point in moving:
                tmp_point = itk.Point.D3()
                tmp_point[0] = point[0]
                tmp_point[1] = point[1]
                tmp_point[2] = point[2]
                rst_point = transform.TransformPoint(tmp_point)
                point[0] = rst_point[0]
                point[1] = rst_point[1]
                point[2] = rst_point[2]
            moving /= fixed_res[:3]
            print moving
            """
            
#            image_type = fixedData.getITKImageType()
#            resampler = itk.ResampleImageFilter[image_type, image_type].New()
#            movingImage = movingData.getITKImage()
#            fixedImage = fixedData.getITKImage()
#            
#            resampler.SetTransform(transform)
#            resampler.SetInput(movingImage)
#            
#            region = fixedImage.GetLargestPossibleRegion()
#            
#            resampler.SetSize(region.GetSize())
#            resampler.SetOutputSpacing(fixedImage.GetSpacing())
#            resampler.SetOutputDirection(fixedImage.GetDirection())
#            resampler.SetOutputOrigin(fixedImage.GetOrigin())
#            resampler.SetDefaultPixelValue(0)
#            resampler.Update()
#        
#            outputImage = resampler.GetOutput()
#            image = itk.PyBuffer[image_type].GetArrayFromImage(outputImage)
            if isTime:
                return movingData.getData().copy(), {'Contour': new_trans_points, 'Centerline': result_center_points}, [0, 0, 0], time2 - time1
            return movingData.getData().copy(), {'Contour': new_trans_points, 'Centerline': result_center_points}, [0, 0, 0]
示例#45
0
 def process(self, dataset):
     savepath = self.path + self.ini.file.savedir
     db.saveMatData(savepath + 'MR_%d_Merge_Full.mat' % self.cnt, dataset,
                    0)
     db.saveMatData(savepath + 'MR_%d_SNAP_Full.mat' % self.cnt, dataset, 1)
 def register(self, fixedData, movingData, discard = False):
     index = self.gui.getDataIndex({'Contour': 0, 'Centerline': 1}, 'Select the object')
     if index is None:
         return None, None, None
     if index == 0:
         fixed_points = fixedData.getPointSet('Contour')
         moving_points = movingData.getPointSet('Contour')
     else:
         fixed_points = fixedData.getPointSet('Centerline')
         moving_points = movingData.getPointSet('Centerline')
     
     fixed_res = fixedData.getResolution().tolist()
     moving_res = movingData.getResolution().tolist()
     fixed_points = fixed_points.copy()[npy.where(fixed_points[:, 0] >= 0)]
     moving_points = moving_points.copy()[npy.where(moving_points[:, 0] >= 0)]
     # Use the bifurcation as the initial position
     fixed_bif = db.getBifurcation(fixed_points)
     moving_bif = db.getBifurcation(moving_points)
     if (fixed_bif < 0) or (moving_bif < 0):
         fixed_min = 0
     else:
         temp = moving_points[:, 2:]
         moving_delta = moving_bif - npy.min(temp[npy.where(npy.round(temp[:, 1]) == 0), 0])
         fixed_min = fixed_bif - moving_delta * moving_res[-1] / fixed_res[-1]
     #print moving_res
     #print fixed_res
     
     # Augmentation of pointset
     fixed = fixed_points[npy.where(fixed_points[:, 2] >= fixed_min)]
     moving = moving_points.copy()
     fixed = util.augmentPointset(fixed, int(fixed_res[-1] / moving_res[-1] + 0.5), moving.shape[0], fixed_bif)
     moving = util.augmentPointset(moving, int(moving_res[-1] / fixed_res[-1] + 0.5), fixed.shape[0], moving_bif)
     
     fixed = fixed[:, :3]
     moving = moving[:, :3]
     fixed[:, :3] *= fixed_res[:3]
     moving[:, :3] *= moving_res[:3]
     if (fixed_bif >= 0) and (moving_bif >= 0):
         fixed[:, 2] -= (fixed_bif * fixed_res[2] - moving_bif * moving_res[2])
     print fixed.shape[0], moving.shape[0]
     #return None, None, None
     
     sourcePoints = vtk.vtkPoints()
     sourceVertices = vtk.vtkCellArray()
     for x in moving:
         id = sourcePoints.InsertNextPoint(x[0], x[1], x[2])
         sourceVertices.InsertNextCell(1)
         sourceVertices.InsertCellPoint(id)
     source = vtk.vtkPolyData()
     source.SetPoints(sourcePoints)
     source.SetVerts(sourceVertices)
     
     targetPoints = vtk.vtkPoints()
     targetVertices = vtk.vtkCellArray()
     for x in fixed:
         id = targetPoints.InsertNextPoint(x[0], x[1], x[2])
         targetVertices.InsertNextCell(1)
         targetVertices.InsertCellPoint(id)
     target = vtk.vtkPolyData()
     target.SetPoints(targetPoints)
     target.SetVerts(targetVertices)
     
     icp = vtk.vtkIterativeClosestPointTransform()
     icp.SetSource(source)
     icp.SetTarget(target)
     icp.GetLandmarkTransform().SetModeToRigidBody()
     icp.Modified()
     icp.Update()
     
     icp_filter = vtk.vtkTransformPolyDataFilter()
     icp_filter.SetInput(source)
     icp_filter.SetTransform(icp)
     icp_filter.Update()
     
     # Get the result transformation parameters
     matrix = icp.GetMatrix()
     T = ml.mat([matrix.GetElement(0, 3), matrix.GetElement(1, 3), matrix.GetElement(2, 3)]).T;
     R = ml.mat([[matrix.GetElement(0, 0), matrix.GetElement(0, 1), matrix.GetElement(0, 2)], 
                 [matrix.GetElement(1, 0), matrix.GetElement(1, 1), matrix.GetElement(1, 2)], 
                 [matrix.GetElement(2, 0), matrix.GetElement(2, 1), matrix.GetElement(2, 2)]]).I;
     if (fixed_bif >= 0) and (moving_bif >= 0):
         T[2] += (fixed_bif * fixed_res[2] - moving_bif * moving_res[2])
     
     moving_points = movingData.getPointSet('Contour').copy()
     moving_center = movingData.getPointSet('Centerline').copy()                
     new_trans_points, result_center_points = util.resliceTheResultPoints(moving_points, moving_center, 20, moving_res, fixed_res, discard, R, T)
     
     T = -T
     T = R * T
     
     transform = sitk.Transform(3, sitk.sitkAffine)
     para = R.reshape(1, -1).tolist()[0] + T.T.tolist()[0]
     transform.SetParameters(para)
     
     movingImage = movingData.getSimpleITKImage()
     fixedImage = fixedData.getSimpleITKImage()
     resultImage = sitk.Resample(movingImage, fixedImage, transform, sitk.sitkLinear, 0, sitk.sitkFloat32)
     
     return sitk.GetArrayFromImage(resultImage), {'Contour': trans_points, 'Centerline': result_center_points}, para + [0, 0, 0]
示例#47
0
 def process(self, dataset, i):
     def autoDetectContour(point, cnt, start, end, delta, res, type):
         self.new_points = npy.append(self.new_points, point, 0)
         points = point[:, :-2]
         d = 20
         count = 0
         for i in range(start + delta, end + delta, delta):
             center = calCentroidFromContour(points).reshape(2)
             image = dataset[type].getData()[i, :, :].transpose().copy()
             image = (image - npy.min(image)) / (npy.max(image) - npy.min(image)) * 255
             down = npy.max([npy.ceil(center[0] - d / res[0]), 0])
             up = npy.min([npy.floor(center[0] + d / res[0]), image.shape[0]])
             left = npy.max([npy.ceil(center[1] - d / res[1]), 0])
             right = npy.min([npy.floor(center[1] + d / res[1]), image.shape[1]])
             crop_image = image[down : up, left : right]
             center -= [down, left]
             
             result = ac_segmentation(center, crop_image)
             
             a1 = ac_area(points.transpose(), image.shape)
             a2 = ac_area(result, crop_image.shape)
             rate = a2 * 1.0 / a1
             if rate >= min(1.5 + count * 0.2, 2.1) or rate <= 0.7:
                 temp_array = points.copy()
                 if cnt != 1 and rate > 0.7:
                     count += 1
             else:
                 temp_array = result.transpose().copy()
                 temp_array[:, :2] += [down, left]
                 count = 0
             points = temp_array.copy()
             
             
             temp_array = npy.insert(temp_array, 2, [[i], [cnt]], 1)
             self.new_points = npy.append(self.new_points, temp_array, 0)
             
             sys.stdout.write(str(i) + ',')
             sys.stdout.flush()
         print ' '
         
     # Segmentation of data
     print 'Segment Data %s...' % self.ini.file.name_result[i]
     tmp = dataset['fix'].pointSet.data['Contour']
     tmp = tmp[tmp[:, 0] >= 0]
     
     self.new_points = npy.array([[-1, -1, -1, -1]], dtype = npy.float32)
     bottom = int(npy.round(npy.min(tmp[:, 2])))
     bif = int(db.getBifurcation(tmp) + 0.5)
     up = int(npy.round(npy.max(tmp[:, 2])))
     bottom += (bif - bottom) / 2
     up -= (up - bif) / 2
     
     point_vital = [0] * 3
     point_vital[0] = tmp[(npy.round(tmp[:, -1]) == 0) & (npy.round(tmp[:, 2]) == bottom)].copy()
     point_vital[1] = tmp[(npy.round(tmp[:, -1]) == 1) & (npy.round(tmp[:, 2]) == up)].copy()
     point_vital[2] = tmp[(npy.round(tmp[:, -1]) == 2) & (npy.round(tmp[:, 2]) == up)].copy()
     
     autoDetectContour(point_vital[0], 0, bottom, bif, 1, dataset['fix'].getResolution().tolist(), 'fix')
     autoDetectContour(point_vital[1], 1, up, bif, -1, dataset['fix'].getResolution().tolist(), 'fix')
     autoDetectContour(point_vital[2], 2, up, bif, -1, dataset['fix'].getResolution().tolist(), 'fix')
     print ' '
     print 'Finish segmentation for fix data. '
     pointset = {'Contour': self.new_points}
     dataset['fix'].pointSet.data['Centerline'] = calCenterlineFromContour(pointset)
     self.new_points_fix = self.new_points.copy()
     # For mov data
     tmp = dataset['mov'].pointSet.data['Contour']
     tmp = tmp[tmp[:, 0] >= 0]
     
     self.new_points = npy.array([[-1, -1, -1, -1]], dtype = npy.float32)
     bottom = int(npy.round(npy.min(tmp[:, 2])))
     bif = int(db.getBifurcation(tmp) + 0.5)
     up = int(npy.round(npy.max(tmp[:, 2])))
     bottom += (bif - bottom) / 2
     up -= (up - bif) / 2
     
     point_vital = [0] * 3
     point_vital[0] = tmp[(npy.round(tmp[:, -1]) == 0) & (npy.round(tmp[:, 2]) == bottom)].copy()
     point_vital[1] = tmp[(npy.round(tmp[:, -1]) == 1) & (npy.round(tmp[:, 2]) == up)].copy()
     point_vital[2] = tmp[(npy.round(tmp[:, -1]) == 2) & (npy.round(tmp[:, 2]) == up)].copy()
         
     autoDetectContour(point_vital[0], 0, bottom, bif, 1, dataset['mov'].getResolution().tolist(), 'mov')
     autoDetectContour(point_vital[1], 1, up, bif, -1, dataset['mov'].getResolution().tolist(), 'mov')
     autoDetectContour(point_vital[2], 2, up, bif, -1, dataset['mov'].getResolution().tolist(), 'mov')
     print ' '
     print 'Finish segmentation for mov data. '
     pointset = {'Contour': self.new_points}
     dataset['mov'].pointSet.data['Centerline'] = calCenterlineFromContour(pointset)
     self.new_points_mov = self.new_points.copy()
     
     # ICP with centerline without label
     print 'Register Data %s with ICP(centerline) without label...' % self.ini.file.name_result[i]
     data, point, para = self.icp.register(dataset['fix'], dataset['mov'], 1, op = True) 
     resultData = db.ResultData(data, db.ImageInfo(dataset['fix'].info.data), point)
     resultData.info.addData('fix', 1)
     resultData.info.addData('move', 2)
     resultData.info.addData('transform', para)
     print 'Done!'
     mean_dis, mean_whole, max_dis, max_whole = self.surfaceerror.analysis(resultData, dataset['fix'].getPointSet('Contour').copy(), dataset['mov'].getPointSet('Contour').copy(), dataset['mov'].getPointSet('Mask').copy(), dataset['mov'].getResolution().tolist())
     print 'Contour Error Done! Whole mean is %0.2fmm.' % mean_whole
     dice_index, dice_index_all = self.areaerror.analysis(resultData, dataset['fix'].getPointSet('Contour').copy())
     print 'Area Error Done! Whole Dice index is %0.3f.' % dice_index_all
     
     self.sheet2.write(0, i + 2, self.ini.file.name_result[i])
     for j in range(3):
         self.sheet2.write(j + 1, i + 2, mean_dis[j])
         self.sheet2.write(j + 5, i + 2, max_dis[j])
         self.sheet2.write(j + 9, i + 2, dice_index[j])
     self.sheet2.write(4, i + 2, mean_whole)
     self.sheet2.write(8, i + 2, max_whole)
     self.sheet2.write(12, i + 2, dice_index_all)
     self.book.save(self.path + self.ini.file.savedir + 'multicontrast_seg_feature.xls')
     del data, point, resultData
     
     # ICP with centerline with label
     print 'Register Data %s with ICP(centerline) with label...' % self.ini.file.name_result[i]
     data, point, para = self.icp.register(dataset['fix'], dataset['mov'], 1, op = False) 
     resultData = db.ResultData(data, db.ImageInfo(dataset['fix'].info.data), point)
     resultData.info.addData('fix', 1)
     resultData.info.addData('move', 2)
     resultData.info.addData('transform', para)
     print 'Done!'
     mean_dis, mean_whole, max_dis, max_whole = self.surfaceerror.analysis(resultData, dataset['fix'].getPointSet('Contour').copy(), dataset['mov'].getPointSet('Contour').copy(), dataset['mov'].getPointSet('Mask').copy(), dataset['mov'].getResolution().tolist())
     print 'Contour Error Done! Whole mean is %0.2fmm.' % mean_whole
     dice_index, dice_index_all = self.areaerror.analysis(resultData, dataset['fix'].getPointSet('Contour').copy())
     print 'Area Error Done! Whole Dice index is %0.3f.' % dice_index_all
     
     self.sheet4.write(0, i + 2, self.ini.file.name_result[i])
     for j in range(3):
         self.sheet4.write(j + 1, i + 2, mean_dis[j])
         self.sheet4.write(j + 5, i + 2, max_dis[j])
         self.sheet4.write(j + 9, i + 2, dice_index[j])
     self.sheet4.write(4, i + 2, mean_whole)
     self.sheet4.write(8, i + 2, max_whole)
     self.sheet4.write(12, i + 2, dice_index_all)
     self.book.save(self.path + self.ini.file.savedir + 'multicontrast_seg_feature.xls')
     del data, point, resultData
     
     fix_points = dataset['fix'].getPointSet('Contour').copy()
     dataset['fix'].pointSet.data['Contour'] = self.new_points_fix
     mov_points = dataset['mov'].getPointSet('Contour').copy()
     dataset['mov'].pointSet.data['Contour'] = self.new_points_mov
     print 'Saving Data %s...' % self.ini.file.name_result[i]
     db.saveMatData(self.path + self.ini.file.savedir + self.ini.file.name_result[i] + '_snap.mat', [dataset['fix']], 0)
     db.saveMatData(self.path + self.ini.file.savedir + self.ini.file.name_result[i] + '_merge.mat', [dataset['mov']], 0)
     print 'Done!'
     
     # ICP with contour without label
     print 'Register Data %s with ICP(contour) without label...' % self.ini.file.name_result[i]
     data, point, para = self.icp.register(dataset['fix'], dataset['mov'], 0, op = False) 
     resultData = db.ResultData(data, db.ImageInfo(dataset['fix'].info.data), point)
     resultData.info.addData('fix', 1)
     resultData.info.addData('move', 2)
     resultData.info.addData('transform', para)
     print 'Done!'
     mean_dis, mean_whole, max_dis, max_whole = self.surfaceerror.analysis(resultData, fix_points.copy(), mov_points.copy(), dataset['mov'].getPointSet('Mask').copy(), dataset['mov'].getResolution().tolist())
     print 'Contour Error Done! Whole mean is %0.2fmm.' % mean_whole
     para = resultData.info.getData('transform')
     R = ml.mat(para[:9]).reshape(3, 3)
     T = ml.mat(para[9:12]).T
     T = R.I * T
     T = -T
     tmp_con, result_center_points = util.resliceTheResultPoints(mov_points, None, 20, dataset['mov'].getResolution().tolist(), 
         dataset['fix'].getResolution().tolist(), False, R, T)
     resultData.pointSet.data['Contour'] = tmp_con
     dice_index, dice_index_all = self.areaerror.analysis(resultData, fix_points.copy())
     print 'Area Error Done! Whole Dice index is %0.3f.' % dice_index_all
     
     self.sheet1.write(0, i + 2, self.ini.file.name_result[i])
     for j in range(3):
         self.sheet1.write(j + 1, i + 2, mean_dis[j])
         self.sheet1.write(j + 5, i + 2, max_dis[j])
         self.sheet1.write(j + 9, i + 2, dice_index[j])
     self.sheet1.write(4, i + 2, mean_whole)
     self.sheet1.write(8, i + 2, max_whole)
     self.sheet1.write(12, i + 2, dice_index_all)
     self.book.save(self.path + self.ini.file.savedir + 'multicontrast_seg_feature.xls')
     del data, point, resultData
     
     # ICP with contour with label
     print 'Register Data %s with ICP(contour) with label...' % self.ini.file.name_result[i]
     data, point, para = self.icp.register(dataset['fix'], dataset['mov'], 0, op = True) 
     resultData = db.ResultData(data, db.ImageInfo(dataset['fix'].info.data), point)
     resultData.info.addData('fix', 1)
     resultData.info.addData('move', 2)
     resultData.info.addData('transform', para)
     print 'Done!'
     mean_dis, mean_whole, max_dis, max_whole = self.surfaceerror.analysis(resultData, fix_points.copy(), mov_points.copy(), dataset['mov'].getPointSet('Mask').copy(), dataset['mov'].getResolution().tolist())
     print 'Contour Error Done! Whole mean is %0.2fmm.' % mean_whole
     para = resultData.info.getData('transform')
     R = ml.mat(para[:9]).reshape(3, 3)
     T = ml.mat(para[9:12]).T
     T = R.I * T
     T = -T
     tmp_con, result_center_points = util.resliceTheResultPoints(mov_points, None, 20, dataset['mov'].getResolution().tolist(), 
         dataset['fix'].getResolution().tolist(), False, R, T)
     resultData.pointSet.data['Contour'] = tmp_con
     dice_index, dice_index_all = self.areaerror.analysis(resultData, fix_points.copy())
     print 'Area Error Done! Whole Dice index is %0.3f.' % dice_index_all
     
     self.sheet3.write(0, i + 2, self.ini.file.name_result[i])
     for j in range(3):
         self.sheet3.write(j + 1, i + 2, mean_dis[j])
         self.sheet3.write(j + 5, i + 2, max_dis[j])
         self.sheet3.write(j + 9, i + 2, dice_index[j])
     self.sheet3.write(4, i + 2, mean_whole)
     self.sheet3.write(8, i + 2, max_whole)
     self.sheet3.write(12, i + 2, dice_index_all)
     self.book.save(self.path + self.ini.file.savedir + 'multicontrast_seg_feature.xls')
     del data, point, resultData
     
     del self.new_points, fix_points, self.new_points_fix, self.new_points_mov, mov_points, tmp_con, result_center_points
示例#48
0
 def process(self, dataset):
     savepath = self.path + self.ini.file.savedir
     db.saveMatData(savepath + 'MR_%d_Merge_Full.mat' % self.cnt, dataset, 0)
     db.saveMatData(savepath + 'MR_%d_SNAP_Full.mat' % self.cnt, dataset, 1)
 def register(self, fixedData, movingData, regPara = [(40.0, 1000.0, "SSD")], w2 = 1.0, true_fixed_points = None, true_moving_points = None): # For simple test
     # Initial data
     fixed_res = fixedData.getResolution().tolist()
     moving_res = movingData.getResolution().tolist()
     
     fixed_points = fixedData.getPointSet('Contour')
     moving_points = movingData.getPointSet('Contour')
     fixed_points_cen = fixedData.getPointSet('Centerline')
     moving_points_cen = movingData.getPointSet('Centerline')
     
     fixed_points_ori = fixed_points.copy()[npy.where(fixed_points[:, 0] >= 0)]
     moving_points_ori = moving_points.copy()[npy.where(moving_points[:, 0] >= 0)]
     fixed_points_cen_ori = fixed_points_cen.copy()[npy.where(fixed_points_cen[:, 0] >= 0)]
     moving_points_cen_ori = moving_points_cen.copy()[npy.where(moving_points_cen[:, 0] >= 0)]
     
     if true_fixed_points is None:
         true_fixed_points = fixed_points_ori
     if true_moving_points is None:
         true_moving_points = moving_points_ori
     
     fixed_points = fixed_points_ori.copy()
     moving_points = moving_points_ori.copy()
     fixed_points_cen = fixed_points_cen_ori.copy()
     moving_points_cen = moving_points_cen_ori.copy()
     
     fix_img = fixedData.getData()
     mov_img = movingData.getData()
     
     init_time = 0.0
     time1 = time.time()
     # Calculate the initial rigid transformation for 9 points T0
     fix_key_point = eutil.getKeyPoints(fixed_points_cen, fixed_res)
     mov_key_point = eutil.getKeyPoints(moving_points_cen, moving_res)
     T0, mov_bif = eutil.getRigidTransform(fix_key_point, mov_key_point) # 4 * 4 Matrix
     moving_points = eutil.applyRigidTransformOnPoints(moving_points, moving_res, T0)
     moving_points_cen_result = eutil.applyRigidTransformOnPoints(moving_points_cen, moving_res, T0)
     crop_fixed_index, crop_moving_index = eutil.cropCenterline(fixed_points_cen, moving_points_cen_result, fixed_res, moving_res, fix_key_point[0, 2] / fixed_res[2], mov_bif[2] / moving_res[2])
     
     # Use GMMREG for centerline-based rigid registration T1
     gmm = GmmregPointsetRegistration(self.gui)
     new_fixedData = db.BasicData(fix_img, db.ImageInfo(fixedData.getInfo().data), 
         {'Contour': fixed_points, 'Centerline': fixed_points_cen[crop_fixed_index]})
     new_movingData = db.BasicData(mov_img, db.ImageInfo(movingData.getInfo().data), 
         {'Contour': moving_points, 'Centerline': moving_points_cen_result[crop_moving_index]})
     tmp_img, points, para = gmm.register(new_fixedData, new_movingData, 1, False, "rigid")
     T1 = eutil.getMatrixFromGmmPara(para)
     T_init = T0 * T1
     moving_points = points['Contour'].copy()
     moving_points_cen_result = points['Centerline'].copy()
     del new_movingData
     
     # Use GMMREG for centerline-based TPS registration
     new_movingData = db.BasicData(mov_img, db.ImageInfo(fixedData.getInfo().data), 
         {'Contour': moving_points, 'Centerline': moving_points_cen_result}) # The image has been resampled into fixed resolution
     tmp_img, points, para = gmm.register(new_fixedData, new_movingData, 1, False, "EM_TPS")
     result_points_cen = points['Centerline'].copy()
     result_points_cen = result_points_cen[result_points_cen[:, -1] >= 0]
     result_points_cen[:, :3] *= fixed_res
     del new_movingData
     del new_fixedData
     del moving_points_cen_result
     
     # Save the images for Elastix registration
     ee.writeImageFile(fixedData, "fix")
     ee.writeImageFile(movingData, "mov")
     fix_binary_mask = eutil.getBinaryImageFromSegmentation(fix_img, fixed_points_ori)
     fix_binary_data = db.BasicData(fix_binary_mask, db.ImageInfo(fixedData.getInfo().data))
     ee.writeImageFile(fix_binary_data, "fixmm")
     del fix_binary_data
     del fix_binary_mask
     fix_binary_mask = eutil.getBinaryImageFromSegmentation(fix_img, true_fixed_points)
     fix_binary_data = db.BasicData(fix_binary_mask, db.ImageInfo(fixedData.getInfo().data))
     ee.writeImageFile(fix_binary_data, "fixmmm")
     del fix_binary_data
     del fix_binary_mask
     mov_binary_mask = eutil.getBinaryImageFromSegmentation(mov_img, moving_points_ori)
     mov_binary_data = db.BasicData(mov_binary_mask, db.ImageInfo(movingData.getInfo().data))
     ee.writeImageFile(mov_binary_data, "movmm")
     del mov_binary_data
     del mov_binary_mask
     mov_binary_mask = eutil.getBinaryImageFromSegmentation(mov_img, true_moving_points)
     mov_binary_data = db.BasicData(mov_binary_mask, db.ImageInfo(movingData.getInfo().data))
     ee.writeImageFile(mov_binary_data, "movmmm")
     del mov_binary_data
     del mov_binary_mask
     
     fix_binary_mask = eutil.getMaskFromCenterline(fix_img, fixed_points_cen_ori, fixed_res)
     fix_binary_data = db.BasicData(fix_binary_mask, db.ImageInfo(fixedData.getInfo().data))
     ee.writeImageFile(fix_binary_data, "fixm")
     del fix_binary_data
     del fix_binary_mask
     mov_binary_mask = eutil.getMaskFromCenterline(mov_img, moving_points_cen_ori, moving_res)
     mov_binary_data = db.BasicData(mov_binary_mask, db.ImageInfo(movingData.getInfo().data))
     ee.writeImageFile(mov_binary_data, "movm")
     del mov_binary_data
     del mov_binary_mask
     
     tmp = moving_points_cen.copy()
     tmp[:, :3] *= moving_res
     ee.writePointsetFile(tmp[crop_moving_index], "movp.txt")
     ee.writePointsetFile(result_points_cen, "fixp.txt")
     
     init_para_inv = eutil.getElastixParaFromMatrix(T_init.I)
     ee.writeTransformFile(init_para_inv, fix_img.shape, fixed_res, type = "MI") # For transformation of image
     ee.writeTransformFile(init_para_inv, fix_img.shape, fixed_res, "transparassd.txt") # For transformation of image
     init_para = eutil.getElastixParaFromMatrix(T_init)
     ee.writeTransformFile(init_para, fix_img.shape, fixed_res, "transpara2.txt") # For transformation of points
     
     # Apply the initial transformation (It seems -t0 didn't work in Elastix)
     ee.run_executable(type = "transformix", mov = "movp.txt", tp = "transpara2.txt")
     ee.writePointsetFileFromResult("Output/outputpoints.txt", "movp0.txt")
     
     tmp = moving_points_ori.copy()
     tmp[:, :3] *= moving_res
     ee.writePointsetFile(tmp, "mov.txt")
     ee.run_executable(type = "transformix", mov = "mov.txt", tp = "transpara2.txt") # Transform the moving segmentation result using initial transformation
     ee.writePointsetFileFromResult("Output/outputpoints.txt", "mov0.txt")
     
     ee.changeOutputBSplineOrder("transpara.txt", 3)
     ee.run_executable(type = "transformix", mov = "mov.mhd", tp = "transpara.txt", outDir = "")
     ee.renameImage("result", "mov0")
     ee.changeOutputBSplineOrder("transpara.txt", 0)
     ee.run_executable(type = "transformix", mov = "movmm.mhd", tp = "transparassd.txt", outDir = "")
     ee.renameImage("result", "movmm0")
     ee.run_executable(type = "transformix", mov = "movm.mhd", tp = "transparassd.txt", outDir = "")
     ee.renameImage("result", "movm0")
     ee.run_executable(type = "transformix", mov = "movmmm.mhd", tp = "transparassd.txt", outDir = "")
     ee.renameImage("result", "movmmm0")
     
     sa = SurfaceErrorAnalysis(None)
     
     # Start registration of different parameters
     cnt = len(regPara)
     result = npy.zeros([cnt, 3], dtype = npy.float32)
     fix_img_mask = ee.readImageFile("fixmmm.mhd")
     time2 = time.time()
     init_time = time2 - time1
     for i in range(0, cnt):
         if regPara[i][2] == "MI" and regPara[i][1] > 0:
             ww = regPara[i][1] / 1000
         else:
             ww = regPara[i][1]
         
         isRigid = regPara[i][0] < 0
         # Save Elastix registration configuration
         ee.writeParameterFile("para_rigid.txt", "rigid", regPara[i][2], regPara[i][0], ww, w2)
         if not isRigid:
             ee.writeParameterFile("para_spline.txt", "bspline", regPara[i][2], regPara[i][0], ww, w2)
         
         # Use Elastix for hybrid registration
         if isRigid:
             para_elastix = ["para_rigid.txt"]
         else:
             para_elastix = ["para_rigid.txt", "para_spline.txt"]
         
         if regPara[i][2] == "SSD":
             mov_name = "movmm0.mhd"
             fix_name = "fixmm.mhd"
         else:
             mov_name = "mov0.mhd"
             fix_name = "fix.mhd"
         time1 = time.time()
         code = ee.run_executable(type = "elastix", para = para_elastix, 
             fix = fix_name, mov = mov_name, movm = "movm0.mhd", movp = "movp0.txt", mask = (regPara[i][2] != "SSD"))
         time2 = time.time()
         if code != 0:
             print "Elastix error!"
             continue
         
         # Read the output files into self data formats
         ee.changeOutputBSplineOrder("Output/TransformParameters.0.txt", 0)
         if not isRigid:
             ee.changeOutputBSplineOrder("Output/TransformParameters.1.txt", 0)
             ee.run_executable(type = "transformix", mov = "movmmm0.mhd", tp = "Output/TransformParameters.1.txt") # Non-rigid transformation
             ee.changeOutputInitTransform("Output/TransformParameters.1.txt")
         else:
             ee.run_executable(type = "transformix", mov = "movmmm0.mhd", tp = "Output/TransformParameters.0.txt")
             ee.changeOutputBSplineOrder("Output/TransformParameters.0.txt", 0)
             
         result_img_mask = ee.readImageFile("Output/result.mhd")
         if regPara[i][2] == "SSD":
             # Transform the segmentation result for evaluation
             '''
             if isRigid:
                 result_img_mask = ee.readImageFile("Output/result.0.mhd")
             else:
                 result_img_mask = ee.readImageFile("Output/result.1.mhd")
             '''
             if cnt == 1:
             #if True:
                 ee.changeOutputBSplineOrder("Output/TransformParameters.0.txt", 3)
                 if not isRigid:
                     ee.changeOutputBSplineOrder("Output/TransformParameters.1.txt", 3)
                     ee.run_executable(type = "transformix", mov = "mov0.mhd", tp = "Output/TransformParameters.1.txt") # Non-rigid transformation
                     ee.changeOutputInitTransform("Output/TransformParameters.1.txt")
                 else:
                     ee.run_executable(type = "transformix", mov = "mov0.mhd", tp = "Output/TransformParameters.0.txt")
                 
                 result_img = ee.readImageFile("Output/result.mhd")
                 print i, 'SSD'
             
         else:
             if cnt == 1:
             #if True:
                 if isRigid:
                     result_img = ee.readImageFile("Output/result.0.mhd")
                     print i, 'Other'
                 else:
                     result_img = ee.readImageFile("Output/result.1.mhd")
             
             
             
         ee.generateInverseTransformFile("Output/TransformParameters.0.txt", "fix.mhd")
         
         # Delete the mask slice from the moving points
         tmp = true_moving_points.copy()
         for point in movingData.getPointSet('Mask'):
             tmp = npy.delete(tmp, npy.where((npy.abs(tmp[:, 2] - point[2]) < 0.0001) & (npy.round(tmp[:, -1]) == point[3])), axis = 0)
         tmp[:, :3] *= moving_res
         ee.writePointsetFile(tmp, "movm.txt")
         ee.run_executable(type = "transformix", mov = "movm.txt", tp = "transpara2.txt") # Transform the moving segmentation result using initial transformation
         ee.writePointsetFileFromResult("Output/outputpoints.txt", "mov0m.txt")
         ee.run_executable(type = "transformix", mov = "mov0m.txt", tp = "TransformParameters.0.txt") # Transform the moving segmentation result using rigid transformation
         if not isRigid:
             ee.generateInverseTransformFile("Output/TransformParameters.1.txt", "fix.mhd")
             ee.writePointsetFile(ee.readPointsetFile("Output/outputpoints.txt"), "Output/outputpoints2.txt")
             ee.run_executable(type = "transformix", mov = "Output/outputpoints2.txt", tp = "TransformParameters.0.txt") # Non-rigid transformation
         
         result_con = tmp.copy()
         result_con[:, :3] = ee.readPointsetFile("Output/outputpoints.txt")
         result_con[:, :3] /= fixed_res
         
         result_pointset = {'Contour': result_con}
         
         if cnt > 1:
         #if False:
             dataset = db.BasicData(npy.array([[[0]]]), fixedData.getInfo(), result_pointset)
             mean_dis, mean_whole, max_dis, max_whole = sa.analysis(dataset, point_data_fix = true_fixed_points, useResult = True)
             del dataset
             
             dice_index = eutil.calDiceIndexFromMask(fix_img_mask, result_img_mask)
             del result_img_mask
             
             del result_pointset
             del result_con
                 
             result[i, :] = [mean_whole, dice_index, time2 - time1]# + init_time]
             print "Result of spacing %fmm, weight %f and metric %s: %fmm, %f. " % (regPara[i][0], ww, regPara[i][2], mean_whole, dice_index)
         
         '''
         # Save the result
         resultData = db.ResultData(result_img, db.ImageInfo(fixedData.info.data), result_pointset)
         resultData.info.addData('fix', 1)
         resultData.info.addData('move', 2)
         resultData.info.addData('transform', [0, 0, 0])
         db.saveMatData('D:/Python src/MIRVAP/Result/Result' + str(i) + '_37L.mat', [resultData, fixedData, movingData], 0)
         del resultData
         '''
     
     del fix_img_mask
     if cnt > 1:
         result_img = None
         result_pointset = None
     else:
         result = [0, 0, 0]
     return result_img, result_pointset, result