Beispiel #1
0
def segmentLesions3Dv2(pathInpNii,
                       dirWithModel,
                       pathOutNii=None,
                       outSize=None,
                       isDebug=False,
                       threshold=None,
                       path_lungs=None):
    if isinstance(pathInpNii, str):  # or isinstance(pathInpNii, unicode):
        isInpFromFile = True
        if not os.path.isfile(pathInpNii):
            raise Exception('Cant find input file [%s]' % pathInpNii)
    else:
        isInpFromFile = False
    if not os.path.isdir(dirWithModel):
        raise Exception('Cant find directory with model [%s]' % dirWithModel)
    if pathOutNii is not None:
        outDir = os.path.dirname(os.path.abspath(pathOutNii))
        if not os.path.isdir(outDir):
            raise Exception(
                'Cant find output directory [%s], create directory for output file before this call'
                % outDir)
    batcherInfer = InferencerLesion3Dv2()
    batcherInfer.load_model(path_model=dirWithModel)
    if isDebug:
        batcherInfer.model.summary()
    ret = batcherInfer.inference([pathInpNii], batchSize=1)
    outMsk = ret[0]
    if isInpFromFile:
        tmpNii = nib.load(pathInpNii)
    else:
        tmpNii = pathInpNii
    #
    outMskNii = nib.Nifti1Image(outMsk.copy().astype(np.uint8),
                                tmpNii.affine,
                                header=tmpNii.header)
    if outSize is not None:
        outMskNii = resizeNii(outMskNii, newSize=outSize, parOrder=0)
    if path_lungs is not None:
        tmp_affine = outMskNii.affine
        tmp_header = outMskNii.header
        msk_lungs = resizeNii(path_lungs, newSize=outSize,
                              parOrder=0).get_data()
        outMsk = outMskNii.get_data().astype(np.uint8)
        outMsk[msk_lungs < 0.5] = 0
        outMskNii = nib.Nifti1Image(outMsk.copy().astype(np.uint8),
                                    tmp_affine,
                                    header=tmp_header)
    # if threshold is not None:
    #     outMskNii = nib.Nifti1Image((outMskNii.get_data() > threshold).astype(np.float16),
    #                                 outMskNii.affine,
    #                                 header=outMskNii.header)
    if pathOutNii is not None:
        nib.save(outMskNii, pathOutNii)
        # pathOutNii = '%s-segm.nii.gz' % pathInpNii
    else:
        return outMskNii
 def test_resize_nii(self):
     self.assertTrue(os.path.isdir(self.wdir))
     lstPathNii = sorted(glob.glob('%s/*.nii.gz' % self.wdir))
     numNii = len(lstPathNii)
     self.assertTrue((numNii > 0))
     pathNii = lstPathNii[0]
     newSize = (128, 128, 128)
     niiResiz = preproc.resizeNii(pathNii, newSize=newSize)
     self.assertTrue(niiResiz.shape == newSize)
Beispiel #3
0
def segmentLungs25D(pathInpNii,
                    dirWithModel,
                    pathOutNii=None,
                    outSize=None,
                    batchSize=8,
                    isDebug=False,
                    threshold=None):
    if isinstance(pathInpNii, str):  # or isinstance(pathInpNii,unicode):
        isInpFromFile = True
        if not os.path.isfile(pathInpNii):
            raise Exception('Cant find input file [%s]' % pathInpNii)
    else:
        isInpFromFile = False
    if not os.path.isdir(dirWithModel):
        raise Exception('Cant find directory with model [%s]' % dirWithModel)
    if pathOutNii is not None:
        outDir = os.path.dirname(os.path.abspath(pathOutNii))
        if not os.path.isdir(outDir):
            raise Exception(
                'Cant find output directory [%s], create directory for output file before this call'
                % outDir)
    batcherInfer = BatcherCTLung2D()
    batcherInfer.loadModelForInference(pathModelJson=dirWithModel,
                                       pathMeanData=dirWithModel)
    if isDebug:
        batcherInfer.model.summary()
    lstPathNifti = [pathInpNii]
    ret = batcherInfer.inference(lstPathNifti,
                                 batchSize=batchSize,
                                 isDebug=isDebug)
    outMsk = ret[0]
    if isInpFromFile:
        tmpNii = nib.load(pathInpNii)
    else:
        tmpNii = pathInpNii
    #
    outMskNii = nib.Nifti1Image(outMsk.copy().astype(np.float16),
                                tmpNii.affine,
                                header=tmpNii.header)
    # resize if need:
    if outSize is not None:
        outMskNii = resizeNii(outMskNii, newSize=outSize)
    # threshold if need:
    if threshold is not None:
        outMskNii = nib.Nifti1Image(
            (outMskNii.get_data() > threshold).astype(np.float16),
            outMskNii.affine,
            header=outMskNii.header)
    # save if output path is present
    if pathOutNii is not None:
        nib.save(outMskNii, pathOutNii)
        # pathOutNii = '%s-segm.nii.gz' % pathInpNii
    else:
        return outMskNii
 def test_lesion_segmentation(self):
     niiOriginal = nib.load(self.pathInpNii)
     inpSize = niiOriginal.shape
     sizeProcessing = (128, 128, 64)
     niiResized = resizeNii(pathNii=niiOriginal, newSize=sizeProcessing)
     niiMask = segmentLesions3D(niiResized,
                                dirWithModel=self.pathModelLesion,
                                pathOutNii=None,
                                outSize=inpSize,
                                threshold=None)
     foutMskLesion = '%s-msk-lesion-test.nii.gz' % self.pathInpNii
     nib.save(niiMask, foutMskLesion)
     self.assertTrue(inpSize == niiMask.shape)
 def test_lung_segmentation(self):
     #
     niiOriginal = nib.load(self.pathInpNii)
     inpSize = niiOriginal.shape
     sizeProcessing = (256, 256, 64)
     niiResized = resizeNii(pathNii=niiOriginal, newSize=sizeProcessing)
     niiMask = segmentLungs25D(niiResized,
                               dirWithModel=self.pathModelLung,
                               pathOutNii=None,
                               outSize=inpSize,
                               threshold=0.5)
     foutMskLung = '%s-msk-lung-test.nii.gz' % self.pathInpNii
     nib.save(niiMask, foutMskLung)
     self.assertTrue(inpSize == niiMask.shape)
                        default=None,
                        required=True,
                        help='path to index with images')
    args = parser.parse_args()
    #
    path_idx = args.path_idx
    shape_4lung = (256, 256, 64)
    wdir = os.path.dirname(path_idx)
    data_csv = pd.read_csv(path_idx)
    paths_img = [os.path.join(wdir, xx) for xx in data_csv['path_img']]
    num_img = len(paths_img)
    #
    for ii, path_nii in enumerate(paths_img):
        print(' [{}/{}] * {}'.format(ii, num_img, paths_img))
        t1 = time.time()
        dataNii = nib.load(path_nii)
        shape_orig = dataNii.shape
        nii_resiz_4lung = resizeNii(dataNii, shape_4lung)
        lungMask = segmentLungs25D(
            nii_resiz_4lung,
            dirWithModel=path_model_lung,
            pathOutNii=None,
            outSize=shape_orig,
            # outSize=shape4Lung,
            threshold=0.5)
        dt = time.time() - t1
        path_out_lungs = '{}-lungs.nii.gz'.format(path_nii)
        print('\t\tdone, dt={:0.2f} (s), export result to [{}]'.format(
            dt, path_out_lungs))
        nib.save(lungMask, path_out_lungs)
Beispiel #7
0
def api_segmentLungAndLesion(dirModelLung,
                             dirModelLesion,
                             series,
                             ptrLogger=None,
                             shape4Lung=(256, 256, 64),
                             shape4Lesi=(512, 512, 256),
                             gpuMemUsage=0.4):
    # (1) msg-helpers
    def msgInfo(msg):
        if ptrLogger is not None:
            ptrLogger.info(msg)
        else:
            print(msg)

    def msgErr(msg):
        if ptrLogger is not None:
            ptrLogger.error(msg)
        else:
            print(msg)

    # (2.1) check data
    if not series.isInitialized():
        msgErr('Series is not initialized, skip .. [{0}]'.format(series))
        return False
    # if not series.isDownloaded():
    #     msgErr('Series data is not downloaded, skip .. [{0}]'.format(series))
    #     return False
    if not series.isConverted():
        msgErr(
            'Series DICOM data is not converted to Nifti format, skip .. [{0}]'
            .format(series))
        return False
    # (2.2) check existing files
    pathNii = series.pathConvertedNifti(isRelative=False)
    # pathSegmLungs = series.pathPostprocLungs(isRelative=False)
    pathSegmLungs = series.pathPostprocLungs(isRelative=False)
    pathSegmLesions = series.pathPostprocLesions2(isRelative=False)
    if os.path.isfile(pathSegmLungs) and os.path.isfile(pathSegmLesions):
        msgInfo('Series data is already segmented, skip task ... [{0}]'.format(
            series))
        return False
    else:
        # (2.3.0) TF GPU memory usage constraints
        # FIXME:temporary fix, in future: apped memory usage parameter in application config
        import tensorflow as tf
        import keras.backend as K
        from keras.backend.tensorflow_backend import set_session
        if K.image_dim_ordering() == 'tf':
            config = tf.ConfigProto()
            config.gpu_options.per_process_gpu_memory_fraction = gpuMemUsage
            set_session(tf.Session(config=config))

        # (2.3.1) load and resize
        try:
            dataNii = nib.load(pathNii)
            shapeOrig = dataNii.shape
            niiResiz4Lung = resizeNii(dataNii, shape4Lung)
        except Exception as err:
            msgErr(
                'Cant load and resize input nifti file [{0}] : {1}, for series [{2}]'
                .format(pathNii, err, series))
            return False
        # (2.3.2) segment lungs
        try:
            if not os.path.isfile(pathSegmLungs):
                K.clear_session()
                lungMask = segmentLungs25D(
                    niiResiz4Lung,
                    dirWithModel=dirModelLung,
                    pathOutNii=None,
                    outSize=shapeOrig,
                    # outSize=shape4Lung,
                    threshold=0.5)
                nib.save(lungMask, pathSegmLungs)
            else:
                pass
                # lungMask = nib.load(pathSegmLungs)
        except Exception as err:
            msgErr('Cant segment lungs for file [{0}] : {1}, for series [{2}]'.
                   format(pathNii, err, series))
            return False
        # (2.3.3) segment lesions
        try:
            if not os.path.isfile(pathSegmLesions):
                # lesionMask = segmentLesions3D(niiResiz4Lesi,
                #                               dirWithModel=dirModelLesion,
                #                               pathOutNii=None,
                #                               outSize=shapeOrig,
                #                               # outSize=shape4Lung,
                #                               threshold=None)
                K.clear_session()
                shape_lesions = [512, 512, 256]
                nii_lung_resiz4lesion = resizeNii(pathSegmLungs,
                                                  shape_lesions,
                                                  parOrder=0)
                nii_data_resiz4lesion = resizeNii(dataNii,
                                                  shape_lesions,
                                                  parOrder=1)
                lesionMask, lesionMaskVal = segmentLesions3Dv3(
                    nii_data_resiz4lesion,
                    dir_with_model=dirModelLesion,
                    nii_lings=nii_lung_resiz4lesion,
                    path_out_nii=None,
                    # outSize=shapeOrig,
                    # outSize=shape4Lung,
                    threshold=None)
                # lesionMask = segmentLesions3Dv2(niiResiz4Lesi,
                #                                 dirWithModel=dirModelLesion,
                #                                 pathOutNii=None,
                #                                 outSize=shapeOrig,
                #                                 # outSize=shape4Lung,
                #                                 threshold=None,
                #                                 path_lungs=pathSegmLungs)
                # (2.3.4) save results
                try:
                    lesionMask = resizeNii(lesionMask, shapeOrig, parOrder=0)
                    nib.save(lesionMask, pathSegmLesions)
                except Exception as err:
                    msgErr(
                        'Cant save segmentation results to file [{0}] : {1}, for series [{2}]'
                        .format(pathSegmLesions, err, series))
                    return False
        except Exception as err:
            msgErr(
                'Cant segment lesions for file [{0}] : {1}, for series [{2}]'.
                format(pathNii, err, series))
            return False
        return True