% Detection of parasites by means of granulometry and regional maxima.
-function [THS, c] = DetectionOfParasites(imgRGB, gt)
+% Inputs:
+% imgRGB: The image of a blood sample.
+% Outputs:
+% THS: Parasites of all types and WBC (mask).
+% c: Typical red cell radius [px].
+function [THS, c] = DetectionOfParasites(imgRGB)
+ imwrite(imgRGB, '../output/imgRGB.png')
+
%% Extracting of H, S and V components
imgHSV = rgb2hsv(imgRGB);
imgH = imgHSV(:, :, 1) * 255;
% We shift the hue to have the greatest value for the nuclei.
- hueShiftValue = 195; % 100
+ hueShiftValue = 175; % 100
imgH = uint8(mod(255 - imgH + hueShiftValue, 256));
+ imwrite(imgH, '../output/imgH.png')
imgS = uint8(imgHSV(:, :, 2) * 255);
+ imwrite(imgS, '../output/imgS.png')
+
+ imgV = uint8(255 - imgHSV(:, :, 3) * 255);
+ imwrite(imgV, '../output/imgV.png')
% imgV = uint8(imgHSV(:, :, 3) * 255); % The value component isn't used.
% imgH = 255 - imgV; % We use the value component instead of the hue one (just for testing)
% area closing to enhance the bright objects and make flatter, darker and cleaner the image background.
imgFiltered{1} = mmareaclose(medfilt2(imgH, [5, 5]), 400); % Hue.
imgFiltered{2} = mmareaclose(medfilt2(imgS, [5, 5]), 400); % Saturation.
-
+ imgFiltered{3} = mmareaclose(medfilt2(imgV, [5, 5]), 400); % Value.
+
+ imwrite(imgFiltered{1}, '../output/imgHFiltered.png');
+ imwrite(imgFiltered{2}, '../output/imgSFiltered.png');
+ imwrite(imgFiltered{3}, '../output/imgVFiltered.png');
+
% Shading correction with a Top-hat transformation (p. 673).
+ % Not in the article -> disable for the moment, not needed.
% imgHFiltered = mmopenth(imgHFiltered, mmsedisk(80, '2D', 'OCTAGON'));
% imgSFiltered = mmopenth(imgSFiltered, mmsedisk(80, '2D', 'OCTAGON'));
% The paper choose the biggest red cell size among the possible red cell sizes. (FIXME)
[m, c] = max(patternSpectrum);
- c = c + 3;
+ % c = c + 3;
nucleiRadius = 5; % Find a way to extract this information from the pattern spectrum histogram. (FIXME)
bar(patternSpectrum);
regionalMaxSE = mmsedisk(c, '2D', 'OCTAGON');
- parfor i = 1:2
+ parfor i = 1:3
% This operation is very time consuming!
M{i} = mmregmax(imgFiltered{i}, regionalMaxSE);
end
nucleiSE = mmsedisk(nucleiRadius, '2D', 'OCTAGON');
MHS = mmdil(M{1}, nucleiSE) & mmdil(M{2}, nucleiSE);
- volumeMHS = funVolume(~MHS);
- muH = funVolume(uint8(~MHS) .* imgFiltered{1}) / volumeMHS;
- muS = funVolume(uint8(~MHS) .* imgFiltered{2}) / volumeMHS;
+ volumeMHS = funVolume(MHS);
+ muH = funVolume(uint8(MHS) .* imgFiltered{1}) / volumeMHS;
+ muS = funVolume(uint8(MHS) .* imgFiltered{2}) / volumeMHS;
TH = im2bw(imgFiltered{1}, double(muH) / 255);
TS = im2bw(imgFiltered{2}, double(muS) / 255);
- THS = TH & TS; % Parasites of all type and WBC.
-
-
- %% Output
-
- mkdir('../output') % Just in case the 'output' directory doesn't exist.
-
- imwrite(imgRGB, '../output/imgRGB.png')
- imwrite(gt, '../output/gt.png')
-
- imwrite(imgH, '../output/imgH.png')
- imwrite(imgS, '../output/imgS.png')
+ THS = TH & TS;
imwrite(M{1}, '../output/MH.png')
- imwrite(imgFiltered{1}, '../output/imgHFiltered.png');
-
imwrite(M{2}, '../output/MS.png')
- imwrite(imgFiltered{2}, '../output/imgSFiltered.png');
-
imwrite(MHS, '../output/MHS.png')
-
imwrite(THS, '../output/THS.png')
-
%% Display
% figure('Position', [100 100 1600 800])
+% Inputs:
+function [schizonts] = DetectionOfSchizonts(THS, c)
+
+ redCellsSE = mmsedisk(c, '2D', 'OCTAGON');
+ schizonts = zeros(size(THS), 'uint8');
+
+ %% Extract all sets.
+ sets = {};
+ n = 1;
+ remainingTHS = THS;
+ marker = false(size(THS));
+ while 1
+ [i, j] = find(remainingTHS, 1);
+ if ~isempty(i)
+ marker(i, j) = 1;
+ sets{n} = mminfrec(marker, remainingTHS); %#ok<AGROW> % Reconstruction by dilation.
+ remainingTHS = remainingTHS & ~sets{n};
+ n = n + 1;
+ marker(i, j) = 0;
+ else
+ break
+ end
+ end
+
+ %% Check the Hausdorff distance between each set combination by dilation.
+ for i = 1:length(sets)
+ setA = sets{i};
+ dilatedSetA = mmdil(setA, redCellsSE);
+ for j = 1:length(sets)
+ setB = sets{j};
+ if setB == setA
+ continue
+ end
+ if (dilatedSetA & setB) == setB %#ok<AND2> % If B is a subset of A -> there are both in a Hausdorff distance of 2*c.
+ schizonts = schizonts | setA | setB;
+ end
+ end
+ end
+
+ imwrite(schizonts, '../output/schizonts.png')
+end
\ No newline at end of file