Showing posts with label ASI. Show all posts
Showing posts with label ASI. Show all posts

Wednesday, February 5, 2014

Making image processing on SageMathCloud. Extraction of chromosomes from multispectral images.

SageMathCloud is a plateform to do mathematics, it also offers the possibility to use a ipython notebook online. Several python libraries are available: numpy, scipy, scikit-image (0.7, 0.93), mahotas 1.1, pandas ...
Once an account is opened (it's free), a project created, some multispectral images were uploaded in a directory of the project. In that project, an ipython notebook was created, this notebook can be run in a project directly in SageMathCloud.

Removing spurious pixels brought by ndimage.find_objects():

The following model image  is a grey scaled image:


Grey image with a pseudo color map

find_objects() succeeds in extracting the letters:

Extracted particles are not convex, their bounding box can contains pixels from other particles in their neighborhood.
For example the letter A, contain pixels belonging to other segmented (labelled) letters. The image of A contains pixels belonging to the letter r and to the letter B. Those spurious pixels have to be eliminated. find_object() provides the bounding box of the segmented particles in a list. The bouding box index seems to correspond to the particle label, this could be used to erase the spurious pixels:

A python function can be written:


It takes two images as arguments: a grey level  image (or stacked images) and a label image and returns a list of images containing the extracted particles from the grey level image. This implementation is much simpler and faster than a previous one .

 

Chromosomes extraction from a MFISH image:

After having uploaded images on cloud.sagemath, for example:

The five components (DAPI excepted) spectral images can be combined in one color image. There is an additional kar image resulting of the segmentation of the MFISH images :
5 spectral images combined into 3 to make a color (rgb) image (left). kar image (right)

Let's use the kar image to produce a label image so that each chromosome is defined by a single label (or grey level):
label image (right)

Now the extraction of individual chromosomes can be done, from the DAPI image:

or from stacked images:

The kar image identifies the chromosomes:

Let's make galleries of chromosomes

The extracted chromosome images have different size. Let's add borders to the images so that the images have all the same size :



Then let's build two galleries, one with MFISH images and one with inverse DAPI chromosomes, the code is visible in the notebook; it yields:
Left: MFISH chromosomes, Right:inverse DAPI

It remains to auto rotate the chromosome. A draft code, at the end of the ipython notebook  in the SageMathCloud project, tries to explore another method than the previously proposed. It remains also to arrange the chromosome according to their classification.

Download the ipython notebook

Go to the notebook on sagemathcloud




Sunday, May 20, 2012

FlyFISH:navigation in the ADIR MFISH images database

FlyFISH allows to visualize images of the ADIR MFISH database. FlyFISH is written in python, the GUI is based on pyQt4, images are loaded and displayed with imread, qimage2ndarray. To work properly, FlyFISH requires:
The path to the DatabaseMFISH.xml file must be modified in the script:
root=et.parse('/home/simon/DatabaseMFISH.xml').getroot() 
and the path to database top directory:
workdir="/home/simon/MFISH/"

The script was tested on ubuntu 12.04, to run faster, the image size was reduced on display:

Thanks to ashren.

Tuesday, May 8, 2012

One shot scripts to reorder images in the ASI/PSI/Vysis-MFISH dataset

The images belonging to the MFISH dataset are not ordered in a hierachy of directories defined as project/slides/field_xy/fluorochromes/image.
To navigate through that images database as in the previous post, the images need to be reordered.
The central part of the following image displays the original images arrangement, the right side shows the images after reordering. We have for example a slide called A01 belonging to the ASI MFISH dataset . For this slide, five xy fields were taken (from 01 to 05) . The folder called Kar, contains the segmented image (the chromosome 1 is set to grey level  and so on).


Three dirty python scripts (pylint 1.76/10 !) reorder the MFISH dataset. One for each images subset (ASI, PSI or Vysis). Prior running the scripts:
  • make three folders (ASI, PSI, Vysis) in the top directory (MFISH)
  • select all the slides whose name start by 'A', cut and copy them in the ASI folder and so on the the PSI slides (starting by a 'P') and the Vysis slides (starting by a 'V').
  • modify the path to the top directory inside the script and run the ASI script to reorder the images from ASI images subset.
  • run the PSI script ...
  • run the Vysis script.
To modify the path find the line:

path='/home/simon/MFISH/'+'ASI'
Modify it as:
 
path='/fit/to/your/path/MFISH/'+'ASI'
 
The pygmentized ASI script is shown:

# -*- coding: utf-8 -*-
"""
Created on Thu Apr  5 14:43:39 2012

@author: jean-pat

3   532
5   Cy 5.5
6   568
A   S. Aqua
C   Cy 5
D   DAPI
E   DEAC
F   Far Red
G   S. Green
I   FITC
O   S. Orange
R   S. Red
T   Texas Red
Y   S. Gold

"""

import sys,os
from shutil import move,rmtree
import re

#Choix répertoire ex Vysis ou ASI ou PSI/Cytocell
path='/home/simon/MFISH/'+'ASI'
slidelist=os.listdir(path)

fluoASI={'5':'Cy5-5','C':'Cy5','D':'DAPI','G':'SpGreen','O':'SpOrange','T':'TexasRed','K':'Kar'}
fluoPSI={'C':'Cy5','D':'DAPI','E':'DEAC','I':'FITC','3':'532','6':'568','K':'Kar'}
fluoVysis={'A':'SpAqua','D':'DAPI','F':'FarRed','G':'SpGreen','R':'SpRed','Y':'SpGold','K':'Kar'}
print "slidelist[0]",slidelist[0]
for apv_slide in slidelist:
    #listfield=os.listdir(os.path.join(path,slidelist[0]))
    listfield=os.listdir(os.path.join(path,apv_slide))
    print listfield
    #cherchons le numero des images dans le nom des fichiers
    #contient V au début et .tif à la fin
    slidecode=apv_slide[0:1]#V for vysis, A for ASI, P for PSI
    motif=re.compile('.tif$')
    imagelist=[]
    for image in listfield:
        if not(motif.search(image)==None):
            imagelist.append(image)
    #print imagelist
    #obtenir le numero des images
    imagenumberlist=[]
    for image in imagelist:
        number=image[3:5]
        if number not in imagenumberlist:
            imagenumberlist.append(number)
    #print imagenumberlist
    #créer un répertoire correspondant au numéro de l'image(métaphase)
    for imNb in imagenumberlist:
        metaphasepath=os.path.join(path,apv_slide,imNb)
        os.makedirs(metaphasepath)
        #puis déplacer les images imNb dedans
        imagesToMove=[item for item in imagelist if item[3:5]==imNb]
        #print imagesToMove
        #print 'MOVING ',imNb, '************'
        for fluo in imagesToMove:
            sourceimage=os.path.join(path,apv_slide,fluo)
            destimage=os.path.join(path,apv_slide,imNb,fluo)
            #os.renames(sourceimage,destimage)
            #print fluo
            #print fluo[7:8],'component:',fluoVysis[fluo[7:8]]
            #make fluorochrome directories
            os.makedirs(os.path.join(path,apv_slide,fluoASI[fluo[7:8]]))
            #print 'Source',sourceimage,os.path.exists(sourceimage)
            #print 'Dest',destimage,os.path.exists(destimage)
            #move component image into component directory
            destComponentImage=os.path.join(path,apv_slide,fluoASI[fluo[7:8]],fluo)
            #print ' **** move compenent images into comp dirs'
            move(sourceimage,destComponentImage)
            #print ' **** ----move compenent dir into metaphase dirs'
            sourceCompDir=os.path.join(path,apv_slide,fluoASI[fluo[7:8]])
            destMetaphaseDir=metaphasepath
            move(sourceCompDir,destMetaphaseDir)
    #fusionner les dossiers correspondant à une même lame
    ## ex V29_62 et V29_63 dans V29

mfishSlidesList=os.listdir(path)
print mfishSlidesList
slidecode='A'#apv_slide[0:1]#V for vysis, A for ASI, P for PSI
    #store the number of each slide V29_62 et V29_63 -> 29
#==============================================================================
#     #For a given slide ex V29_62
#==============================================================================
dirtomake=[]
for slide in mfishSlidesList:
    slidenumber=slide[1:3]# ex 13, 14...29 for vysis
    #print slidenumber
    if slidenumber not in dirtomake:
        dirtomake.append(slidenumber)
        
for d in dirtomake:
    slidename=slidecode+d
    print "makedir " , os.path.join(path,slidename)
    os.makedirs(os.path.join(path,slidename))
    
for newdir in dirtomake:
    slidename=slidecode+newdir
    #find all slides starting by slidename
    slides_content_to_move=[] #ex all V29_xx
    #print "moving slides starting by " , slidename
    for movingslide in mfishSlidesList:        
        
        if movingslide[0:3]==slidename:
            slides_content_to_move.append(movingslide)
        
        for moving in slides_content_to_move:
            current_content=os.listdir(os.path.join(path,moving))
            #print "current content of" , movingslide , "is =" , current_content
            
            for cc in current_content:
                source=os.path.join(path , movingslide , cc)
                dest=os.path.join(path , slidename , cc)
                print "move ", source, "-> dest" , dest
                move(source,dest)
    #print "end",mfishSlidesList
    
#supprimer les lames vides
for empty_slide in mfishSlidesList:
    curpath=os.path.join(path,empty_slide)
    print empty_slide
    print "remove(",os.path.join(path,empty_slide),")"
    print 'dir?',os.path.isdir(curpath),'vide?',os.listdir(curpath)
    os.removedirs(curpath)