function varargout = BlobDetection(varargin)
% BLOBDETECTION MATLAB code for BlobDetection.fig
%      BLOBDETECTION, by itself, creates a new BLOBDETECTION or raises the existing
%      singleton*.
%
%      H = BLOBDETECTION returns the handle to a new BLOBDETECTION or the handle to
%      the existing singleton*.
%
%      BLOBDETECTION('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in BLOBDETECTION.M with the given input arguments.
%
%      BLOBDETECTION('Property','Value',...) creates a new BLOBDETECTION or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before BlobDetection_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to BlobDetection_OpeningFcn via varargin.
%
%      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
%      instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES

% Edit the above text to modify the response to help BlobDetection

% Last Modified by GUIDE v2.5 29-May-2011 17:26:20

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @BlobDetection_OpeningFcn, ...
                   'gui_OutputFcn',  @BlobDetection_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT


% --- Executes just before BlobDetection is made visible.
function BlobDetection_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% varargin   command line arguments to BlobDetection (see VARARGIN)

% Choose default command line output for BlobDetection
handles.output = hObject;

handles.S = 0;
set(handles.SymbolText,'String','X');

% handles.files = dir('img*.jpg');

figure(2)
figure(4)
figure(6)
figure(8)

% Update handles structure
guidata(hObject, handles);

% UIWAIT makes BlobDetection wait for user response (see UIRESUME)
% uiwait(handles.figure1);

% --- Outputs from this function are returned to the command line.
function varargout = BlobDetection_OutputFcn(hObject, eventdata, handles) 
% varargout  cell array for returning output args (see VARARGOUT);
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Get default command line output from handles structure
varargout{1} = handles.output;


% --- Executes on button press in PB_Start.
function PB_Start_Callback(hObject, eventdata, handles)
% hObject    handle to PB_Start (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

%initialize the flag variable
set(handles.PB_Start,'UserData',1); 

i = 1; % reset the counter for numbering of saved images

    nametxt = 'Test_Statistic_Final.txt'; % text file for statistic
    file = fopen(nametxt, 'wt');
    fprintf(file,'Name,\tRed,\tGreen,\tYellow,\tbRed,\tbGreen,\tbYellow,\tSymbol\n');
    fclose(file);
    

%while the flag variable is one, the loop continues
while (get(handles.PB_Start,'UserData') == 1)
    
    files = dir('img*.jpg');
    name = files(i).name;
      
    image_rgb = imread(name);
    
    figure(2), imshow(image_rgb);
    title('Original Image');

    % Converting to HSV colour space and extraction of HSV component
    hsv_image=rgb2hsv(image_rgb);
    [M,N,O]=size(hsv_image);

    image_H=hsv_image(:, :, 1);
    image_S=hsv_image(:, :, 2);
    image_V=hsv_image(:, :, 3);

    
    % ### QUANTITY OF GREEN COLOUR ###
    value = (image_H>0.26 & image_H<0.54) & image_S>0.4 & image_V>0.4;
    qG = sum(sum(value)); % quantity of green color
    
%     figure(3), imshow(value);
%     title('Value, Green');

    % Blob analysis
    Label = bwlabel(value,4);
    BlobStats = regionprops(Label, 'Area', 'Eccentricity');
    idx = find([BlobStats.Area] > 40 & [BlobStats.Eccentricity] < 0.97);
    keepBlobImage = ismember(Label, idx);     % logical
    
    G_RG = 0;
    
    if numel(idx) ~= 0

        G_RG = 1; % red & green - true

        if numel(idx) < 7
            G_RG = 0; % red & green - false
            Label = bwlabel(keepBlobImage);
            BlobStats = regionprops(Label, 'Area', 'Eccentricity', 'Extent', 'EulerNumber', 'Solidity', 'Orientation', 'BoundingBox');
            idx = find([BlobStats.Area] > 200 & [BlobStats.Eccentricity] < 0.9 & [BlobStats.Extent] > 0.4 & [BlobStats.EulerNumber] > -20 & [BlobStats.Solidity] < 0.83 & ([BlobStats.Orientation] < -60 | [BlobStats.Orientation] > 60));
            keepBlobImage = ismember(Label, idx);
        end;
        
    end;

    if numel(idx) == 1
        figure(2)
        rectangle('Position', [BlobStats(idx).BoundingBox], 'LineWidth', 1, 'EdgeColor','g')
    end;

    qGb = sum(sum(keepBlobImage)); % quantity of green color using blob detection

    figure(4), imshow(keepBlobImage);
    title('KeepBlob, Green');

    
    % ### QUANTITY OF YELLOW COLOUR ###
    value =(image_H>0.15 & image_H<0.2) & image_S>0.5 & image_V>0.4;
    qY = sum(sum(value)); % quantity of yellow color

%     figure(5), imshow(value);
%     title('value, yellow');

    % Blob analysis
    Label = bwlabel(value,4);
    BlobStats = regionprops(Label, 'Area', 'Eccentricity', 'Solidity', 'Extent', 'Orientation', 'EulerNumber'); % 'Area', 'BoundingBox', 'Eccentricity', 'EulerNumber','ConvexImage', 'ConvexArea');
    idx = find([BlobStats.Area] > 200 & [BlobStats.Eccentricity] < 0.9 & [BlobStats.Solidity] < 0.83 & [BlobStats.Extent] > 0.35 & [BlobStats.Orientation] > -25 & [BlobStats.Orientation] < 25 & [BlobStats.EulerNumber] > -8);
    keepBlobImage = ismember(Label, idx);

    if numel(idx) == 1
        
        Label = bwlabel(keepBlobImage);
        BlobStats = regionprops(Label, 'Area', 'FilledArea');
        idx = find(((BlobStats.Area / BlobStats.FilledArea > 0.93) & (BlobStats.Area / BlobStats.FilledArea < 1.01)));
        keepBlobImage = ismember(Label, idx);

        if numel(idx)~= 0
            Label = bwlabel(keepBlobImage);
            BlobStats = regionprops(Label, 'Centroid', 'BoundingBox');

            Centroid = [BlobStats.Centroid];
            if Centroid ~= 0
                figure(2)
                hold on
                plot(Centroid(:,1), Centroid(:,2), 'r+')
                hold off
            end;

            rectangle('Position', [BlobStats.BoundingBox], 'LineWidth', 1, 'EdgeColor','y')

            Cx = int16(Centroid(:,1)); % X coordinate of centroid
            L = keepBlobImage(:,1:Cx); % left part of szmbol
            R = keepBlobImage(:,Cx+1:N); % right part of szmbol

            % calculation of area for left and right part
            LabelL = bwlabel(L);
            BlobStatsL = regionprops(LabelL, 'Area');
            AreaL = [BlobStatsL.Area];
            LabelR = bwlabel(R);
            BlobStatsR = regionprops(LabelR, 'Area');
            AreaR = [BlobStatsR.Area];
            
            % compare which part is bigger and establish direction
            D = 3; % reset direction
            if AreaL > AreaR
                D = 1.3;    %direction  to the left
            else if AreaL < AreaR
                    D = 3.1;    % direction to the right
                end;
            end;
        end;
    end;

    qYb = sum(sum(keepBlobImage));    % quantity of yellow color using blob

    figure(6), imshow(keepBlobImage);
    title('KeepBlob, yellow');

    % ### QUANTITY OF RED COLOUR ###
    value = ((image_H >=0 & image_H<0.07) | (image_H >=0.96 & image_H<=1)) & image_S>0.6 & image_V>0.4;
    qR = sum(sum(value));   % quantity of red color

%     figure(7), imshow(value);
%     title('value, red');

    % Blob analysis
    Label = bwlabel(value,4);
    BlobStats = regionprops(Label, 'Area', 'Eccentricity');
    idx = find([BlobStats.Area] > 40 & [BlobStats.Eccentricity] < 0.97);
    keepBlobImage = ismember(Label, idx);
    
    R_RG = 0;

    if numel(idx) ~= 0
    
        R_RG = 1;

        if numel(idx) < 7
            R_RG = 0;
            Label = bwlabel(keepBlobImage);
            BlobStats = regionprops(Label, 'Area', 'Eccentricity', 'Solidity', 'Extent', 'BoundingBox');
            idx = find([BlobStats.Area] > 200 & [BlobStats.Eccentricity] < 0.7 & [BlobStats.Solidity] < 0.8 & [BlobStats.Solidity] > 0.4 & [BlobStats.Extent] > 0.3 & [BlobStats.Extent] < 0.8);
            keepBlobImage = ismember(Label, idx);
        end;
        
    end;

    if numel(idx) == 1
        figure(2)
        rectangle('Position', [BlobStats(idx).BoundingBox], 'LineWidth', 1, 'EdgeColor','r')
    end;

    qRb = sum(sum(keepBlobImage)); % quantity of red color using blob detection

    figure(8), imshow(keepBlobImage);
    title('keepBlobImage, red');

    % Proportion of colours, value in percent (colour segmentation)
    red   =qR/numel(image_H)*100;
    green =qG/numel(image_H)*100;
    yellow=qY/numel(image_H)*100;

    col_comp=[red green yellow];

    % Dominant colour by colour segmentation
    dC = -8;
    col={ 'red', 'green', 'yellow'};
    if numel(idx) == 1
        dC = idx;
    else if numel(idx) == 2
            dC = 22;
        else if numel(idx) == 3
                dC = 33;
            else
                    dC = 88;
            end;
        end;
    end;

    % Proportion of colours, values in percent (colour segmentation + blob analysis)
    red_b   =qRb/numel(image_H)*100;
    green_b =qGb/numel(image_H)*100;
    yellow_b=qYb/numel(image_H)*100;

    if G_RG == 1 && R_RG == 0
        green_b = 0;
    end;
    
    if R_RG == 1 && G_RG == 0
        red_b = 0;
    end;    
    
    % if there is a lot of red & green color in the image
    if (qRb + qGb) / qYb > 1
        yellow_b = 0;   
    end;

    col_comp=[red_b green_b yellow_b];
    
    % Dominant colour by colour segmentation and blob analysis
    S = -8; % reset indicator of symbol
    col={ 'red', 'green', 'yellow'};
    idx=find(col_comp > 0);
    if numel(idx) == 0
        S = 0; % no sybol detected
        else if numel(idx) == 1
            S = idx;    % indicating dominant color of image
            else if numel(idx) == 2
                    if qRb ~= 0 && qGb ~= 0
                       S = 4;   % red & green
                    else
                        idx=find(col_comp == max(col_comp));
                        S = idx;    % choose maximal value
                    end;
                else if numel(idx) == 3 % if there is each of color component in the image
                        idx=find(col_comp > 0.1);
                        if numel(idx) == 1
                            S = idx;    % indicating dominant color of image
                        else if numel(idx) == 2
                            if qRb ~= 0 && qGb ~= 0
                                S = 4;  % red & green
                            else
                                idx=find(col_comp == max(col_comp));
                                S = idx;    % choose maximal value
                            end;
                            else if numel(idx) == 3
                                    S = 33; % still too many colors
                                end;
                            end;
                        end;
                    else
                            S = 88; % error - Something is wrong... ;-)
                    end;
                end;
            end;
    end;
    
    % if detected symbol is yellow arrow, specify the direction
    if S == 3
        S = D;
    end;

    i = i + 1;  % counter for numbering of saved images
    
    file = fopen(nametxt, 'at');
    fprintf(file,'%s,\t%.0f,\t%.0f,\t%.0f,\t%.0f,\t%.0f,\t%.0f,\t%.1f\n', name, qR, qG, qY, qRb, qGb, qYb,S);
    fclose(file);
    
    handles.S = S;
    set(handles.SymbolText, 'String',num2str(handles.S));
    
end;

guidata(hObject, handles);

% --- Executes on button press in PB_Stop.
function PB_Stop_Callback(hObject, eventdata, handles)
% hObject    handle to PB_Stop (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

%toggle the flag variable so that the other process will stop
set(handles.PB_Start,'UserData',0);
guidata(hObject, handles);
