Matlab: Classification

(German) This post describes a Matlab function which classifies images dependent on shape color and so on to differentiate between images like bananas and apples.

Mode of operation:

In this function different attributes of images are calculated in values to classify images and seperate them in 2D or 3D. Classification methodes are 'color', 'color2' and 'colorhex' for different color classifications and 'brightness' for the brightness value 'shape', 'std', 'mean', 'cov' and 'sub' are different shape conditions. This function can be downloaded on MathWorks. Following figure shows the classification of apples, bananas and black berries. 


It is seen in three dimensions it is clearly classified. Most of the mathematical algortihm are based on magnitude gradient maps to whether calculate shape or substructures. Following figure shows the different input images and their gradient map.
In source code give below there is an example how to use it. MLClassification(image,class_1,class_2,class_3) classifies the image according to class 1-3 with 3 output arguments. Iteratively over all images this is done and then plotted. With parzen window approach a Gaussian cloud is fitted around the values with a standard deviation of 2 to border the different image groups. The function Gaussian cloud is given at the very bottom of the source code. 
To determine where an image belongs the function IdentifyClass(ax1, ax2, ax3, ax4, varargin) is used. It calculates the minimal distance to the Gaussian cloud surface of the different groups. Because mathematically elliptic bodies have no analytical solutions the function [~, dist] = PointOnSurface(XData, YData, ZData, arg1, arg2, arg3); calculates it numerically which can be downloaded here

Source code:

tic;
%% ____________________Plotting___________________%%
class_1 = 'color';
class_2 = 'shape';
class_3 = 'sub';
% Processing Apple
tresh = 0.35;
cd(dir_apple);
for i=1:1:length(files_apple)
    img_apple{i} = im2double(imread(names_apple{i}));
    image = img_apple{i};
    [arg1_apple(i), arg2_apple(i), arg3_apple(i)] = MLClassification(image,class_1,class_2,class_3);
end

% Processing Apple Green
cd(dir_others);
for i=1:1:length(files_others)
    img_others{i} = im2double(imread(names_others{i}));
    image = img_others{i};
    [arg1_others(i), arg2_others(i), arg3_others(i)] = MLClassification(image,class_1,class_2,class_3);
end

% Processing Banana
cd(dir_banana);
for i=1:1:length(files_banana)
    img_banana{i} = im2double(imread(names_banana{i}));
    image = img_banana{i};
    [arg1_banana(i), arg2_banana(i), arg3_banana(i)] = MLClassification(image,class_1,class_2,class_3);
end

col_1 = 'darkred';
col_2 = 'yellow';
col_3 = 'black';
fig(2) = figure(2);clf(2);
dev = 1.2;
ax1 = subplot(2,2,1);hold on;box on;%set(gca,'xtick',[]);set(gca,'ytick',[]);
plot(arg1_apple,arg2_apple,'.','Markersize',12,'Color',clrs(col_1));
plot(arg1_banana,arg2_banana,'.','Markersize',12,'Color',clrs(col_2));
plot(arg1_others,arg2_others,'.','Markersize',12,'Color',clrs(col_3));
GaussCloud(arg1_apple,arg2_apple,'Color',clrs(col_1),'dev',dev);
GaussCloud(arg1_banana,arg2_banana,'Color',clrs(col_2),'dev',dev);
GaussCloud(arg1_others,arg2_others,'Color',clrs(col_3),'dev',dev);
% LinearDiscriment(arg2_apple,arg1_apple,arg2_banana,arg1_banana);
xlabel(class_1);ylabel(class_2);

ax2 = subplot(2,2,2);hold on;box on;%set(gca,'xtick',[]);set(gca,'ytick',[]);
plot(arg1_apple,arg3_apple,'.','Markersize',12,'Color',clrs(col_1));
plot(arg1_banana,arg3_banana,'.','Markersize',12,'Color',clrs(col_2));
plot(arg1_others,arg3_others,'.','Markersize',12,'Color',clrs(col_3));
GaussCloud(arg1_apple,arg3_apple,'Color',clrs(col_1),'dev',dev);
GaussCloud(arg1_banana,arg3_banana,'Color',clrs(col_2),'dev',dev);
GaussCloud(arg1_others,arg3_others,'Color',clrs(col_3),'dev',dev);
xlabel(class_1);ylabel(class_3);

ax3 = subplot(2,2,3);hold on;box on;%set(gca,'xtick',[]);set(gca,'ytick',[]);
plot(arg3_apple,arg2_apple,'.','Markersize',12,'Color',clrs(col_1));
plot(arg3_banana,arg2_banana,'.','Markersize',12,'Color',clrs(col_2));
plot(arg3_others,arg2_others,'.','Markersize',12,'Color',clrs(col_3));
GaussCloud(arg3_apple,arg2_apple,'Color',clrs(col_1),'dev',dev);
GaussCloud(arg3_banana,arg2_banana,'Color',clrs(col_2),'dev',dev);
GaussCloud(arg3_others,arg2_others,'Color',clrs(col_3),'dev',dev);
xlabel(class_3);ylabel(class_2)

ax4 = subplot(2,2,4);hold on;box on;%set(gca,'xtick',[]);set(gca,'ytick',[]);set(gca,'ztick',[]);
plot3(arg1_apple,arg2_apple,arg3_apple,'.','Markersize',12,'Color',clrs(col_1));
plot3(arg1_banana,arg2_banana,arg3_banana,'.','Markersize',12,'Color',clrs(col_2));
plot3(arg1_others,arg2_others,arg3_others,'.','Markersize',12,'Color',clrs(col_3));
GaussCloud(arg1_apple,arg2_apple,arg3_apple,'Color',clrs(col_1),'dev',dev);
GaussCloud(arg1_banana,arg2_banana,arg3_banana,'Color',clrs(col_2),'dev',dev);
GaussCloud(arg1_others,arg2_others,arg3_others,'Color',clrs(col_3),'dev',dev);
xlabel(class_1);ylabel(class_2);zlabel(class_3);view(15,15);axis tight;

time_2 = toc;

% __________Load Image for Classification__________$
choice = questdlg('Load image for classification?', ...
    'Question DLG', ...
    'Yes','No','No');
switch choice
    case 'Yes'
        use_own = 1;
    case 'No'
        use_own = 0;
end

if use_own == 1
    id = IdentifyClass(ax1 ,ax2, ax3, ax4,'args',class_1,class_2,class_3);
end

%% ____________________Identify Class_____________________%%
function varargout = IdentifyClass(ax1, ax2, ax3, ax4, varargin)
% Identify to which class the loaded image belongs to with the distance
% function
ax_dist = get(ax4);

varargout = cell(length(varargin),1);
logic = strcmp(varargin,'args');
if any(logic)~= 0
    args = find(logic,1);
    class_1 = varargin{args+1};
    class_2 = varargin{args+2};
    class_3 = varargin{args+3};
else
    class_1 = 'color';
    class_2 = 'shape';
    class_3 = 'std';
end

[filename, pathname] = uigetfile({'*.jpg';'*.bmp';'*.gif';'*.*'},'File Selector');
cd(pathname);

img_test = im2double(imread(filename));
col_test = 'blue';
[arg1_test, arg2_test, arg3_test] = MLClassification(img_test,class_1,class_2,class_3);

XData1 = ax_dist.Children(5).XData;YData1 = ax_dist.Children(5).YData;ZData1 = ax_dist.Children(5).ZData;
XData2 = ax_dist.Children(3).XData;YData2 = ax_dist.Children(3).YData;ZData2 = ax_dist.Children(3).ZData;
XData3 = ax_dist.Children(1).XData;YData3 = ax_dist.Children(1).YData;ZData3 = ax_dist.Children(1).ZData;

[~, dist_1] = PointOnSurface(XData1, YData1, ZData1, arg1_test, arg2_test, arg3_test);
[~, dist_2] = PointOnSurface(XData2, YData2, ZData2, arg1_test, arg2_test, arg3_test);
[~, dist_3] = PointOnSurface(XData3, YData3, ZData3, arg1_test, arg2_test, arg3_test);

dist = [dist_1 dist_2 dist_3];

varargout{1} = dist;
fprintf('The loaded image belongs to class %d', I);

plot(ax1,arg1_test,arg2_test,'.','Markersize',12,'Color',clrs(col_test));
plot(ax2,arg1_test,arg3_test,'.','Markersize',12,'Color',clrs(col_test));
plot(ax3,arg3_test,arg2_test,'.','Markersize',12,'Color',clrs(col_test));
plot3(ax4,arg1_test,arg2_test,arg3_test,'.','Markersize',12,'Color',clrs(col_test));
%
% plot(ax1,surf_1(1),surf_1(2),'x','Markersize',12,'Color',clrs(col_test));
% plot(ax2,surf_1(1),surf_1(3),'x','Markersize',12,'Color',clrs(col_test));
% plot(ax3,surf_1(3),surf_1(2),'x','Markersize',12,'Color',clrs(col_test));
% plot3(ax4,surf_1(1),surf_1(2),surf_1(3),'x','Markersize',12,'Color',clrs(col_test));
   
end  


%% ________________Gauss Cloud_________________________%%
function [middle, distances, stds] = GaussCloud(x,y,varargin)

if isstring(varargin{1})
    ex = 0;
    z = zeros(numel(x),1);
else
    z = varargin{1};
    ex = 1;
end
% Color defintion
logic_col = strcmp(varargin,'Color');
if any(logic_col)~= 0
    pos_col = find(logic_col,1);
    col = varargin{pos_col+1};
else
    col = [0 0 0];
end
% Size
logic_col = strcmp(varargin,'dev');
if any(logic_col)~= 0
    pos_col = find(logic_col,1);
    dev = varargin{pos_col+1};
else
    dev = 1;
end
%Markersize definition
logic_size = strcmp(varargin,'Markersize');
if any(logic_size)~= 0
    pos_mark = find(logic_size,1);
    mark_size = varargin{pos_mark+1};
else
    mark_size = 12;
end
% Transparency definition
logic_alpha = strcmp(varargin,'Alpha');
if any(logic_alpha)~= 0
    pos_alpha = find(logic_alpha,1);
    alpha = varargin{pos_alpha+1};
else
    alpha = 0.25;
end

% The Function

mean_x = mean(x);
mean_y = mean(y);
mean_z = mean(z);
middle = [mean_x,mean_y,mean_z];

std_x = std(x);
std_y = std(y);
std_z = std(z);
stds = [std_x,std_y,std_z];

vec_x = mean_x-x;mean_dist_x = mean(vec_x);
vec_y = mean_y-y;mean_dist_y = mean(vec_y);
vec_z = mean_z-z;mean_dist_z = mean(vec_z);
distances = [mean_dist_x, mean_dist_y, mean_dist_z];
   
% generate sphere
[X,Y,Z] = sphere(100);
X = X.*(2*std_x*dev);
Y = Y.*(2*std_y*dev);
Z = Z.*(2*std_z*dev);

X = X+mean_x;
Y = Y+mean_y;
Z = Z+mean_z;

hold on;
if ex == 1
    plot3(mean_x,mean_y,mean_z,'x','Markersize',mark_size,'Color',col);
    surf(X,Y,Z,'FaceAlpha',alpha,'FaceColor',col,'EdgeColor','none');
else
    plot(mean_x,mean_y,'x','Markersize',mark_size,'Color',col);
    surf(X,Y,Z,'FaceAlpha',alpha,'FaceColor',col,'EdgeColor','none');
end

end



Kommentare

Beliebte Posts aus diesem Blog

Easy Plots in HTML/PHP with Google Charts

Matlab: 3D Coordinate System Rotations with Vectors

Matlab: Dijkstra methode - shortest way on gradient (small neighborhood)