From 3ede14b1ef0b422a070b7f0cdb8ea72ce98a253d Mon Sep 17 00:00:00 2001 From: Greg Burri Date: Sun, 3 May 2015 17:31:44 +0200 Subject: [PATCH] * Beginning of the report. * Cleaning, using some relative values to the image size instead of absolute values. --- rapport/main.tex | 69 ++++++------------------------------ src/DetectionOfParasites.m | 62 +++++--------------------------- src/DetectionOfWhiteCells.m | 3 +- src/Main.m | 28 ++++++++++++--- src/SegmentationOfRedCells.m | 13 +++---- 5 files changed, 49 insertions(+), 126 deletions(-) diff --git a/rapport/main.tex b/rapport/main.tex index 6434ec7..7616ac3 100644 --- a/rapport/main.tex +++ b/rapport/main.tex @@ -14,85 +14,36 @@ \usepackage{color} \usepackage[usenames,dvipsnames]{xcolor} -\title{PA} +\title{Détection de cellules sanguines infectées par la malaria} \author{G.Burri} - \begin{document} \nocite{*} -%\maketitle +\maketitle -Fichier : 1305121398-0001.png -\begin{figure}[p] - \includegraphics[width=\linewidth]{../output/imgRGBResampled.png} - \caption{Image originale} - \label{fig:imgRGBResampled} -\end{figure} +\section{Introduction} -\begin{figure}[p] - \includegraphics[width=\linewidth]{../output/gtResampled.png} - \caption{Ground truth} - \label{fig:gtResampled} -\end{figure} +Le but de ce projet est -%%% -\begin{figure}[p] - \includegraphics[width=\linewidth]{../output/imgH.png} - \caption{Composante teinte (Hue)} - \label{fig:imgH} -\end{figure} +\section{Outils utilisés} -\begin{figure}[p] - \includegraphics[width=\linewidth]{../output/imgS.png} - \caption{Composante saturation} - \label{fig:imgS} -\end{figure} +\section{Approche générale} -%%% - -\begin{figure}[p] - \includegraphics[width=\linewidth]{../output/imgHFiltered.png} - \caption{Composante teinte filtrée : filtre médian 5x5 + \it{morphological area closing}} - \label{fig:imgHFiltered} -\end{figure} +\section{Détection des parasites} -\begin{figure}[p] - \includegraphics[width=\linewidth]{../output/imgSFiltered.png} - \caption{Composante saturation filtrée : filtre médian 5x5 + \it{morphological area closing}} - \label{fig:imgSFiltered} -\end{figure} +\section{ -%%% -\begin{figure}[p] - \includegraphics[width=\linewidth]{../granulometry_histogram.png} - \caption{Granulométrie \it{(Pattern spectrum)}} - \label{fig:granulometry_histogram} -\end{figure} +\section{Conclusion} -\begin{figure}[p] - \includegraphics[width=\linewidth]{../output/MH.png} - \caption{Marqueurs des parasites pour la composante teinte suite à l'application d'un maximum regional} - \label{fig:MH} -\end{figure} +Travaux futurs. -\begin{figure}[p] - \includegraphics[width=\linewidth]{../output/MS.png} - \caption{Marqueurs des parasites pour la composante saturation suite à l'application d'un maximum regional} - \label{fig:MS} -\end{figure} -\begin{figure}[p] - \includegraphics[width=\linewidth]{../output/MHS.png} - \caption{Intersection entre MH et MS} - \label{fig:MHS} -\end{figure} -%%% \begin{figure}[p] \includegraphics[width=\linewidth]{../output/THS.png} diff --git a/src/DetectionOfParasites.m b/src/DetectionOfParasites.m index fe76424..ab7ffc7 100644 --- a/src/DetectionOfParasites.m +++ b/src/DetectionOfParasites.m @@ -24,33 +24,29 @@ function [THS, c, nucleiRadius] = DetectionOfParasites(imgRGB) % p. 136: median filter to smooth the noise and % area closing to enhance the bright objects and make flatter, darker and cleaner the image background. medianFilterWindow = [5, 5]; - imgFiltered{1} = mmareaclose(medfilt2(imgH, medianFilterWindow), 200); % Hue. + imgFiltered{1} = mmareaclose(medfilt2(imgH, medianFilterWindow), 800); % Hue. % We use an opening fot the saturation because the parasites are darker than the rest of the image. - imgFiltered{2} = mmareaopen(medfilt2(imgS, medianFilterWindow), 200); % Saturation. - imgFiltered{3} = mmareaclose(medfilt2(imgV, medianFilterWindow), 200); % Value. + imgFiltered{2} = mmareaopen(medfilt2(imgS, medianFilterWindow), 800); % Saturation. + imgFiltered{3} = mmareaclose(medfilt2(imgV, medianFilterWindow), 800); % Value. This component isn't used. 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')); - + %% Granulometry % We use the saturation component to find the red cells mean size. + saturationComponent = imgFiltered{2}; - redCellMaxSize = 42; % Radius [px]. + redCellMaxSize = round(size(imgRGB, 2) / 35); % Radius [px], depending of the input size. funVolume = @(m) sum(sum(m)); - volImg = funVolume(imgFiltered{2}); + volImg = funVolume(saturationComponent); sizeDistribution = zeros(redCellMaxSize, 1); parfor k = 1:redCellMaxSize SE = mmsedisk(k, '2D', 'OCTAGON'); % 'EUCLIDEAN' is more precise. - imgOpened = mmopen(imgFiltered{2}, SE); + imgOpened = mmopen(saturationComponent, SE); A = funVolume(imgOpened); N = 1 - A / volImg; sizeDistribution(k) = N; @@ -64,7 +60,7 @@ function [THS, c, nucleiRadius] = DetectionOfParasites(imgRGB) % The paper chooses the biggest red cell size among the possible red cell sizes. (FIXME) [~, c] = max(patternSpectrum); - nucleiRadius = 5; % Find a way to extract this information from the pattern spectrum histogram. (FIXME) + nucleiRadius = c / 8; % We admit the size of a parasite is eight time smaller than a red blood cell. Find a way to extract this information from the pattern spectrum histogram. (FIXME) bar(patternSpectrum); @@ -100,45 +96,5 @@ function [THS, c, nucleiRadius] = DetectionOfParasites(imgRGB) imwrite(MHS, '../output/MHS.png') imwrite(THS, '../output/THS.png') - %% Display - -% figure('Position', [100 100 1600 800]) -% colormap(gray); -% -% subplot(2, 4, 1); -% imagesc(imgRGB); -% title(['Original: ', imageFolder, '/', imageNumber]); -% -% subplot(2, 4, 2); -% imagesc(imgFiltered{1}); -% title('Hue component'); -% -% subplot(2, 4, 3); -% imagesc(imgFiltered{2}); -% title('Saturation component'); -% -% subplot(2, 4, 4); -% imagesc(M{1}); -% title('MH'); -% -% subplot(2, 4, 5); -% imagesc(M{2}); -% title('MS'); -% -% subplot(2, 4, 6); -% imagesc(MHS); -% title('MHS'); -% -% subplot(2, 4, 7); -% imagesc(THS); -% title('THS'); end -% print("-f1"’, "-dpng", "Toto.png") - - - - - - - diff --git a/src/DetectionOfWhiteCells.m b/src/DetectionOfWhiteCells.m index b9fc019..5c711b2 100644 --- a/src/DetectionOfWhiteCells.m +++ b/src/DetectionOfWhiteCells.m @@ -1,7 +1,8 @@ % Inputs: % c: The typical red cell radius [px]. function [WBCSmoothed] = DetectionOfWhiteCells(THS, c) - redCellsSE = mmsedisk(c - 8, '2D', 'OCTAGON'); + % We use a radius near the smallest red blood cell size (80% of the radius) + redCellsSE = mmsedisk(c * 0.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. diff --git a/src/Main.m b/src/Main.m index 40c3fdc..0456261 100644 --- a/src/Main.m +++ b/src/Main.m @@ -14,9 +14,23 @@ delete('../output/*'); % imageFolder = '1409191647'; % 9. imageFolder = '1412151257'; % 10. (Gamma) -imageNumber = 'Gamma-0.8-0008'; +%% Gamma +% imageNumber = 'Gamma-0.8-0002'; +% imageNumber = 'Gamma-0.8-0005'; +% imageNumber = 'Gamma-0.8-0008'; -scaleFactor = 0.6; +% imageNumber = 'Gamma-1-0001'; +% imageNumber = 'Gamma-1-0004'; +imageNumber = 'Gamma-1-0007'; + +% imageNumber = 'Gamma-1.2-0003'; +% imageNumber = 'Gamma-1.2-0006'; +% imageNumber = 'Gamma-1.2-0009'; + +%% Main +fprintf('Folder: %s, Number: %s\n', imageFolder, imageNumber); + +scaleFactor = 1; % Load the image and its ground truth. [imgRGB, gt] = loadImg(imageFolder, imageNumber); @@ -43,8 +57,12 @@ disp('4) Segmentation of red cells ...') disp('5) Finding infected red cells ...') parasites = THS & ~WBC & ~schizonts; -IdentificationOfInfectedRedCells(redCells, parasites); +[infectedRedCells] = IdentificationOfInfectedRedCells(redCells, parasites); -disp('Finished') -toc +nbRedCells = mmstats(mmlabel(redCells), 'max'); +nbInfectedRedCells = mmstats(mmlabel(infectedRedCells), 'max'); +infectionPercentage = 100 * nbInfectedRedCells / nbRedCells; +fprintf('Percentage of infected cell: %.1f%%\n', infectionPercentage) +disp('Finished') +toc \ No newline at end of file diff --git a/src/SegmentationOfRedCells.m b/src/SegmentationOfRedCells.m index 3786cb2..ef12a9d 100644 --- a/src/SegmentationOfRedCells.m +++ b/src/SegmentationOfRedCells.m @@ -2,7 +2,6 @@ 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') @@ -31,19 +30,17 @@ function [redCells] = SegmentationOfRedCells(imgRGB, c) holesClosed = mmareaclose(openedGradientThreshold, 10 * cMinArea); imwrite(holesClosed, '../output/red cells segmentation - holes closed.png') + % Watershed algorithm from here: http://mmorph.com/mxmorph/html/mmdemos/mmdcells.html. 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') + i = mmedgeoff(h); + j = mmareaopen(i, cMinArea / 3); + imwrite(j, '../output/red cells segmentation - individual.png') - redCells = i; + redCells = j; end \ No newline at end of file -- 2.45.2