classdef Extra_segmentation < matlab.apps.AppBase

    % Properties that correspond to app components
    properties (Access = public)
        UIFigure              matlab.ui.Figure
        Panel                 matlab.ui.container.Panel
        MaxpairsSpinner       matlab.ui.control.Spinner
        MaxpairsSpinnerLabel  matlab.ui.control.Label
        KSpinner              matlab.ui.control.Spinner
        KSpinnerLabel         matlab.ui.control.Label
        HminSpinner           matlab.ui.control.Spinner
        HminSpinnerLabel      matlab.ui.control.Label
        InverseButton         matlab.ui.control.StateButton
        ResetButton           matlab.ui.control.Button
        AlgorithmButtonGroup  matlab.ui.container.ButtonGroup
        ISODATAButton         matlab.ui.control.ToggleButton
        KmeansButton          matlab.ui.control.ToggleButton
        WatershedButton       matlab.ui.control.ToggleButton
        LoadButton            matlab.ui.control.Button
        ProcessedAxes         matlab.ui.control.UIAxes
        OriginalAxes          matlab.ui.control.UIAxes
    end


    properties (Access = private)
        RGBImage;
        GrayImage;
        Label;
    end

    methods (Access = private)

        function results = DrawImage(app)
            imshow(app.RGBImage, Parent=app.OriginalAxes);
            imshow(labeloverlay(app.RGBImage, app.Label),Parent=app.ProcessedAxes);

        end

        function results = CalculateLabels(app)

            if app.AlgorithmButtonGroup.SelectedObject == app.WatershedButton
                if app.InverseButton.Value
                    app.Label = watershed(imhmin(imcomplement(app.GrayImage),app.HminSpinner.Value/100));
                else
                    app.Label = watershed(imhmin(app.GrayImage,app.HminSpinner.Value/100));
                end
            elseif app.AlgorithmButtonGroup.SelectedObject == app.KmeansButton
                app.Label = imsegkmeans(uint8(app.RGBImage*255),app.KSpinner.Value);
            else
                app.Label = imsegisodata(app.RGBImage, "MaxPairsToMerge",app.MaxpairsSpinner.Value);
            end
        end
   
end


    % Callbacks that handle component events
    methods (Access = private)

        % Button pushed function: LoadButton
        function LoadButtonPushed(app, event)
        try
        [file, path] = uigetimagefile;
        if ~isempty(file)
            app.RGBImage = double(imread(file))/255;
            app.GrayImage = rgb2gray(app.RGBImage);

            app.CalculateLabels;
            app.DrawImage;

            app.OriginalAxes.Visible = "on";
            app.ProcessedAxes.Visible = "on";

            app.Panel.Visible = "on";
        end
        catch e
            uialert(app.UIFigure, e.message, "Error while loading image",Interpreter="html");
        end
        end

        % Selection changed function: AlgorithmButtonGroup
        function AlgorithmButtonGroupSelectionChanged(app, event)
        selectedButton = app.AlgorithmButtonGroup.SelectedObject;

        if selectedButton == app.KmeansButton
            app.MaxpairsSpinner.Visible = "off";
            app.HminSpinner.Visible = "off";
            app.KSpinner.Visible = "on";
            app.InverseButton.Visible="off";

            app.MaxpairsSpinnerLabel.Visible="off";
            app.HminSpinnerLabel.Visible ="off";
            app.KSpinnerLabel.Visible = "on";

            app.KSpinner.Value= 1;
        elseif selectedButton == app.WatershedButton
            app.MaxpairsSpinner.Visible = "off";
            app.HminSpinner.Visible = "on";
            app.KSpinner.Visible = "off";
            app.InverseButton.Visible="on";

            app.MaxpairsSpinnerLabel.Visible="off";
            app.HminSpinnerLabel.Visible ="on";
            app.KSpinnerLabel.Visible = "off";
            
            app.HminSpinner.Value = 1;
        else
            app.MaxpairsSpinner.Visible = "off";
            app.HminSpinner.Visible = "off";
            app.KSpinner.Visible = "off";
            app.InverseButton.Visible="off";

            app.MaxpairsSpinnerLabel.Visible="off";
            app.HminSpinnerLabel.Visible ="off";
            app.KSpinnerLabel.Visible = "off";
            
            app.MaxpairsSpinner.Value= 2;
        end
        app.CalculateLabels;
        app.DrawImage;
        end

        % Button pushed function: ResetButton
        function ResetButtonPushed(app, event)
            app.HminSpinner.Value = 1;
            app.KSpinner.Value= 1;
            app.MaxpairsSpinner.Value = 2;
            app.InverseButton.Value=1;
            app.CalculateLabels;
            app.DrawImage;
        end

        % Value changed function: HminSpinner, InverseButton, KSpinner, 
        % ...and 1 other component
        function MaxpairsSpinnerValueChanged(app, event)
            app.CalculateLabels;
            app.DrawImage;
            
        end
    end

    % Component initialization
    methods (Access = private)

        % Create UIFigure and components
        function createComponents(app)

            % Create UIFigure and hide until all components are created
            app.UIFigure = uifigure('Visible', 'off');
            app.UIFigure.Position = [100 100 1046 975];
            app.UIFigure.Name = 'MATLAB App';

            % Create OriginalAxes
            app.OriginalAxes = uiaxes(app.UIFigure);
            title(app.OriginalAxes, 'Original')
            app.OriginalAxes.XTick = [];
            app.OriginalAxes.YTick = [];
            app.OriginalAxes.ZTick = [];
            app.OriginalAxes.Visible = 'off';
            app.OriginalAxes.Position = [1 496 640 480];

            % Create ProcessedAxes
            app.ProcessedAxes = uiaxes(app.UIFigure);
            title(app.ProcessedAxes, 'Segmented')
            app.ProcessedAxes.XTick = [];
            app.ProcessedAxes.YTick = [];
            app.ProcessedAxes.ZTick = [];
            app.ProcessedAxes.Visible = 'off';
            app.ProcessedAxes.Position = [1 17 640 480];

            % Create LoadButton
            app.LoadButton = uibutton(app.UIFigure, 'push');
            app.LoadButton.ButtonPushedFcn = createCallbackFcn(app, @LoadButtonPushed, true);
            app.LoadButton.Position = [663 937 100 23];
            app.LoadButton.Text = 'Load';

            % Create Panel
            app.Panel = uipanel(app.UIFigure);
            app.Panel.Visible = 'off';
            app.Panel.Position = [662 33 385 905];

            % Create AlgorithmButtonGroup
            app.AlgorithmButtonGroup = uibuttongroup(app.Panel);
            app.AlgorithmButtonGroup.SelectionChangedFcn = createCallbackFcn(app, @AlgorithmButtonGroupSelectionChanged, true);
            app.AlgorithmButtonGroup.Title = 'Algorithm';
            app.AlgorithmButtonGroup.Position = [2 778 123 106];

            % Create WatershedButton
            app.WatershedButton = uitogglebutton(app.AlgorithmButtonGroup);
            app.WatershedButton.Text = 'Watershed';
            app.WatershedButton.Position = [11 52 100 23];
            app.WatershedButton.Value = true;

            % Create KmeansButton
            app.KmeansButton = uitogglebutton(app.AlgorithmButtonGroup);
            app.KmeansButton.Text = 'K-means';
            app.KmeansButton.Position = [11 31 100 23];

            % Create ISODATAButton
            app.ISODATAButton = uitogglebutton(app.AlgorithmButtonGroup);
            app.ISODATAButton.Text = 'ISODATA';
            app.ISODATAButton.Position = [11 10 100 23];

            % Create ResetButton
            app.ResetButton = uibutton(app.Panel, 'push');
            app.ResetButton.ButtonPushedFcn = createCallbackFcn(app, @ResetButtonPushed, true);
            app.ResetButton.Position = [125 881 100 23];
            app.ResetButton.Text = 'Reset';

            % Create InverseButton
            app.InverseButton = uibutton(app.Panel, 'state');
            app.InverseButton.ValueChangedFcn = createCallbackFcn(app, @MaxpairsSpinnerValueChanged, true);
            app.InverseButton.Text = 'Inverse';
            app.InverseButton.Position = [125 849 100 23];

            % Create HminSpinnerLabel
            app.HminSpinnerLabel = uilabel(app.Panel);
            app.HminSpinnerLabel.HorizontalAlignment = 'right';
            app.HminSpinnerLabel.Position = [25 740 37 22];
            app.HminSpinnerLabel.Text = 'H-min';

            % Create HminSpinner
            app.HminSpinner = uispinner(app.Panel);
            app.HminSpinner.Limits = [1 100];
            app.HminSpinner.ValueChangedFcn = createCallbackFcn(app, @MaxpairsSpinnerValueChanged, true);
            app.HminSpinner.Position = [77 740 100 22];
            app.HminSpinner.Value = 1;

            % Create KSpinnerLabel
            app.KSpinnerLabel = uilabel(app.Panel);
            app.KSpinnerLabel.HorizontalAlignment = 'right';
            app.KSpinnerLabel.Visible = 'off';
            app.KSpinnerLabel.Position = [38 740 25 22];
            app.KSpinnerLabel.Text = 'K';

            % Create KSpinner
            app.KSpinner = uispinner(app.Panel);
            app.KSpinner.Limits = [1 20];
            app.KSpinner.ValueChangedFcn = createCallbackFcn(app, @MaxpairsSpinnerValueChanged, true);
            app.KSpinner.Visible = 'off';
            app.KSpinner.Position = [78 740 100 22];
            app.KSpinner.Value = 1;

            % Create MaxpairsSpinnerLabel
            app.MaxpairsSpinnerLabel = uilabel(app.Panel);
            app.MaxpairsSpinnerLabel.HorizontalAlignment = 'right';
            app.MaxpairsSpinnerLabel.Visible = 'off';
            app.MaxpairsSpinnerLabel.Position = [5 740 57 22];
            app.MaxpairsSpinnerLabel.Text = 'Max pairs';

            % Create MaxpairsSpinner
            app.MaxpairsSpinner = uispinner(app.Panel);
            app.MaxpairsSpinner.Limits = [1 20];
            app.MaxpairsSpinner.ValueChangedFcn = createCallbackFcn(app, @MaxpairsSpinnerValueChanged, true);
            app.MaxpairsSpinner.Visible = 'off';
            app.MaxpairsSpinner.Position = [77 740 100 22];
            app.MaxpairsSpinner.Value = 2;

            % Show the figure after all components are created
            app.UIFigure.Visible = 'on';
        end
    end

    % App creation and deletion
    methods (Access = public)

        % Construct app
        function app = Extra_segmentation

            % Create UIFigure and components
            createComponents(app)

            % Register the app with App Designer
            registerApp(app, app.UIFigure)

            if nargout == 0
                clear app
            end
        end

        % Code that executes before app deletion
        function delete(app)

            % Delete UIFigure when app is deleted
            delete(app.UIFigure)
        end
    end
end