def ac( NAME, priorSeg, followUpScan, followUpSegName, alpha=1e5, sigma=3, smoothing=3, threshold=0.01, balloon=1.0, iters=45, ): "Perform active contour on initial warped follow-up segmentation (to finalize segmentation)." print "Performing active contour finalization of follow-up segmentation..." input_fixed = followUpScan gray = nib.load(input_fixed) graydata = gray.get_data() # do 99% norm to 1000 origDATA = np.array(graydata, dtype=float) origDATA = origDATA * 1000 / np.percentile(origDATA, 99) input_seg = NAME + "/" + os.path.basename(priorSeg[:-7]) + "0to1.nii.gz" seg = nib.load(input_seg) segdata = seg.get_data() affine = seg.get_affine() new_image_preAC = nib.Nifti1Image(segdata, affine) nib.save(new_image_preAC, followUpSegName[:-7] + "_preAC.nii.gz") img = segdata > 0.2 [L, M, N] = np.shape(img) # Active Contour 2D finalseg2 = img.copy() * 0 for n in range(0, N): mgac = [] img2 = origDATA[:, :, n] gI = msnake.gborders(img2, alpha, sigma) # Morphological GAC. Initialization of the level-set. mgac = msnake.MorphGAC(gI, smoothing, threshold, balloon) mgac.levelset = img[:, :, n] > 0.2 for ijk123 in xrange(iters): # num iterations mgac.step() finalseg2[:, :, n] = mgac.levelset # Light filtering finalSeg = (gaussian_filter(finalseg2.copy() * 255, sigma=[3, 3, 1])) > 100 im_data = origDATA.copy() # Add now narrow band sobel/watershed technique. for i in xrange(0, N): img = im_data[:, :, i] segslice = finalSeg[:, :, i] if np.max(finalSeg[:, :, i] > 0): erodeimg = erosion(segslice.copy(), iterations=1) dilateimg = dilation(segslice.copy(), iterations=1) seeds = img * 0 seeds[:] = 1 seeds[dilateimg > 0] = 0 seeds[erodeimg > 0] = 2 sobelFilt = sobel(np.array(img.copy(), dtype="int16")) mgac = watershed(sobelFilt, seeds) > 1 finalSeg[:, :, i] = mgac > 0 # Write the final output affine = seg.get_affine() image1 = np.uint8(finalSeg) new_image = nib.Nifti1Image(image1, affine) nib.save(new_image, followUpSegName)
def MICOS(fileNAME): tic = time.clock() selfz =0 selfz1 = 0 selfz2 = 0 selfrotD = -90 imgObj2= nib.load(str(fileNAME)) imgObj1 = imgObj2 im = imgObj2 selfaffine2 = imgObj2.get_affine() selfheaderdtype = imgObj2.get_data_dtype() selfPSx = imgObj1.get_header()['pixdim'][1] selfPSy = imgObj1.get_header()['pixdim'][2] selfPSz = imgObj1.get_header()['pixdim'][3] (x,y,z) = orx.aff2axcodes(selfaffine2) selfOrx = x selfOry = y selfOrz = z ornt = orx.axcodes2ornt((x,y,z)) refOrnt = orx.axcodes2ornt(('R','S','A')) #was 'R', 'A', 'S' newOrnt = orx.ornt_transform(ornt,refOrnt) selfornt = ornt selfrefOrnt = refOrnt selfimg_data2 = imgObj2.get_data() selfimg_data2 = orx.apply_orientation(selfimg_data2,newOrnt) selfimg_data2 = np.fliplr(np.rot90(selfimg_data2,1)) im_data = selfimg_data2 [x_si,y_si,z_si] = np.shape(im_data) #do 99% norm to 1000 im_data = np.array(im_data,dtype='float') im_data = im_data * 1000/np.percentile(im_data,99) #print np.shape(im_data) initialSeg = im_data.copy() * 0 #begin user roi drawing... #go from middle up... for i in xrange(np.round(z_si/2),z_si,3): img = (im_data[:,:,i]) # show the image if i > np.round(z_si/2): plt.figure(figsize=(ROI1.figwidth,ROI1.figheight)) plt.imshow(img,cmap='gray') plt.colorbar() plt.title("outline one kidney, slice = " + str(i)) # let user draw first ROI ROI1 = polydraw(roicolor='r') #let user draw first ROI # show the image with the first ROI plt.figure(figsize=(ROI1.figwidth,ROI1.figheight)) plt.imshow(img,cmap='gray') plt.colorbar() ROI1.displayROI() plt.title("outline other kidney, slice = " + str(i)) # let user draw second ROI ROI2 = polydraw(roicolor='b') #let user draw ROI initialSeg[:,:,i] = ROI1.getMask(img) + ROI2.getMask(img) #go from middle up... for i in xrange(np.round(z_si/2)-1,0,-3): img = (im_data[:,:,i]) # show the image plt.figure(figsize=(ROI1.figwidth,ROI1.figheight)) plt.imshow(img,cmap='gray') plt.colorbar() plt.title("outline one kidney, slice = " + str(i)) # let user draw first ROI ROI1 = polydraw(roicolor='r') #let user draw first ROI # show the image with the first ROI plt.figure(figsize=(ROI1.figwidth,ROI1.figheight)) plt.imshow(img,cmap='gray') plt.colorbar() ROI1.displayROI() plt.title("outline other kidney, slice = " + str(i)) # let user draw second ROI ROI2 = polydraw(roicolor='b') #let user draw ROI initialSeg[:,:,i] = ROI1.getMask(img) + ROI2.getMask(img) toc = time.clock() #save out drawn polygon aff = selfaffine2 outImage = deepcopy(initialSeg)#np.rot90(np.fliplr(self.segImg),-1) [x_si,y_si,z_si] = np.shape(outImage) #print np.shape(outImage) #This method works (for fastsegs)... but need more robust #for i in range(0,z_si): # outImage[:,:,i] = np.rot90(self.segImg[:,:,z_si-1-i],-1) #try new method (more robust to header and affine mix-ups) ornt = orx.axcodes2ornt((selfOrx,selfOry,selfOrz)) refOrnt = orx.axcodes2ornt(('R','S','A')) newOrnt = orx.ornt_transform(refOrnt,ornt) #reversed these outImage= orx.apply_orientation(np.rot90(np.fliplr(outImage),-1),newOrnt) #outImage = orx.apply_orientation(outImage,newOrnt) #outImage = np.rot90(np.fliplr(outImage),-1) #print np.shape(outImage) #outImage = np.array(outImage,dtype=selfheaderdtype) new_image = nib.Nifti1Image(outImage,aff) nib.save(new_image,fileNAME[:-7]+'_polygon_MICOS.nii.gz') # Dilate and fill in missing slices initialSeg = dilation(initialSeg,iterations = 1) finalSeg = initialSeg.copy() * 0 # now try convex hull method instead to better approximate missing slices (previous method is above) # This works but way too long. Also, would likely need to do object finding first, so compute # Convex hull for each kidney separately. while 0: xlist,ylist,zlist = find_3D_object_voxel_list(initialSeg) voxlist = np.zeros(shape=(np.shape(xlist)[0],3),dtype='int16') voxlist[:,0] = xlist voxlist[:,1] = ylist voxlist[:,2] = zlist tri = dtri(voxlist) # construct full voxel list xxlist,yylist,zzlist = find_3D_object_voxel_list((initialSeg+1)>0) fullvoxlist = np.zeros(shape=(np.shape(xxlist)[0],3),dtype='int16') fullvoxlist[:,0] = xxlist fullvoxlist[:,1] = yylist fullvoxlist[:,2] = zzlist finalSeg = np.array(in_hull(fullvoxlist,tri),dtype=float) finalSeg = np.reshape(finalSeg,(x_si,y_si,z_si)) # Now do gaussian blur of polygon to smooth initialSeg = (filt.gaussian_filter(initialSeg.copy()*255,sigma=[3,3,1])) > 100 #Begin optimized method... for i in xrange(0,z_si): img = (im_data[:,:,i]) if np.max(initialSeg[:,:,i]>0): mgac = [] gI = msnake.gborders(img,alpha=1E5,sigma=3.0) # increasing sigma allows more changes in contour mgac = msnake.MorphGAC(gI,smoothing=3,threshold=0.01,balloon=0.0) #was 2.5 mgac.levelset = initialSeg[:,:,i]>0.5 for ijk123 in xrange(100): mgac.step() finalSeg[:,:,i] = mgac.levelset #print i # Now do gaussian blur and threshold to finalize segmentation... finalSeg = (filt.gaussian_filter(finalSeg.copy()*255,sigma=[3,3,1])) > 100 #using this helps with single slice errors of the active contour # Try adding now narrow band sobel/watershed technique. for i in xrange(0,z_si): img = (im_data[:,:,i]) segslice = finalSeg[:,:,i] if np.max(finalSeg[:,:,i]>0): erodeimg = erosion(segslice.copy(),iterations=1) dilateimg = dilation(segslice.copy(),iterations=1) seeds = img * 0 seeds[:] = 1 seeds[dilateimg>0] = 0 seeds[erodeimg>0] = 2 sobelFilt = sobel(np.array(img.copy(),dtype='int16')) mgac = watershed(sobelFilt,seeds)>1 finalSeg[:,:,i] = mgac>0 #save out segmentation aff = selfaffine2 outImage = deepcopy(finalSeg)#np.rot90(np.fliplr(self.segImg),-1) outImage = np.array(outImage,dtype='float') [x_si,y_si,z_si] = np.shape(outImage) #This method works (for fastsegs)... but need more robust #for i in range(0,z_si): # outImage[:,:,i] = np.rot90(self.segImg[:,:,z_si-1-i],-1) #try new method (more robust to header and affine mix-ups) ornt = orx.axcodes2ornt((selfOrx,selfOry,selfOrz)) refOrnt = orx.axcodes2ornt(('R','S','A')) newOrnt = orx.ornt_transform(refOrnt,ornt) #reversed these outImage= orx.apply_orientation(np.rot90(np.fliplr(outImage),-1),newOrnt) #outImage = orx.apply_orientation(outImage,newOrnt) #outImage = np.rot90(np.fliplr(outImage),-1) new_image = nib.Nifti1Image(outImage,aff) nib.save(new_image,fileNAME[:-7]+'_FASTseg_MICOS.nii.gz') print 'time = ' print toc - tic return (fileNAME[:-7]+'_FASTseg_MICOS.nii.gz')