classification code
This commit is contained in:
27
src/albina nirupa/classificationcode.m
Normal file
27
src/albina nirupa/classificationcode.m
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
%%
|
||||||
|
mkdir('E:\Experiments\odroid\A2\A2a\cells\rbc');
|
||||||
|
mkdir('E:\Experiments\odroid\A2\A2a\cells\cluster');
|
||||||
|
mkdir('E:\Experiments\odroid\A2\A2a\cells\wbc');
|
||||||
|
mkdir('E:\Experiments\odroid\A2\A2a\cells\parasite');
|
||||||
|
%%
|
||||||
|
%Classifier Function obtained after training the classifier with the
|
||||||
|
%generated training data set and the feature table
|
||||||
|
% There are 4 different catergories of classification
|
||||||
|
X = table2array(varfun(@double, CellFeature_table_A(:,trainedClassifiercells.PredictorNames)));
|
||||||
|
cellclass = predict(trainedClassifiercells, X);
|
||||||
|
|
||||||
|
for i = 1:length(cellclass)
|
||||||
|
image = imread(strcat('E:\Experiments\odroid\A2\A2a\cells\A1 (',num2str(i),').jpg'));
|
||||||
|
if(cellclass(i)== 'rbc')
|
||||||
|
imwrite(image,strcat('E:\Experiments\odroid\A2\A2a\cells\rbc\',num2str(i),'.jpg'),'jpeg');
|
||||||
|
else if (cellclass(i)== 'wbc')
|
||||||
|
imwrite(image,strcat('E:\Experiments\odroid\A2\A2a\cells\wbc\',num2str(i),'.jpg'),'jpeg');
|
||||||
|
else if (cellclass(i)== 'cluster')
|
||||||
|
imwrite(image,strcat('E:\Experiments\odroid\A2\A2a\cells\cluster\',num2str(i),'.jpg'),'jpeg');
|
||||||
|
else if (cellclass(i)== 'parasite')
|
||||||
|
imwrite(image,strcat('E:\Experiments\odroid\A2\A2a\cells\parasite\',num2str(i),'.jpg'),'jpeg');
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
37
src/albina nirupa/createMask.m
Normal file
37
src/albina nirupa/createMask.m
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
function [BW,maskedRGBImage] = createMask(RGB,Imax,Imin)
|
||||||
|
%createMask Threshold RGB image using auto-generated code from colorThresholder app.
|
||||||
|
% [BW,MASKEDRGBIMAGE] = createMask(RGB) thresholds image RGB using
|
||||||
|
% auto-generated code from the colorThresholder App. The colorspace and
|
||||||
|
% minimum/maximum values for each channel of the colorspace were set in the
|
||||||
|
% App and result in a binary mask BW and a composite image maskedRGBImage,
|
||||||
|
% which shows the original RGB image values under the mask BW.
|
||||||
|
|
||||||
|
% Auto-generated by colorThresholder app on 12-Dec-2015
|
||||||
|
%------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
% Convert RGB image to chosen color space
|
||||||
|
I = RGB;
|
||||||
|
|
||||||
|
% Define thresholds for channel 1 based on histogram settings
|
||||||
|
channel1Min = Imin;%132.000;
|
||||||
|
channel1Max = Imax;%182.000;
|
||||||
|
|
||||||
|
% Define thresholds for channel 2 based on histogram settings
|
||||||
|
channel2Min = channel1Min;%131.000;
|
||||||
|
channel2Max = channel1Max;%177.000;
|
||||||
|
|
||||||
|
% Define thresholds for channel 3 based on histogram settings
|
||||||
|
channel3Min = channel1Min;%130.000;
|
||||||
|
channel3Max = channel1Max;%180.000;
|
||||||
|
|
||||||
|
% Create mask based on chosen histogram thresholds
|
||||||
|
BW = (I(:,:,1) >= channel1Min ) & (I(:,:,1) <= channel1Max) & ...
|
||||||
|
(I(:,:,2) >= channel2Min ) & (I(:,:,2) <= channel2Max) & ...
|
||||||
|
(I(:,:,3) >= channel3Min ) & (I(:,:,3) <= channel3Max);
|
||||||
|
|
||||||
|
% Initialize output masked image based on input image.
|
||||||
|
maskedRGBImage = RGB;
|
||||||
|
|
||||||
|
% Set background pixels where BW is false to zero.
|
||||||
|
maskedRGBImage(repmat(~BW,[1 1 3])) = 0;
|
||||||
223
src/albina nirupa/whole_blood_segment_odroid.m
Normal file
223
src/albina nirupa/whole_blood_segment_odroid.m
Normal file
@@ -0,0 +1,223 @@
|
|||||||
|
%%
|
||||||
|
%The code creates a feature table for the different types of cells and
|
||||||
|
%is used to create a initial training dataset for the classifier
|
||||||
|
|
||||||
|
%%
|
||||||
|
clc ;
|
||||||
|
close all;
|
||||||
|
clear all;
|
||||||
|
%%
|
||||||
|
mkdir('E:\Experiments\odroid\S\S1\gate1');
|
||||||
|
mkdir('E:\Experiments\odroid\S\S1\gate2');
|
||||||
|
mkdir('E:\Experiments\odroid\S\S1\gate3');
|
||||||
|
mkdir('E:\Experiments\odroid\S\S1\gate4');
|
||||||
|
mkdir('E:\Experiments\odroid\S\S1\P');
|
||||||
|
%%
|
||||||
|
% To create a circular mask to eliminate the spokes channels and perform
|
||||||
|
% processing of cells in the central imaging region
|
||||||
|
% Create a logical image of a circle with specified
|
||||||
|
% diameter, center, and image size.
|
||||||
|
% First create the image.
|
||||||
|
imageSizeX = 640; %X pixel size of the image
|
||||||
|
imageSizeY = 480; %Y pixel size of the image
|
||||||
|
[columnsInImage rowsInImage] = meshgrid(1:imageSizeX, 1:imageSizeY);
|
||||||
|
% Next create the circle in the image.
|
||||||
|
centerX = 300; %center X pixel of the circle
|
||||||
|
centerY = 240; %center y pixel of the circle
|
||||||
|
radius = 220; %Radius of the circle
|
||||||
|
circlePixels = (rowsInImage - centerY).^2 ...
|
||||||
|
+ (columnsInImage - centerX).^2 <= radius.^2; % creates the circular mask
|
||||||
|
|
||||||
|
%% Generate Background
|
||||||
|
%a = rgb2gray(imread(strcat('E:\Experiments\odroid\step1\1 (',num2str(V),').jpg')));
|
||||||
|
%imshow(a);
|
||||||
|
%%% average ten frames to generate background.
|
||||||
|
bg = 0; V=1;
|
||||||
|
count = 500 ;% set number of frame to be averaged
|
||||||
|
N = 1; % start frame number
|
||||||
|
for i = N:N+count
|
||||||
|
bg = bg +double(rgb2gray((imread(strcat('E:\Experiments\odroid\S\S1\1 (',num2str(V+i),').jpg')))));
|
||||||
|
end
|
||||||
|
bg = uint8(bg /count); % Final Background generated.
|
||||||
|
imshow(uint8(circlePixels).*bg);
|
||||||
|
%%
|
||||||
|
tic
|
||||||
|
r =0;b=0;
|
||||||
|
count = 0;
|
||||||
|
maxglcm = 0;
|
||||||
|
Cont =0;Corr=0;Homo=0;I_mean=0;I_std=0;I_cir=0;I_area =0;stain=0;
|
||||||
|
ccount = 0;
|
||||||
|
C_Percentstained =0;StainMaxlength=0;StainMinlength=0;StainSolid=0; StainNumobj=0;
|
||||||
|
Features_table = [];F=[];
|
||||||
|
CellFeature_table = [];cell=[];
|
||||||
|
% Feature_table = table('VariableNames',{'Area', 'ConvexArea', 'Eccentricity', 'EquivDiameter', 'EulerNumber', 'Extent', 'FilledArea', 'MajorAxisLength', 'MinorAxisLength', 'Orientation', 'Perimeter', 'Solidity'});
|
||||||
|
for V =1:29999
|
||||||
|
disp(V);
|
||||||
|
Shape_Features =[]; Texture_Features1 = [];
|
||||||
|
% The if condition is used to refresh the background for every 2000 frames
|
||||||
|
% This helps eliminate any debris/ struck cells in the ROI
|
||||||
|
if mod(V,2000) == 0
|
||||||
|
%if V <19999-30
|
||||||
|
% bg1 = bg;
|
||||||
|
bg =0;
|
||||||
|
count = 300 ;% set number of frame to be averaged
|
||||||
|
N = 1; % start frame number
|
||||||
|
for i = N:N+count
|
||||||
|
bg = bg +double(rgb2gray((imread(strcat('E:\Experiments\odroid\S\S1\1 (',num2str(V+i),').jpg')))));
|
||||||
|
end
|
||||||
|
bg = uint8(bg /count); % Final Background generated.
|
||||||
|
% bg = (bg+bg1)/2.0
|
||||||
|
end
|
||||||
|
% The following section performs the segmentation based on histogram values
|
||||||
|
CurrFrame = (rgb2gray((imread(strcat('E:\Experiments\odroid\S\S1\1 (',num2str(V),').jpg')))));
|
||||||
|
Sub =double(double(CurrFrame.*uint8(circlePixels))-double(bg.*uint8(circlePixels)));
|
||||||
|
%imshow(Sub);
|
||||||
|
Submin = min(Sub(:));
|
||||||
|
Submax = max(Sub(:));
|
||||||
|
AdjBGSub = uint8( (Sub - Submin)/(Submax-Submin) * 255);
|
||||||
|
Ia = AdjBGSub;
|
||||||
|
[A, B]=size(Ia);
|
||||||
|
I = medfilt2(Ia); % To smoothen the image
|
||||||
|
I = adapthisteq(I);
|
||||||
|
I1 = medfilt2(I);
|
||||||
|
Irgb = cat(3, I1, I1, I1);
|
||||||
|
meanIntensityValue(V) = mean2(I1); % Finds the mean of the intensities of the image pixels
|
||||||
|
stdIntensityValue = std2(I1); % Finds the standard deviation of the intensities of the image pixels
|
||||||
|
% Selection of max and minimum of intensities for the thresholding
|
||||||
|
%This multipication factor can be varied when you are optimizing the
|
||||||
|
%thresholding
|
||||||
|
Imax = meanIntensityValue(V)+stdIntensityValue*4; % mean+ 4*standard deviation
|
||||||
|
Imin = meanIntensityValue(V)-stdIntensityValue*4; % mean- 4*standard deviation
|
||||||
|
% Further processing of the thresholded image
|
||||||
|
Mask = createMask(Irgb,Imax,Imin);%figure;imshow(Mask);
|
||||||
|
MaskInv = ~Mask;
|
||||||
|
Maskopen =bwareaopen(MaskInv,150);%figure;imshow(Maskfinal);
|
||||||
|
% Maskdil = imdilate(Maskopen, [se90 se0]);%figure;imshow(Maskdil);
|
||||||
|
Maskdil = imclose(Maskopen, strel('disk',5));
|
||||||
|
Maskfill = imfill(Maskdil, 'holes');%figure;imshow(Maskfill);
|
||||||
|
Maskclose = Maskfill;
|
||||||
|
% Maskclose = imclose(Maskfill, strel('disk',5));
|
||||||
|
Maskclear = imclearborder(Maskclose, 4);%figure;imshow(Maskclear);
|
||||||
|
Maskfinal = Maskclear;
|
||||||
|
% Filter image based on image properties.
|
||||||
|
Maskfinal = bwpropfilt(Maskfinal, 'Area', [350 + eps(350), Inf]); % Area greater than 350 pixels
|
||||||
|
Maskfinal = bwpropfilt(Maskfinal, 'Solidity', [0.6 + eps(0.6), Inf]); % 1 is completely solid region
|
||||||
|
Maskfinal = bwpropfilt(Maskfinal, 'EulerNumber', [4.94065646e-324 + eps(4.94065646e-324), Inf]);
|
||||||
|
%Extract properties of all the cells in the thresholded image
|
||||||
|
Maskproperties = regionprops(Maskfinal, {'Area', 'ConvexArea', 'Eccentricity', 'EquivDiameter', 'EulerNumber', 'Extent', 'FilledArea', 'MajorAxisLength', 'MinorAxisLength', 'Orientation', 'Perimeter', 'Solidity'});
|
||||||
|
% Creates a feature table of all the above listed properties for all the
|
||||||
|
% segmented cells/regions in the image
|
||||||
|
Shape_Features = struct2table(Maskproperties);
|
||||||
|
%Plotting of 200 images to see the performance of segmetation operations
|
||||||
|
if V<200
|
||||||
|
h= figure;
|
||||||
|
subplot(2,3,1);
|
||||||
|
subimage(Mask);
|
||||||
|
title('Mask');
|
||||||
|
|
||||||
|
subplot(2,3,2);
|
||||||
|
subimage(Maskfill);
|
||||||
|
title('Maskfill');
|
||||||
|
|
||||||
|
subplot(2,3,3);
|
||||||
|
subimage(Maskdil);
|
||||||
|
title('Maskdil');
|
||||||
|
|
||||||
|
subplot(2,3,4);
|
||||||
|
subimage(uint8(MaskInv).*I1);
|
||||||
|
title('Maskclose');
|
||||||
|
% subplot(1,2,1);
|
||||||
|
subplot(2,3,5);
|
||||||
|
subimage(I1);
|
||||||
|
title('I1');
|
||||||
|
% subplot(1,2,2);
|
||||||
|
subplot(2,3,6);
|
||||||
|
subimage(uint8(Maskfinal).*I1);
|
||||||
|
title(' Maskfinal');
|
||||||
|
%saveas(h,strcat('E:\Experiments\odroid\S\S1\gate4\FrameNumber','-',num2str(V)),'jpg');
|
||||||
|
close(h);
|
||||||
|
% figure;imshow(uint8(Maskfinal).*I);
|
||||||
|
% figure;imshow(I);
|
||||||
|
end
|
||||||
|
% Generation of the traning images for the classification program
|
||||||
|
CComp = bwconncomp(Maskfinal);
|
||||||
|
Areas = regionprops(CComp,'Area');
|
||||||
|
Centroids1=regionprops(CComp,'Centroid');
|
||||||
|
Perimeters=regionprops(CComp,'Perimeter');
|
||||||
|
Texture_Features=[];
|
||||||
|
for i = 1:CComp.NumObjects
|
||||||
|
Cent = Centroids1(i).Centroid;
|
||||||
|
HighX = round(Cent(1))+20;
|
||||||
|
if HighX>B
|
||||||
|
HighX =B;
|
||||||
|
end
|
||||||
|
HighY = round(Cent(2))+20;
|
||||||
|
if HighY>A
|
||||||
|
HighY =A;
|
||||||
|
end
|
||||||
|
LowX = round(Cent(1))-19;
|
||||||
|
if LowX<=0
|
||||||
|
LowX =1;
|
||||||
|
end
|
||||||
|
|
||||||
|
LowY = round(Cent(2))-19;
|
||||||
|
if LowY<=0
|
||||||
|
LowY =1;
|
||||||
|
end
|
||||||
|
|
||||||
|
ccount = ccount +1;%,num2str(V),'.avi'
|
||||||
|
Icrop=Ia(LowY:HighY,LowX:HighX);
|
||||||
|
Icrop1=I(LowY:HighY,LowX:HighX);
|
||||||
|
Maskcrop=Maskfinal(LowY:HighY,LowX:HighX);
|
||||||
|
imwrite(Icrop,strcat('E:\Experiments\odroid\S\S1\gate3\FrameNumber','-',num2str(V),'_',num2str(ccount),'.jpg'));
|
||||||
|
% Additional texture features for the feature table
|
||||||
|
glcm = graycomatrix(Icrop1);%gray level covariance matrix
|
||||||
|
maxglcm(ccount)=max(max(glcm)); %Feature 1
|
||||||
|
stats(ccount) = graycoprops(glcm,{'Contrast','Correlation','homogeneity'});
|
||||||
|
Texture_Features = struct2table(stats(ccount));
|
||||||
|
% Cont(ccount)= stats(ccount).Contrast; %Feature 2
|
||||||
|
% Corr(ccount) = stats(ccount).Correlation; %Feature 3
|
||||||
|
% Homo(ccount)= stats(ccount).Homogeneity;%Feature 4
|
||||||
|
% Ent(ccount)= stats(ccount).Entropy;
|
||||||
|
I_mean(ccount) = mean2(Icrop1); %Feature 5
|
||||||
|
I_std(ccount)=std2(Icrop1); %Feature 6
|
||||||
|
I_cir(ccount) = ((Shape_Features.Perimeter(i))^ 2)/ (4 * pi * Shape_Features.Area(i)); %Feature 7
|
||||||
|
|
||||||
|
% Percentage of stained area
|
||||||
|
BWthresh = im2bw(Icrop,0.15);
|
||||||
|
BWthreshtemp =~(BWthresh).*Maskcrop;
|
||||||
|
CC1 =bwconncomp(imcomplement(BWthresh).*Maskcrop);
|
||||||
|
MaxLength = regionprops(CC1,'MajorAxisLength');
|
||||||
|
MinLength = regionprops(CC1,'MinorAxisLength');
|
||||||
|
Solid = regionprops(CC1,'Solidity');
|
||||||
|
% imwrite(~BWthresh,strcat('E:\Experiments\odroid\A2\A2a\gate2\FrameNumber','-',num2str(V),'_',num2str(ccount),'.jpg'));
|
||||||
|
Areas_stained = regionprops(CC1,'Area');
|
||||||
|
StainNumobj(ccount) = CC1.NumObjects;
|
||||||
|
if CC1.NumObjects ==0
|
||||||
|
C_Percentstained(ccount) = 0;
|
||||||
|
StainMaxlength(ccount) = 0;StainMinlength(ccount) = 0;
|
||||||
|
StainSolid(ccount) = 0; StainSolid(ccount) = 0;
|
||||||
|
else
|
||||||
|
if (max(struct2array(MaxLength))/max(struct2array(MinLength)))<2
|
||||||
|
F = [F; max(struct2array(MaxLength))/max(struct2array(MinLength))];
|
||||||
|
% imwrite(Icrop,strcat('E:\Experiments\odroid\A2\A2a\P\FrameNumber','-',num2str(V),'_',num2str(ccount),'.jpg'));
|
||||||
|
end
|
||||||
|
C_Percentstained(ccount) = sum(struct2array(Areas_stained))/max((Shape_Features.Area(i)))*100;
|
||||||
|
StainMaxlength(ccount) = max(struct2array(MaxLength));
|
||||||
|
StainMinlength(ccount) = max(struct2array(MinLength));
|
||||||
|
StainSolid(ccount) = max(struct2array(Solid));
|
||||||
|
% Stainproperties = regionprops(BWthreshtemp, {'Area', 'ConvexArea', 'Eccentricity', 'EquivDiameter', 'EulerNumber', 'Extent', 'FilledArea', 'MajorAxisLength', 'MinorAxisLength', 'Orientation', 'Perimeter', 'Solidity'});
|
||||||
|
% Parasite_Features = struct2table(Stainproperties);
|
||||||
|
end
|
||||||
|
Texture_Features1 = [Texture_Features; Texture_Features1];
|
||||||
|
end
|
||||||
|
if CComp.NumObjects>0
|
||||||
|
Features = [Shape_Features Texture_Features1]; %Variable Addition
|
||||||
|
|
||||||
|
Features_table = [Features_table; Features]; % Table update
|
||||||
|
end
|
||||||
|
cell = table(I_mean', I_std', I_cir', maxglcm', C_Percentstained',StainMaxlength',StainMinlength',StainSolid', StainNumobj');
|
||||||
|
cell.Properties.VariableNames = {'Mean' 'Std' 'Circularity' 'MaxGLCM' 'Percentage_Stain' 'StainMaxlength' 'StainMinlength' 'StainSolid' 'StainNumobj'};
|
||||||
|
CellFeature_table = [Features_table cell]; % Table update
|
||||||
|
end
|
||||||
|
toc
|
||||||
Reference in New Issue
Block a user