% skript na detekciu buniek v obraze a určenie ich vlastnosti

clear all;close all;clc

% Nacitanie obrazu a prevod na sedotonovy
image = imread('input_4.tif');
%image(:,:,4) = [];  %potrebne zapnut pri T0-B_O a T3-C_O
image_gray = rgb2gray(image);

% Posilnenie kontrastu pre posilnenie rozdielov medzi pozadim a objektmi
image_contr = imadjust(image_gray);

% posilnenie jasu pre  zvyraznenie hladanych objektov
light =30;
image_light = image_contr + light;
image_edited = image_light;

% Vypocet parametrov histogramu
[num_of_pixel, gray_tone] = imhist(image_edited);

% Urcenie prahu pre prevod na ciernobiely obraz - binarny
% Manualne nastavenie prahu podla histogramu. Hodnoty vacsie ako prah 
% su detekovane ako objekty, mensie ako pozadie
threshold = 100;
image_bw = image_edited > threshold; 
image_bw = imfill(image_bw, 'holes'); %vyplnenie dier detekovanych objektov

% Vyhladzovaci filter = Savitzky-Golay filter
window = 10;
maska = ones(window)/window^2;
image_fuzzy = conv2(single(image_bw), maska, 'same');
Smooth = image_fuzzy > 0.5; 

% Rozlisenie utvarov, ktore su blizko seba alebo sa prekryvaju, pomocou
% funkcie watershed
Label = watershed(Smooth);
image_RGB = label2rgb(Label);
% Spojenie obrazov - kompozit
image_composite = imfuse(Smooth,image_RGB);
% 
Distance = -bwdist(~Smooth);
%
Ld = watershed(Distance);

%
bw2 = Smooth;
bw2(Ld == 0) = 0;
%
mask = imextendedmin(Distance,2);
%
Distance2 = imimposemin(Distance,mask);
Ld2 = watershed(Distance2);
image_watershed = Smooth;
image_watershed(Ld2 == 0) = 0;


% identifikacia jednotlivych objektov(buniek)podla spajania rovnakych
% pixelov, vzajomne odlisenie objektov medzi sebou. najdenie ich vlastnosti
image_label = bwlabel(image_watershed, 8);
stats = regionprops(image_label,'all');
quantity = size(stats, 1);

% Vykreslenie obrazov
figure('Name','Detektor buniek','NumberTitle','off');
% Automaticke maximalizovanie obrazovky 
set(gcf, 'Position', get(0, 'Screensize'));

subplot(331)
imshow(image);
title('Pôvodný obraz');

subplot(332);
imshow(image_gray);
title('Šedotónový obraz');

subplot(333);
imshow(image_contr);
title('Úprava kontrastu');

subplot(334);
imshow(image_light);
title('Úprava jasu');

subplot(335);
bar(num_of_pixel);
grid on;
title('Histogram upraveného obrazu');
% Graficke zobrazenie prahu - treshold
hold on;
hodnota_Y = ylim;
line([threshold, threshold], hodnota_Y, 'Color', 'r');
text(double(threshold+20),double(0.8*hodnota_Y(2)),'Bunky');
text(double(threshold-50),double(0.8*hodnota_Y(2)),'Pozadie');

subplot(336);
imshow(image_bw);
title('Čiernobiely obraz (prahovanie)');
imwrite(image_bw,'Čiernobiely obraz.tif')

subplot(337);
imshow(Smooth);
title('Vyhladený obraz');
imwrite(Smooth,'smooth.jpg')

subplot(338);
imshow(image_watershed);
title('Centroidy objektov');
imwrite(image_watershed,'Centroidy.tif')
hold on;
outlines = bwboundaries(image_watershed);
num_of_outlines = size(outlines, 1);
centroidy = [stats.Centroid];
centroid_x = centroidy(1:2:end-1);
centroid_y = centroidy(2:2:end);
for i=1:num_of_outlines 
plot(centroid_x, centroid_y, 'b+', 'MarkerSize', 5, 'LineWidth', 0.5);
end

hold off;

subplot(339);
imshow(image_watershed);
hold on;
title('Ohraničenie objektov')
for i = 1:num_of_outlines
    outline_i = outlines{i};
	plot(outline_i(:,2), outline_i(:,1), 'r', 'LineWidth', 1);
end


% forma vystupu
fprintf('Celkovy pocet detekovanych buniek : %d\n', num_of_outlines) 
fprintf('Namerane vlastnosti buniek : \n')
fprintf('Bunka    Obvod     Plocha           Centroid          Priemer\n' );

% prevod vzdialenosti z pixelov na mikrometre
% rozmery povodneho obrazu : 1439x1080 pixelov = 622.18x466.55 mikrometrov
% 1 mikrometer = 1439/622.18 = 2.312 pixelov

for j = 1 : num_of_outlines
	Plocha = stats(j).Area;	
    Priemer = sqrt(4 * Plocha / pi);
	Obvod = stats(j).Perimeter;	
    Centroid = stats(j).Centroid;  % mozno netreba vypisovat, sluzi na ocislovanie buniek
	fprintf('#%2d %10.2f %10.2f %10.2f %10.2f %10.2f\n', j, Obvod/2.312, Plocha/2.312, Centroid(1), Centroid(2), Priemer/2.312);
	% Put the "blob number" labels on the "boundaries" grayscale image.
	text(Centroid(1)-4,Centroid(2),num2str(j),'FontSize',5);
end
hold off;

