Contagem automática de células é uma ferramenta poderosa para biólogos entenderem como células se comportam em alguns cenários específicos. Contagem de células a partir de amostras de microcopia conforcal, por exemplo, pode mostrar o balanço entre divisão celular e morte de células. Esta informação é útil para estudar como células se comportam em diferentes cenários como em caso de doenças ou lesões.

O exemplo abaixo demonstra como usar processamento de imagens para contar o número de células de uma dada amostra. Basicamente, a abordagem utilizada funciona da seguinte forma:

    1. Carrega amostra contendo diversas células.
    2. Aumenta o contraste entre elementos foreground (células) e o fundo da imagem.
    3. Aplica limite de cor considerando a vizinhança para separar as céluas do fundo da imagem.
    4. Sapara células agrupadas utilizando operadores morfológicos. A imagem é convertida para formato binário antes deste processo.
    5. Segmenta cada célula utilizando abordagem flood fill. Para cada segmento, obtêm-se o blob, converte o mesmo para contorno para destacar cada célula.
    6. Salva imagem resultando.
    7. Imprime o número de células.


Input Image:



Result:



Console output:

total cells: 184

Source:
package countCells;

import static marvin.MarvinPluginCollection.*;
import marvin.color.MarvinColorModelConverter;
import marvin.image.MarvinBlob;
import marvin.image.MarvinBlobSegment;
import marvin.image.MarvinContour;
import marvin.image.MarvinImage;
import marvin.io.MarvinImageIO;
import marvin.math.MarvinMath;
import marvin.math.Point;

public class CountingCells {

	public CountingCells(){
		
		// 1. Load sample image
		MarvinImage originalImage = MarvinImageIO.loadImage("./res/cells.png");
		MarvinImage image = originalImage.clone();
		
		// 2. Increase contrast
		brightnessAndContrast(image, 0, 30);
		MarvinImage imageOut = image.clone();
		
		// 3. Thesholding
		thresholdingNeighborhood(image, imageOut, 1, 8, 1);
		
		// 4. Separate cells that are grouped
		invertColors(imageOut);
		MarvinImage bin = MarvinColorModelConverter.rgbToBinary(imageOut, 50);
		morphologicalErosion(bin.clone(), bin, MarvinMath.getTrueMatrix(3, 3));
		morphologicalDilation(bin.clone(), bin, MarvinMath.getTrueMatrix(3, 3));
		
		// 5. Segment each cell
		image = MarvinColorModelConverter.binaryToRgb(bin);
		image.setAlphaByColor(0, 0xFFFFFFFF);
		
		MarvinBlobSegment[] segments = floodfillSegmentationBlob(image);
		
		int totalCells=0;
		for(MarvinBlobSegment s:segments){
			MarvinBlob blob = s.getBlob();
			MarvinContour contour = blob.toContour();
			
			if(blob.getArea() > 50){
				totalCells++;
				for(Point p:contour.getPoints()){
					originalImage.setIntColor(s.getX()+p.x, s.getY()+p.y, 0xFF00FF00);
				}
			}
		}
		
		// 6. save output image
		MarvinImageIO.saveImage(originalImage, "./res/cells_output.png");
		
		//7. Print the number of cells
		System.out.println("total cells: "+totalCells);
	}
	
	public static void main(String[] args) {
		new CountingCells();
	}
}