% 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);
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);
% 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');
%% 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.
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
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
+function [infectedRedCells] = IdentificationOfInfectedRedCells(redCells, parasites)
+
+ infectedRedCells = mminfrec(parasites, redCells);
+ imwrite(infectedRedCells, '../output/infected red cells.png')
+end
\ No newline at end of file
-%% 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.
% imageFolder = '1409191647'; % 9.
imageFolder = '1412151257'; % 10. (Gamma)
-imageNumber = 'Gamma-0.8-0002';
+imageNumber = 'Gamma-0.8-0008';
scaleFactor = 0.6;
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
--- /dev/null
+function [redCells] = RemoveWBCAndSchizonts(imgRGB, WBC, schizonts)
+ redCells = imgRGB;
+ redCells(WBC) = 255;
+ redCells(schizonts) = 255;
+end
+
-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