The following python script implements three ways to segment metaphasic chromosomes through functions relying on scipy.ndimage and pymorph/mahotas. Starting from initial image:
| | |
Human DAPI stained metaphasic chromosomes recorded with KAF1600 Peltier cooled CCD camera. |
- The first idea consists in performing a hipass filtering followed by a simple thresholding step and finally cleaning the binary image with a morphological opening. This is achieved with the function def HighPassBinary(image):
|
Labelled image displayed with pylab. Hipass filtering results in fragmented nuclei |
- The second idea, implemented in def metaphaseSeg(image):, tries to preserve both nuclei and chromosomes shape using a region growing algorithm (watershed + markers). The markers are obtained from a regional maxima on a blured DAPI image. However, according to the size of the gaussian kernel the segmented image can be over or under segmented with undetected chromosomes as shown in the following animation:
|
gif animation of a region based segmentation with increasing gaussian kernel size (3, 5, 7, 9,11, 13, 19). A small kernel (3) yields an oversegmented image. |
- A third idea tries to combine both methods using the result of the first method as markers to initiate a region growing, implemented in def HighPassMetaphaseSeg(image):
|
Artifacts close to the nuclei yield background artifacts near the nuclei. |
The result of this third method wouldn't be too bad if additionnal image cleaning was performed on the first image.
The python script runs under ubuntu linux , I didn't take care of path to access to the image file to make it portable for windows or MacOS. To use one of the function comment/uncomment the code.
from scipy import ndimage as ND
import readmagick
import mahotas
import pymorph
import pylab
def HighPassBinary(image):
'''depuis une image DAPI, genere une image passe haut avec fond a zero'''
'''necessite scipy.ndimage'''
blur=ND.filters.gaussian_filter(image, 9)
sharp=image-1.0*blur
'''float 64bits'''
print sharp.dtype, sharp.shape
smax=sharp.max()
'''threshold above negative values'''
imBin=(sharp>0)
imBin2=ND.binary_fill_holes(imBin)
imBin3=ND.binary_opening(imBin2, iterations=4)
labeled,nr_obj=ND.label(imBin3)
print nr_obj
return labeled
def metaphaseSeg(image):
blur=ND.filters.gaussian_filter(image, 15)
remax=pymorph.regmax(blur)
binRemax=(remax>0)
seeds,nr_obj=ND.label(binRemax)
print nr_obj
grad=pymorph.gradm(image)
label=mahotas.cwatershed(grad, seeds, Bc=None, return_lines=False)
return label
def HighPassMetaphaseSeg(image):
'''depuis une image DAPI, genere une image passe haut avec fond a zero'''
'''necessite scipy.ndimage'''
blur=ND.filters.gaussian_filter(image, 9)
sharp=image-1.0*blur
'''float 64bits'''
print sharp.dtype, sharp.shape
smax=sharp.max()
'''threshold negative values'''
imBin=(sharp>0)
imBin2=ND.binary_fill_holes(imBin)
imBin3=ND.binary_opening(imBin2, iterations=4)
seeds,nr_obj=ND.label(imBin3)
print nr_obj
grad=pymorph.gradm(ND.filters.gaussian_filter(image, 1))
labeled=mahotas.cwatershed(grad, seeds, Bc=None, return_lines=False)
return labeled
if __name__ == "__main__":
dapi=readmagick.readimg("/home/jeanpat/Applications/Images_test/png/essai09/humain.png")
'''dapiLabeled=metaphaseSeg(dapi)'''
dapiLabeled1=HighPassBinary(dapi)
'''dapiLabeled2=HighPassMetaphaseSeg(dapi)'''
pylab.imshow(dapiLabeled1)
pylab.show()
'''pylab.imshow(dapiLabeled1)
pylab.show()
pylab.imshow(dapiLabeled2)
pylab.show()'''
'''readmagick.writeimg(dapiBin,"/home/jeanpat/Applications/Images_test/png/essai09/humainBin.png")'''
No comments:
Post a Comment