Ajout de deux fonctions :
authorGreg Burri <greg.burri@gmail.com>
Fri, 22 May 2015 10:28:33 +0000 (12:28 +0200)
committerGreg Burri <greg.burri@gmail.com>
Fri, 22 May 2015 10:28:33 +0000 (12:28 +0200)
* L'algorithme wathershed à partir d'une transformé de distance.
* Une fonction permettant l'écriture du gradient d'une image logique.

current.psd
rapport/main.tex
src/DetectionOfParasites.m
src/Main.m
src/SegmentationOfRedCells.m
src/WatershedsByDistanceTransform.m [new file with mode: 0644]
src/WriteImageGradient.m [new file with mode: 0644]

index e18a1b5..9eca60a 100644 (file)
Binary files a/current.psd and b/current.psd differ
index b408146..ec26011 100644 (file)
@@ -102,8 +102,9 @@ Un filtre médian 5 x 5 suivi d'une fermeture par aire de 1000 sont appliqués 
 
 \subsubsection{Granulometrie}
 
-L'objectif ici est de déterminé la taille moyenne des 
+L'objectif ici est de déterminer le rayon moyenne des globules rouges (souvent abrégé \emph{RBC} pour \emph{red blood cell}). Pour ce faire nous allons réaliser une succession de fermetures à l'aide d'un élément structurant de forme octogonale dont le rayon va être augmenté à chaque itération sur la composante \emph{saturation} ($imgFiltered\{2\}$). Nous évitons ici un élément structurant ayant la forme d'un disque pour des raisons de performance, une fermeture avec ce dernier demandant beaucoup plus de calculs à effectuer.
 
+Nous partons d'un rayon initial de 1 pour arriver à un rayon maximal de $largeur(imgRGB) / 35$. À chaque itération une fermeture est effectuée suivi du calcul du volume relatif de l'image : $volume(imgClosed) \rightarrow A, 1 - A / volImg \rightarrow N$ où $volImg$ est le volume de $imgFiltered\{2\}$.
 
 
 
index b699d6b..36af6d2 100644 (file)
@@ -11,7 +11,7 @@ function [THS, RBCRadius, nucleiRadius] = DetectionOfParasites(imgRGB)
 
     imgH = imgHSV(:, :, 1) * 255;
     % We shift the hue to have the greatest value for the nuclei.
-    hueShiftValue = 175;
+    hueShiftValue = 100; % 175;
     imgH = uint8(mod(255 - imgH + hueShiftValue, 256));
     imwrite(imgH, '../output/imgH.png')
 
index 48a1cae..c275618 100644 (file)
@@ -26,9 +26,10 @@ delete('../output/*');
  
 %% 13 mai 2015
 
-imagePath = '13.05.2015/1412151257-100x-Teinte30-Saturation3-0013.tif';
-imagePath = '13.05.2015/1412151257-100x-Teinte30-Saturation3-0014.tif'; % Good result.
+imagePath = '13.05.2015/1412151257-100x-Teinte30-Saturation3-0013.tif';
+imagePath = '13.05.2015/1412151257-100x-Teinte30-Saturation3-0014.tif'; % Good result.
 % imagePath = '13.05.2015/1412151257-100x-Teinte0-Saturation0-0015.tif'; % Bad result.
+% imagePath = '13.05.2015/1412151257-100x-0010.tif';
 
 segmentationMethod = SegmentationMethod.WatershedByMorphologicalGradient;
 
index dde8483..c9b1a6a 100644 (file)
@@ -89,6 +89,9 @@ function [segmentedCells] = SegmentationOfRedCells(imgRGB, RBCRadius, WBC, schiz
             imwrite(compositesOpenedGradientThresholdHolesFilled, '../output/red cells segmentation - composites opened gradient threshold holes filled.png')
             
             compositesThinning = mmthin(compositesOpenedGradientThresholdHolesFilled);
+            
+            imwrite(compositesThinning, '../output/red cells segmentation - composites thinning 1.png')
+            
             compositesThinningFlooded = mmareaclose(compositesThinning, 5 * RBCRadiusMinArea);
             compositesThinningFlooded(compositesThinning) = 0;
             compositesThinningFlooded = mmero(compositesThinningFlooded); % We erode by a 3x3 cross to avoid the composites to touch the singles when fusionning later.
diff --git a/src/WatershedsByDistanceTransform.m b/src/WatershedsByDistanceTransform.m
new file mode 100644 (file)
index 0000000..e7fbe1c
--- /dev/null
@@ -0,0 +1,24 @@
+% Watershed from a distance transformation.
+% Inspired by: http://mmorph.com/mxmorph/html/mmdemos/mmdcells.html.
+% img: A binary image.
+function [result] = WatershedsByDistanceTransform(img)
+    if ~islogical(img)
+        ME = MException('WatershedsByDistanceTransform:invalid_input_type', 'the input type must be logical');
+        throw(ME)
+    end    
+    
+    % Distance transform. Higher values denote the centers of cells.
+    distances = mmdist(img, mmsebox, 'EUCLIDEAN'); 
+    
+    % Search the regional maximums to locate the center of each cell.
+    regionalMax = mmregmax(distances); 
+    
+    % To merge some very near detected cells, avoid some isolated pixels.
+    dilatedRegionalMax  = mmdil(regionalMax, mmsedisk(5, '2D', 'EUCLIDEAN')); 
+    
+    % Apply the watershed algorithme to flood each cell from they center and find their boundaries.
+    cellBoundaries = mmcwatershed(mmneg(distances), dilatedRegionalMax, mmsebox); 
+    
+    % Cut the cells.
+    result = mmintersec(img, mmneg(cellBoundaries));
+end
\ No newline at end of file
diff --git a/src/WriteImageGradient.m b/src/WriteImageGradient.m
new file mode 100644 (file)
index 0000000..a1e0676
--- /dev/null
@@ -0,0 +1,20 @@
+% From a logical image 'img', a gradient is calculated
+% then colored with color and written in 'filename'.
+function WriteImageGradient(img, filename, color)  
+    gradientImg = mmgradm(img);
+    [M, N] = size(gradientImg);
+    red = zeros(M, N, 'uint8');
+    green = zeros(M, N, 'uint8');
+    blue = zeros(M, N, 'uint8');
+    alphaChannel = zeros(M, N, 'double');
+    
+    red(gradientImg) = color(1);
+    green(gradientImg) = color(2);
+    blue(gradientImg) = color(3);
+    alphaChannel(gradientImg) = 1;
+    
+    rgb = cat(3, red, green, blue);
+    
+    imwrite(rgb, filename, 'Alpha', alphaChannel)
+end
+