Section 3.3 and 3.4.
authorGreg Burri <greg.burri@gmail.com>
Sat, 2 May 2015 21:08:00 +0000 (23:08 +0200)
committerGreg Burri <greg.burri@gmail.com>
Sat, 2 May 2015 21:08:00 +0000 (23:08 +0200)
src/DetectionOfParasites.m
src/DetectionOfSchizonts.m
src/DetectionOfWhiteCells.m
src/IdentificationOfInfectedRedCells.m
src/Main.m
src/RemoveWBCAndSchizonts.m [new file with mode: 0644]
src/SegmentationOfRedCells.m

index 830f484..fe76424 100644 (file)
@@ -4,7 +4,7 @@
 % Outputs:
 %  THS: Parasites of all types and WBC (mask).
 %  c: Typical red cell radius [px].
-function [THS, c] = DetectionOfParasites(imgRGB)
+function [THS, c, nucleiRadius] = DetectionOfParasites(imgRGB)
     
     %% Extracting of H, S and V components
     imgHSV = rgb2hsv(imgRGB);
@@ -63,7 +63,7 @@ function [THS, c] = DetectionOfParasites(imgRGB)
     end
 
     % The paper chooses the biggest red cell size among the possible red cell sizes. (FIXME)
-    [m, c] = max(patternSpectrum);
+    [~, c] = max(patternSpectrum);
     nucleiRadius = 5; % Find a way to extract this information from the pattern spectrum histogram. (FIXME)
 
     bar(patternSpectrum);
index 823d9c5..8c59ace 100644 (file)
@@ -1,7 +1,7 @@
 % Inputs:
 %  THS:
 %  c: (TODO: should be the average red cell size)
-function [schizonts] = DetectionOfSchizonts(THS, c)    
+function [schizontsSmoothed] = DetectionOfSchizonts(THS, c)    
     
     schizontsConnectivityMin = 3; % Minimum cluster size when detecting schizonts.
     redCellsSE = mmsedisk(c, '2D', 'OCTAGON');    
@@ -24,14 +24,13 @@ function [schizonts] = DetectionOfSchizonts(THS, c)
         
     %% Check the Hausdorff distance between each set combination by dilation -> create a graph by populate 'adjacencyMatrix'.
     adjacencyMatrix = spalloc(length(sets), length(sets), 500);
-    addedSet = zeros(length(sets));
-    
+    addedSet = zeros(1, length(sets));
     for i = 1:length(sets)
         setA = sets{i};
         dilatedSetA = mmdil(setA, redCellsSE);
         for j = 1:length(sets)
             setB = sets{j};
-            if isequal(setB, setA) || addedSet(j)
+            if addedSet(j) || i == j
                 continue
             end
             if (dilatedSetA & setB) == setB % If B is a subset of A -> there are both in a Hausdorff distance of 2*c.
@@ -59,7 +58,12 @@ function [schizonts] = DetectionOfSchizonts(THS, c)
             end
         end
         n = n + 1;
-    end    
+    end
+    
+    %% Smoothing.
+    
+    % Dilation + Morphological smoothing (Hole filling).
+    schizontsSmoothed = logical(mmclohole(mmdil(schizonts, mmsedisk(4))));
     
-    imwrite(schizonts, '../output/schizonts.png')
+    imwrite(schizontsSmoothed, '../output/schizonts.png')
 end
\ No newline at end of file
index b139bc9..b9fc019 100644 (file)
@@ -8,7 +8,7 @@ function [WBCSmoothed] = DetectionOfWhiteCells(THS, c)
     WBC = mminfrec(WBCMarker, THS); % Reconstruction by dilation.
         
     % Morphological smoothing (Hole filling).
-    WBCSmoothed = mmclohole(WBC);    
+    WBCSmoothed = mmclohole(WBC);
     
     imwrite(WBCSmoothed, '../output/whiteCells.png')
 end
\ No newline at end of file
index e69de29..7a0f69f 100644 (file)
@@ -0,0 +1,5 @@
+function [infectedRedCells] = IdentificationOfInfectedRedCells(redCells, parasites)
+
+    infectedRedCells = mminfrec(parasites, redCells);    
+    imwrite(infectedRedCells, '../output/infected red cells.png')
+end
\ No newline at end of file
index a7f6ca5..40c3fdc 100644 (file)
@@ -1,7 +1,10 @@
-%% Parameters
+tic
+
+mkdir('../output'); % Just in case the 'output' directory doesn't exist.
+delete('../output/*');
 
-delete('../output')
-mkdir('../output') % Just in case the 'output' directory doesn't exist.
+
+%% Parameters
 
 % Hue is unusable for '1305121398'/'0001'
 % imageFolder = '1305121398'; % 1.
@@ -11,7 +14,7 @@ mkdir('../output') % Just in case the 'output' directory doesn't exist.
 % imageFolder = '1409191647'; % 9.
 imageFolder = '1412151257'; % 10. (Gamma)
 
-imageNumber = 'Gamma-0.8-0002';
+imageNumber = 'Gamma-0.8-0008';
 
 scaleFactor = 0.6;
 
@@ -26,20 +29,22 @@ imwrite(imgRGBResampled, '../output/imgRGB.png')
 imwrite(gtResampled, '../output/gt.png')
 
 disp('1) Detection of parasites ...')
-[THS, c] = DetectionOfParasites(imgRGBResampled);
+[THS, c, nucleiRadius] = DetectionOfParasites(imgRGBResampled);
 
 disp('2) Detection of white cells ...')
 [WBC] = DetectionOfWhiteCells(THS, c);
 
 disp('3) Detection of schizonts ...')
 [schizonts] = DetectionOfSchizonts(THS, c);
+[imgRGBRedCells] = RemoveWBCAndSchizonts(imgRGBResampled, WBC, schizonts);
 
-disp('Segmentation of red cells ...')
-SegmentationOfRedCells();
-
-% infectedRedCells = THS - WBC - schizonts;
-% imwrite(infectedRedCells, '../output/infectedRedCells.png')
+disp('4) Segmentation of red cells ...')
+[redCells] = SegmentationOfRedCells(imgRGBRedCells, c);
 
+disp('5) Finding infected red cells ...')
+parasites = THS & ~WBC & ~schizonts;
+IdentificationOfInfectedRedCells(redCells, parasites);
 
 disp('Finished')
+toc
 
diff --git a/src/RemoveWBCAndSchizonts.m b/src/RemoveWBCAndSchizonts.m
new file mode 100644 (file)
index 0000000..c3fa8d4
--- /dev/null
@@ -0,0 +1,6 @@
+function [redCells] = RemoveWBCAndSchizonts(imgRGB, WBC, schizonts)
+    redCells = imgRGB;
+    redCells(WBC) = 255;
+    redCells(schizonts) = 255;
+end
+
index 4a86c1b..3786cb2 100644 (file)
@@ -1,4 +1,49 @@
-function [] = DetectionOfSchizonts()
-
+function [redCells] = SegmentationOfRedCells(imgRGB, c)
+    cMin = uint32(c * 0.8); % 80%.
+    cMinArea = pi * cMin ^ 2;
 
+    % green = mmareaopen(imgRGB(:,:,3), 1000);
+    gray = mmareaopen(rgb2gray(imgRGB), 2 * cMinArea); % The gray image is better than the green component alone.    
+    imwrite(gray, '../output/red cells segmentation - gray.png')
+    
+    % Thresholding using the Otsu's method .
+    threshold = ~im2bw(gray, graythresh(gray));
+    
+    % We remove all objects with a smaller area than a red blood cell.
+    threshold = mmareaopen(threshold, cMinArea);
+    
+    % We set the background to 0 by using the previous threshold.
+    redCellsFiltered = gray;
+    redCellsFiltered(~threshold) = 0;
+    
+    imwrite(redCellsFiltered, '../output/red cells segmentation - input.png')
+    
+    %% Segmentation
+    opened = mmopen(redCellsFiltered, mmsedisk(cMin, '2D', 'EUCLIDEAN', 'NON-FLAT', 0));
+    imwrite(opened, '../output/red cells segmentation - opened.png')
+    
+    openedGradient = mmgradm(opened);
+    imwrite(openedGradient, '../output/red cells segmentation - opened - gradient.png')
+        
+    openedGradientThreshold = im2bw(openedGradient, 0.02);
+    imwrite(openedGradientThreshold, '../output/red cells segmentation - opened - gradient - threshold.png')
+    
+    holesClosed = mmareaclose(openedGradientThreshold, 10 * cMinArea);
+    imwrite(holesClosed, '../output/red cells segmentation - holes closed.png')
+        
+    d = holesClosed;
+    e1 = mmdist(d, mmsebox,'EUCLIDEAN');
+%     e2 = mmsurf(e1);
+    e3 = mmregmax(e1);
+    e  = mmdil(e3, mmsedisk(5, '2D', 'EUCLIDEAN'));
+    f = mmneg(e1);
+%     fs = mmsurf(f);
+%     mmshow(fs);
+    g = mmcwatershed(f, e, mmsebox);
+%     mmshow(fs, g, e);
+    h = mmintersec(d, mmneg(g));
+    i = mmareaopen(h, cMinArea / 3);
+    imwrite(i, '../output/red cells segmentation - individual.png')
+    
+    redCells = i;        
 end
\ No newline at end of file