From: Greg Burri Date: Fri, 24 Apr 2015 07:22:07 +0000 (+0200) Subject: Implmentation of the detection of WBC and schizonts. X-Git-Url: http://git.euphorik.ch/index.cgi?a=commitdiff_plain;h=2e4d245c1fb6e89cda91d76aea9e5866e7a82c40;p=malaria.git Implmentation of the detection of WBC and schizonts. --- diff --git a/src/DetectionOfParasites.m b/src/DetectionOfParasites.m index fd94e0e..bdb2a51 100644 --- a/src/DetectionOfParasites.m +++ b/src/DetectionOfParasites.m @@ -1,15 +1,27 @@ % 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) @@ -18,8 +30,14 @@ function [THS, c] = DetectionOfParasites(imgRGB, gt) % 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')); @@ -48,7 +66,7 @@ function [THS, c] = DetectionOfParasites(imgRGB, gt) % 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); @@ -59,7 +77,7 @@ function [THS, c] = DetectionOfParasites(imgRGB, gt) 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 @@ -67,37 +85,20 @@ function [THS, c] = DetectionOfParasites(imgRGB, gt) 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]) diff --git a/src/DetectionOfSchizonts.m b/src/DetectionOfSchizonts.m index e69de29..4d94f08 100644 --- a/src/DetectionOfSchizonts.m +++ b/src/DetectionOfSchizonts.m @@ -0,0 +1,41 @@ +% 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 % 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 % 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 diff --git a/src/DetectionOfWhiteCells.m b/src/DetectionOfWhiteCells.m index e32eb25..b139bc9 100644 --- a/src/DetectionOfWhiteCells.m +++ b/src/DetectionOfWhiteCells.m @@ -1,3 +1,14 @@ -function [] = DetectionOfParasites() +% Inputs: +% c: The typical red cell radius [px]. +function [WBCSmoothed] = DetectionOfWhiteCells(THS, c) + redCellsSE = mmsedisk(c - 8, '2D', 'OCTAGON'); + + % The white cells may not be correctly marked in the case they have a very special shape (oblong). + WBCMarker = mmero(THS, redCellsSE); % Erosion to keep only fragments of white cells. + WBC = mminfrec(WBCMarker, THS); % Reconstruction by dilation. + + % Morphological smoothing (Hole filling). + WBCSmoothed = mmclohole(WBC); + imwrite(WBCSmoothed, '../output/whiteCells.png') end \ No newline at end of file