classdef APLICACAO_IMG_FINAL_FINAL_FINAL_REUNIAORMVS < matlab.apps.AppBase

    % Properties that correspond to app components
    properties (Access = public)
        UIFigure                     matlab.ui.Figure
        OBJECTDETECTIONPanel         matlab.ui.container.Panel
        CONTOURSPanel                matlab.ui.container.Panel
        ShowContoursButton           matlab.ui.control.Button
        UIAxesObjectContours         matlab.ui.control.UIAxes
        REGIONOFINTERESTPanel        matlab.ui.container.Panel
        SelectROIButton              matlab.ui.control.Button
        SelectFullObjectButton       matlab.ui.control.Button
        SelectRegionofInterestforContoursPanel  matlab.ui.container.Panel
        DropDownSelectROIForContour  matlab.ui.control.DropDown
        Label                        matlab.ui.control.Label
        TargetAreaPanel              matlab.ui.container.Panel
        ViewTargetAreaButton         matlab.ui.control.Button
        Image                        matlab.ui.control.Image
        GetTargetAreaButton          matlab.ui.control.Button
        ZLabel                       matlab.ui.control.Label
        YLabel                       matlab.ui.control.Label
        XLabel                       matlab.ui.control.Label
        EditField_Zmax               matlab.ui.control.NumericEditField
        EditField_Zmin               matlab.ui.control.NumericEditField
        EditField_Xmax               matlab.ui.control.NumericEditField
        EditField_Ymax               matlab.ui.control.NumericEditField
        EditField_Ymin               matlab.ui.control.NumericEditField
        EditField_Xmin               matlab.ui.control.NumericEditField
        ViewFullPointCloudButton     matlab.ui.control.Button
        GetFullPointCloudButton      matlab.ui.control.Button
        ExitButton                   matlab.ui.control.Button
        VIDEOSTREAMSPanel            matlab.ui.container.Panel
        DepthVideoStreamLabel        matlab.ui.control.Label
        RGBVideoStreamLabel          matlab.ui.control.Label
        StartStreamsButton           matlab.ui.control.Button
        UIAxesDEPTHStream            matlab.ui.control.UIAxes
        UIAxesRGBStream              matlab.ui.control.UIAxes
    end

    
    methods (Access = private)
        

        
        function [pcloud, distance] = depthToCloud(~,depth,topleft,profmax)
            % FUNÇAO TRANSFORMA IMAGEM DEPTH EM NUVEM DE PONTOS
            if nargin < 2
                topleft = [1 1];
            end

            depth= double(depth);
            depth(depth>profmax) = nan;
            depth(depth==0) = nan;

            % RGB-D camera constants
            center = [320 240];
            [imh, imw] = size(depth);
            constant = 570.3;
            MM_PER_M = 1000;

            % convert depth image to 3d point clouds
            pcloud = zeros(imh,imw,3);
            xgrid = ones(imh,1)*(1:imw) + (topleft(1)-1) - center(1);
            ygrid = (1:imh)'*ones(1,imw) + (topleft(2)-1) - center(2);
            pcloud(:,:,1) = xgrid.*depth/constant/MM_PER_M;
            pcloud(:,:,2) = ygrid.*depth/constant/MM_PER_M;
            pcloud(:,:,3) = depth/MM_PER_M;
            distance = sqrt(sum(pcloud.^2,3));            
        end
    end
    

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

        % Code that executes after component creation
        function startupFcn(app)
            % FAZER RESET À CAMARA
            imaqreset
            
            % DESATIVAR TODOS OS BOTÕES AO INICIAR A APP
            set(app.GetFullPointCloudButton,'Enable','off')
            set(app.ViewFullPointCloudButton,'Enable','off')
            set(app.EditField_Xmax,'Enable','off')
            set(app.EditField_Xmin,'Enable','off')
            set(app.EditField_Ymax,'Enable','off')
            set(app.EditField_Ymin,'Enable','off')
            set(app.EditField_Zmax,'Enable','off')
            set(app.EditField_Zmin,'Enable','off')
            set(app.GetTargetAreaButton,'Enable','off')
            set(app.SelectFullObjectButton,'Enable','off')
            set(app.ShowContoursButton,'Enable','off')
            set(app.SelectROIButton,'Enable','off')
            set(app.DropDownSelectROIForContour,'Enable','off')
            set(app.ViewTargetAreaButton,'Enable','off')
        end

        % Button pushed function: StartStreamsButton
        function StartStreamsButtonPushed(app, event)
            %% GLOBALS
            global DEPTHDisp
            global RGBDisp
            global imgRGB
            global RGBFrameFlipped
            global DEPTHFrameFlipped

            %% FECHAR JANELA ABERTA
            close(figure(1))

           % ATIVAR O BOTAO PARA OBTER NUVEM COMPLETA, DEPOIS DO BOTÃO PARA OBTER AS STREAMS SER CLICKADO
            if app.StartStreamsButton.Enable
                set(app.GetFullPointCloudButton,'Enable','on')
            end

            % AVISAR O USER QUE É NECESSÁRIO ESPERAR PELA DEPTH CAM ESTABILIZAR PARA SE OBTER A NUVEM DE PONTOS
            if app.StartStreamsButton.Enable
                uialert(app.UIFigure,'Depth camera must be stabilised before proceeding to further steps','Depth camera stabilization','Icon','warning')
            end

            %% RGB
            % LIGAR CAMARA RGB
            RGBDisp = videoinput('kinect',1,'RGB_640x480');

            RGBFrameFlipped = flip(getsnapshot(RGBDisp),2);
            imgRGB = image(app.UIAxesRGBStream,zeros(size(RGBFrameFlipped),'uint16'));

            % MOSTRAR RGB STREAM
            axis(app.UIAxesRGBStream,'image');
            preview(RGBDisp,imgRGB);

            % RESOLUÇAO DA STREAM VIDEO RGB
            app.UIAxesRGBStream.XLim = [0,640];
            app.UIAxesRGBStream.YLim = [0,480];
            pbaspect(app.UIAxesRGBStream,[640,480,1]);

            %% DEPTH
            % LIGAR CAMARA DEPTH
            DEPTHDisp = videoinput('kinect',2,'Depth_640x480');

            DEPTHFrameFlipped = flip(getsnapshot(DEPTHDisp),2);
            imgDEPTH = image(app.UIAxesDEPTHStream,zeros(size(DEPTHFrameFlipped),'uint16'));

            % MOSTRAR DEPTH STREAM
            axis(app.UIAxesDEPTHStream)
            preview(DEPTHDisp,imgDEPTH)

            % RESOLUÇAO DA STREAM VIDEO DEPTH
            app.UIAxesDEPTHStream.XLim = [0,640];
            app.UIAxesDEPTHStream.YLim = [0,480];
            pbaspect(app.UIAxesDEPTHStream,[640,480,2]);
            colormap(app.UIAxesDEPTHStream,'jet')

        end

        % Button pushed function: GetFullPointCloudButton
        function GetFullPointCloudButtonPushed(app, event)
            %% GLOBALS
            global DEPTHDisp
            global RGBDisp
            global ptCloudRot

            % ATIVAR O BOTAO PARA OBTER NUVEM COMPLETA, DEPOIS DO BOTÃO PARA OBTER AS STREAMS SER CLICKADO
            if app.GetFullPointCloudButton.Enable
                set(app.GetTargetAreaButton,'Enable','on')
                set(app.EditField_Xmax,'Enable','on')
                set(app.EditField_Xmin,'Enable','on')
                set(app.EditField_Ymax,'Enable','on')
                set(app.EditField_Ymin,'Enable','on')
                set(app.EditField_Zmax,'Enable','on')
                set(app.EditField_Zmin,'Enable','on')
                set(app.ViewFullPointCloudButton,'Enable','on')
            end

            % MUDAR O NOME DO BOTAO DEPOIS DESTE SER CLICKADO
            if app.GetFullPointCloudButton.Enable
                app.GetFullPointCloudButton.Text = "Update Full Point Cloud";
            end

            %% FECHAR JANELA ABERTA
            close(figure(1))

            %% NUVEM DE PONTOS COMPLETA
            % EXTRAIR A NUVEM DE PONTOS
            RGBFrame1 = getsnapshot(RGBDisp);
            DEPTHFrame1 = getsnapshot(DEPTHDisp);

            ptCloudOriginal = pcfromkinect(DEPTHDisp, DEPTHFrame1, RGBFrame1);

            %% RODAR A NUVEM DE PONTOS PARA FICAR PARALELA COM EIXO DOS XX
            %ANGULO DE ROTAÇAO
            theta = -0.04;

            % MATRIZ DE ROTAÇAO EM X
            Rx = [1 0 0; 0 cos(theta) -sin(theta); 0 sin(theta) cos(theta)];
            trans = [0, 0, 0];
            tform = rigid3d(Rx,trans);

            % NOVA NUVEM DE PONTOS RODADA
            ptCloudRot = pctransform(ptCloudOriginal,tform);

            % MOSTAR NUVEM DE PONTOS
            figure
            pcshow(ptCloudRot,"VerticalAxis","Y",VerticalAxisDir="Down");
            title('Full Point Cloud')
            xlabel('X(m)')
            ylabel('Y(m)')
            zlabel('Z(m)')

        end

        % Button pushed function: ViewFullPointCloudButton
        function ViewFullPointCloudButtonPushed(app, event)
            %% GLOBALS
            global ptCloudRot

            % MOSTAR NUVEM DE PONTOS
            figure
            pcshow(ptCloudRot,"VerticalAxis","Y",VerticalAxisDir="Down");
            title('Full Point Cloud')
            xlabel('X(m)')
            ylabel('Y(m)')
            zlabel('Z(m)')
        end

        % Button pushed function: GetTargetAreaButton
        function GetTargetAreaButtonPushed(app, event)
            %% GLOBALS
            global ptCloudRot
            global ptcloudB
            
            % ATIVAR O BOTAO PARA OBTER NUVEM COMPLETA, DEPOIS DO BOTÃO PARA OBTER AS STREAMS SER CLICKADO
            if app.GetTargetAreaButton.Enable
                set(app.SelectFullObjectButton,'Enable','on')
                set(app.ViewTargetAreaButton,'Enable','on')
            end

            % MUDAR O NOME DO BOTAO DEPOIS DESTE SER CLICKADO
             if app.GetTargetAreaButton.Enable
                app.GetTargetAreaButton.Text = "Update Target Area";
            end

            %% FECHAR JANELA ABERTA
            close(figure(1))
            
            %% DEFINIR UMA ROI CUBICA PARA ASSUMIR A TARGET AREA
            % ESPECIDICAR O STEP SIZE 
            stepSize = 100;

            % AMOSTRA A NUVEM DE PONTOS DE ENTRADA E ARMAZENA AS COORDENADAS DE PONTOS COMO UM OBJETO DE NUVEM DE PONTOS
            indices = 1:stepSize:ptCloudRot.Count;
            tempPtCloud = select(ptCloudRot,indices);

            % REMOVER OS PONTOS INVALIDOS DENTRO DA AMOSTRA ANTERIOR
            [tempPtCloud,validIndices] = removeInvalidPoints(tempPtCloud);

            % OBTER AS COORDENADAS DE LOCALIZAÇAO 3D DOS PONTOS DA NUVEM DE PONTOS
            worldPoints = tempPtCloud.Location;

            % CONVERTER E ENCONTRAR AS COORDENADAS DOS PONTOS 2D CORRESPONDENTES AOS PONTOS 3D DA NUVEM
            [Y,X] = ind2sub([size(ptCloudRot.Location,1),size(ptCloudRot.Location,2)],indices);
            imagePoints = [X(validIndices)' Y(validIndices)'];

            % ESTIMATIVA DA MATRIZ DE PROJEÇAO DA CAMARA A PARTIR DA IMAGEM E DAS COORDENADAS DOS PONTOS DE LOCALIZAÇAO 3D
            camMatrix = estimateCameraMatrix(imagePoints,worldPoints);

            % DEFINIR A ROI CUBICA PARA A TARGET AREA
            roi = [app.EditField_Xmin.Value app.EditField_Xmax.Value app.EditField_Ymin.Value app.EditField_Ymax.Value app.EditField_Zmin.Value app.EditField_Zmax.Value];
            
            % ENCONTRAR OS INDICES DOS PONTOS DA NUVEM QUE ESTAO DENTRO DA ROI CUBICA
            indices = findPointsInROI(ptCloudRot,roi,camMatrix);

            % SELECIONAR OS PONTOS DA NUVEM QUE SE ENCONTRAM DENTRO DA ROI
            ptcloudB = select(ptCloudRot,indices);

            % MOSTRAR A NUVEM DE PONTOS COM A TARGER AREA
            figure
            pcshow(ptCloudRot,"VerticalAxis","Y",VerticalAxisDir="Down")
            hold on
            pcshow(ptcloudB.Location,'r',"VerticalAxis","Y",VerticalAxisDir="Down")
            title('Full Point Cloud with Target Area')
            xlabel('X(m)')
            ylabel('Y(m)')
            zlabel('Z(m)')

            % DEFINIÇÃO DOS PONTOS DOS VERTICES DO CUBO DA ROI
            p1 = [app.EditField_Xmin.Value app.EditField_Ymax.Value app.EditField_Zmax.Value]';
            p2 = [app.EditField_Xmin.Value app.EditField_Ymax.Value app.EditField_Zmin.Value]';
            p3 = [app.EditField_Xmax.Value app.EditField_Ymax.Value app.EditField_Zmin.Value]';
            p4 = [app.EditField_Xmax.Value app.EditField_Ymax.Value app.EditField_Zmax.Value]';
            p5 = [app.EditField_Xmin.Value app.EditField_Ymin.Value app.EditField_Zmax.Value]';
            p6 = [app.EditField_Xmin.Value app.EditField_Ymin.Value app.EditField_Zmin.Value]';
            p7 = [app.EditField_Xmax.Value app.EditField_Ymin.Value app.EditField_Zmin.Value]';
            p8 = [app.EditField_Xmax.Value app.EditField_Ymin.Value app.EditField_Zmax.Value]';

            % DEFINIR AS FACES DO CUBO ATRAVES DOS VERTICES ANTERIORES
            A1=[p1 p2 p3 p4;p4 p3 p7 p8;p7 p8 p5 p6;p7 p6 p2 p3;p6 p5 p1 p2;p8 p5 p1 p4];

            % CORES DAS FACES
            p=fill3(A1(1,:),A1(2,:),A1(3,:),'--w');
            p.FaceAlpha = 0.3;
            p=fill3(A1(4,:),A1(5,:),A1(6,:),'--w');
            p.FaceAlpha = 0.3;
            p=fill3(A1(7,:),A1(8,:),A1(9,:),'--w');
            p.FaceAlpha = 0.3;
            p=fill3(A1(10,:),A1(11,:),A1(12,:),'--w');
            p.FaceAlpha = 0.3;
            p=fill3(A1(13,:),A1(14,:),A1(15,:),'--w');
            p.FaceAlpha = 0.3;
            p=fill3(A1(16,:),A1(17,:),A1(18,:),'--w');
            p.FaceAlpha = 0.3;

            hold off
        end

        % Button pushed function: ViewTargetAreaButton
        function ViewTargetAreaButtonPushed(app, event)
            %% GLOBALS
            global ptCloudRot
            global ptcloudB

             % MOSTRAR A NUVEM DE PONTOS COM A TARGER AREA
            figure
            pcshow(ptCloudRot,"VerticalAxis","Y",VerticalAxisDir="Down")
            hold on
            pcshow(ptcloudB.Location,'r',"VerticalAxis","Y",VerticalAxisDir="Down")
            title('Full Point Cloud with Target Area')
            xlabel('X(m)')
            ylabel('Y(m)')
            zlabel('Z(m)')

            % DEFINIÇÃO DOS PONTOS DOS VERTICES DO CUBO DA ROI
            p1 = [app.EditField_Xmin.Value app.EditField_Ymax.Value app.EditField_Zmax.Value]';
            p2 = [app.EditField_Xmin.Value app.EditField_Ymax.Value app.EditField_Zmin.Value]';
            p3 = [app.EditField_Xmax.Value app.EditField_Ymax.Value app.EditField_Zmin.Value]';
            p4 = [app.EditField_Xmax.Value app.EditField_Ymax.Value app.EditField_Zmax.Value]';
            p5 = [app.EditField_Xmin.Value app.EditField_Ymin.Value app.EditField_Zmax.Value]';
            p6 = [app.EditField_Xmin.Value app.EditField_Ymin.Value app.EditField_Zmin.Value]';
            p7 = [app.EditField_Xmax.Value app.EditField_Ymin.Value app.EditField_Zmin.Value]';
            p8 = [app.EditField_Xmax.Value app.EditField_Ymin.Value app.EditField_Zmax.Value]';

            % DEFINIR AS FACES DO CUBO ATRAVES DOS VERTICES ANTERIORES
            A1=[p1 p2 p3 p4;p4 p3 p7 p8;p7 p8 p5 p6;p7 p6 p2 p3;p6 p5 p1 p2;p8 p5 p1 p4];

            % CORES DAS FACES
            p=fill3(A1(1,:),A1(2,:),A1(3,:),'--w');
            p.FaceAlpha = 0.3;
            p=fill3(A1(4,:),A1(5,:),A1(6,:),'--w');
            p.FaceAlpha = 0.3;
            p=fill3(A1(7,:),A1(8,:),A1(9,:),'--w');
            p.FaceAlpha = 0.3;
            p=fill3(A1(10,:),A1(11,:),A1(12,:),'--w');
            p.FaceAlpha = 0.3;
            p=fill3(A1(13,:),A1(14,:),A1(15,:),'--w');
            p.FaceAlpha = 0.3;
            p=fill3(A1(16,:),A1(17,:),A1(18,:),'--w');
            p.FaceAlpha = 0.3;

            hold off
        end

        % Button pushed function: SelectFullObjectButton
        function SelectFullObjectButtonPushed(app, event)
              %% GLOBALS
            global ptcloudB
            global pclimpa

             % ATIVAR O BOTAO PARA OBTER NUVEM COMPLETA, DEPOIS DO BOTÃO PARA OBTER AS STREAMS SER CLICKADO
            if app.SelectFullObjectButton.Enable
                set(app.ShowContoursButton,'Enable','on')
                set(app.SelectROIButton,'Enable','on')
                set(app.DropDownSelectROIForContour,'Enable','on')
            end

            %% FECHAR JANELA ABERTA
            close(figure(1))

            %% REMOVER O PLANO DO CHAO
            % DEFINIR A DISTANCIA MAXIMA PONTO-PLANO PARA A MONTAGEM DO PLANO
            maxDistance = 0.0005;     % (m)

            % DEFINIR O VETOR NORMAL AO PLANO A DEFINIR (NESTE CASO VETOR PREPENDICULAR AO PLANO Y)
            referenceVector = [0,1,0];

            % DETETAR O PLANO E EXTRAI-LO DA NUVEM DE PONTOS
            [~,~,outlierIndices] = pcfitplane(ptcloudB,maxDistance,referenceVector);
            remainPtCloud = select(ptcloudB,outlierIndices);

            % REMOVER O BARULHO DA NUVEM DE PONTOS (ELIMINAR "IMPUREZAS")
            pclimpa = pcdenoise(remainPtCloud,"NumNeighbors",100);

            % MOSTRAR A NUVEM DE PONTOS LIMPA E SEM O PLANO DO CHAO
            figure
            pcshow(pclimpa,"VerticalAxis","Y",VerticalAxisDir="Down")
            title('Object Cloud Point')
            xlabel('X(m)')
            ylabel('Y(m)')
            zlabel('Z(m)')
        end

        % Button pushed function: SelectROIButton
        function SelectROIButtonPushed(app, event)
            %% GLOBALS
            global pclimpa
            global ptCloudRot
            global DEPTHDisp
            global RGBDisp
            global ROI_RGB_cropped
            global pcloud

            % AVISAR O USER QUE É NECESSÁRIO FAZER DOUBLE CLICK PARA ESCOLHER A ROI
            if app.SelectROIButton.Enable
                uialert(app.UIFigure,'Draw a rectangle to mark the Region of Interest. Double click inside the rectangle to select the ROI.','Info','Icon','info')
            end

            % RETIRAR UM FRAME DA CAMARA RGB E DEPTH
            DEPTHFrameFlipped2 = flip(getsnapshot(DEPTHDisp),2);
            RGBFrameFlipped2 = flip(getsnapshot(RGBDisp),2);

            % COMPARAR A NUVEM DE PONTOS COMPLETA COM A NUVEM DE PONTOS DO OBJETO PARA ENCONTRAR OS PONTOS SEMELHANTES E GUARDA OS INDICES DESSES PONTOS NUMA NOVA VARIAVEL 
            indicescor=0;
            for i=1:size(pclimpa.Location(:,1))
                indicescor= [indicescor find(ptCloudRot.Location(:,:,1)==pclimpa.Location(i,1) & ptCloudRot.Location(:,:,2)==pclimpa.Location(i,2) & ptCloudRot.Location(:,:,3)==pclimpa.Location(i,3))];
            end

            % LINHAS E COLUNAS DA MATRIZ DO OBJETO SELECIONADO
            [row_c,col_c] = ind2sub([480 640],indicescor(2:end));

            % CRIAR UMA IMAGEM PRETA DO MESMO TAMANHO DO FRAME RGB
            Black_roi=zeros(size(RGBFrameFlipped2));

            % CONVERTER OS PONTOS IGUAIS (NUVEM COMPLETA E DO OBJETO OU SEJA O OBJETO) A CORES E O RESTO A PRETO
            for i=1:size(col_c,2)
                Black_roi(row_c(i),col_c(i),:)=1;
            end

            RGBFrameFlipped2(Black_roi==0)=0;
            IMG_roi=RGBFrameFlipped2;

            % MOSTRAR A IMAGEM PARA SELECIONAR A ROI
            figure(200)
            imshow(IMG_roi)

            % ROI COMO UM RECTANGULO DEFINIDO PELO USER
            h1 = imrect;

            % ESPERAR PELO USER DEFINIR A ROI PARA SE OBTER A SUA POSIÇAO
            position1 = wait(h1);

            % RECORTAR A IMAGEM PELA POSIÇAO DEFINIDA ANTERIORMENTE
            ROI_RGB_cropped = imcrop(IMG_roi, position1);

            % PEQUENA CALIBRAÇAO PARA COINCIDIR A IMAGEM DEPTH COM A RGB
            position2 = [position1(1) (position1(2)-20) position1(3)+10 position1(4)+10];

            % RECORTAR A IMAGEM DEPTH PELA MESMA POSIÇAO QUE A RGB
            ROI_DEPTH_cropped =  imcrop(DEPTHFrameFlipped2, position2);

            % FECHAR A JANELA DA ROI DEFINIDA
            close(figure(200))

            % DEFINIR DISTANCIA MAX PARA ELIMINAR PERTURBAÇÕES ATRAS DO OBJETO
            profmax=(app.EditField_Zmax.Value)*1000;

            % CRIAR A NUVEM DE PONTOS COM OS PONTOS SELECIONADOS PELA ROI
            [pcloud, ~] = depthToCloud(app,ROI_DEPTH_cropped,position1,profmax);

            % MOSTRAR A NUVEM DE PONTOS DA ROI
            figure
            pcshow(pcloud,"VerticalAxis","Y",VerticalAxisDir="Down",MarkerSize=10)
            title('ROI Point Cloud')
            xlabel('X(m)')
            ylabel('Y(m)')
            zlabel('Z(m)')
        end

        % Button pushed function: ShowContoursButton
        function ShowContoursButtonPushed(app, event)
            %% GLOBALS
            global pclimpa
            global pcloud

            switch app.DropDownSelectROIForContour.Value
                case 'Full Object'
                    % EXTRAIR COORDENADAS X E Y DO OBJETO (RETIRAR Z)
                    xnuvem = pclimpa.Location(:,1);
                    ynuvem = pclimpa.Location(:,2);

                    % FAZER PLOT DOS PONTOS X E Y DO OBJETO E RODAR O PLOT
                    plot(app.UIAxesObjectContours,xnuvem,ynuvem,'.k')
                    set(app.UIAxesObjectContours,'ydir','reverse')
                    axis(app.UIAxesObjectContours,'off')

                    % RETIRAR FRAME DO PLOT ANTERIOR
                    frameplot = frame2im(getframe(app.UIAxesObjectContours));
                    %                     imgplot = imresize(frameplot,[480,640]);
                    %                     imshow(imgplot,'Parent',app.UIAxesObjectContours)
                    %                     title('plot frame')
                    %                     figure
                    %                     imshow(imgplot)

                    % BINARIZAR IMG E INVERTER COR
                    imgbin = imbinarize(im2gray(frameplot));
                    inverseimg = uint8(255) - im2uint8(imgbin);
                    %                     imshow(inverseimg,'Parent',app.UIAxesObjectContours)
                    %                     figure
                    %                     imshow(inverseimg)

                    % PREENCHER ESPAÇOS ABERTOS NO OBJETO
                    se = strel('disk',5);
                    j = imclose(inverseimg,se);
                    %                     imshow(j,'Parent',app.UIAxesObjectContours)
                    %                     figure
                    %                     imshow(j)

                    % FAZER CONTORNOS DO OBJETO
                    imgedge1 = bwperim(j);

                    imgpContorno = imgedge1;
%                     imshow(imgedge1,'Parent',app.UIAxesObjectContours)
                    %                     figure
                    %                     imshow(imgedge1)


                case 'ROI'
                    % EXTRAIR COORDENADAS X E Y DO OBJETO (RETIRAR Z)
                    xnuvem_roi = pcloud(:,:,1);
                    ynuvem_roi = pcloud(:,:,2);

                    % FAZER PLOT DOS PONTOS X E Y DO OBJETO E RODAR O PLOT
                    plot(app.UIAxesObjectContours,xnuvem_roi,ynuvem_roi,'.k')
                    set(app.UIAxesObjectContours,'ydir','reverse')
                    axis(app.UIAxesObjectContours,'off')

                    % RETIRAR FRAME DO PLOT ANTERIOR
                    frameplot_roi = frame2im(getframe(app.UIAxesObjectContours));
                    %                     imgplot = imresize(frameplot,[480,640]);
                    %                     imshow(imgplot,'Parent',app.UIAxesObjectContours)
                    %                     title('plot frame')
                    %                     figure
                    %                     imshow(imgplot)

                    % BINARIZAR IMG E INVERTER COR
                    imgbin_roi = imbinarize(im2gray(frameplot_roi));
                    inverseimg_roi = uint8(255) - im2uint8(imgbin_roi);
                    %                     imshow(inverseimg,'Parent',app.UIAxesObjectContours)
                    %                     figure
                    %                     imshow(inverseimg)

                    % PREENCHER ESPAÇOS ABERTOS NO OBJETO
                    se_roi = strel('disk',10);
                    j_roi = imclose(inverseimg_roi,se_roi);
                    %                     imshow(j,'Parent',app.UIAxesObjectContours)
                    %                     figure
                    %                     imshow(j)

                    % FAZER CONTORNOS DO OBJETO
                    imgedge1_roi = bwperim(j_roi);

                    imgpContorno = imgedge1_roi;
                    %                     imshow(imgedge1_roi,'Parent',app.UIAxesObjectContours)
                    %                     figure
                    %                     imshow(imgedge1)
            end

            % RETIRAR LINHAS E COLUNAS DOS PONTOS DOS CONTORNOS
            [rowbw1,colbw1] = find(imgpContorno==1);

            % RETIRAR O PONTO MINIMO E MAX DOS CONTORNOS PARA FORMATAR JANELA DE VISUALIZAÇAO
            rowmax12 = max(rowbw1)+10;
            rowmin12 = min(rowbw1)-10;
            colmax12 = max(colbw1)+10;
            colmin12 = min(colbw1)-10;

            % NAO DEIXAR QUE A FORMATAÇAO DA JANELA NAO ULTRAPASSE A RESOLUÇAO DA IMAGEM
            if rowmin12 < 0
                rowmin12 = 1;
            end
            if rowmax12 > size(imgpContorno,1)
                rowmax12 = size(imgpContorno,1);
            end

            if colmin12 < 0
                colmin12 = 1;
            end
            if colmax12 > size(imgpContorno,2)
                colmax12 = size(imgpContorno,2);
            end

            % MOSTRAR IMAGEM RECORTADA COM OS CONTORNOS
            novaimagembw1 = imgpContorno(rowmin12:rowmax12,colmin12:colmax12,:);
            imshow(novaimagembw1,'Parent',app.UIAxesObjectContours)
            ax = app.UIAxesObjectContours;
            ax.PlotBoxAspectRatio = [1.33 1 1];

        end

        % Button pushed function: ExitButton
        function ExitButtonPushed(app, event)
            % FECHAR APLICAÇAO E TODAS AS JANELAS ABERTAS
            app.delete
            close all
        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 1169 671];
            app.UIFigure.Name = 'MATLAB App';

            % Create VIDEOSTREAMSPanel
            app.VIDEOSTREAMSPanel = uipanel(app.UIFigure);
            app.VIDEOSTREAMSPanel.Title = 'VIDEO STREAMS';
            app.VIDEOSTREAMSPanel.Position = [21 53 354 605];

            % Create UIAxesRGBStream
            app.UIAxesRGBStream = uiaxes(app.VIDEOSTREAMSPanel);
            app.UIAxesRGBStream.Box = 'on';
            app.UIAxesRGBStream.Position = [21 378 312 185];

            % Create UIAxesDEPTHStream
            app.UIAxesDEPTHStream = uiaxes(app.VIDEOSTREAMSPanel);
            app.UIAxesDEPTHStream.Box = 'on';
            app.UIAxesDEPTHStream.Position = [21 138 313 185];

            % Create StartStreamsButton
            app.StartStreamsButton = uibutton(app.VIDEOSTREAMSPanel, 'push');
            app.StartStreamsButton.ButtonPushedFcn = createCallbackFcn(app, @StartStreamsButtonPushed, true);
            app.StartStreamsButton.Position = [128 68 100 22];
            app.StartStreamsButton.Text = 'Start Streams';

            % Create RGBVideoStreamLabel
            app.RGBVideoStreamLabel = uilabel(app.VIDEOSTREAMSPanel);
            app.RGBVideoStreamLabel.Position = [124 554 107 22];
            app.RGBVideoStreamLabel.Text = 'RGB Video Stream';

            % Create DepthVideoStreamLabel
            app.DepthVideoStreamLabel = uilabel(app.VIDEOSTREAMSPanel);
            app.DepthVideoStreamLabel.Position = [121 314 113 22];
            app.DepthVideoStreamLabel.Text = 'Depth Video Stream';

            % Create ExitButton
            app.ExitButton = uibutton(app.UIFigure, 'push');
            app.ExitButton.ButtonPushedFcn = createCallbackFcn(app, @ExitButtonPushed, true);
            app.ExitButton.Position = [1038 10 100 22];
            app.ExitButton.Text = 'Exit';

            % Create OBJECTDETECTIONPanel
            app.OBJECTDETECTIONPanel = uipanel(app.UIFigure);
            app.OBJECTDETECTIONPanel.Title = 'OBJECT DETECTION';
            app.OBJECTDETECTIONPanel.Position = [398 53 740 604];

            % Create GetFullPointCloudButton
            app.GetFullPointCloudButton = uibutton(app.OBJECTDETECTIONPanel, 'push');
            app.GetFullPointCloudButton.ButtonPushedFcn = createCallbackFcn(app, @GetFullPointCloudButtonPushed, true);
            app.GetFullPointCloudButton.Position = [18 544 300 32];
            app.GetFullPointCloudButton.Text = 'Get Full Point Cloud';

            % Create ViewFullPointCloudButton
            app.ViewFullPointCloudButton = uibutton(app.OBJECTDETECTIONPanel, 'push');
            app.ViewFullPointCloudButton.ButtonPushedFcn = createCallbackFcn(app, @ViewFullPointCloudButtonPushed, true);
            app.ViewFullPointCloudButton.Position = [415 544 300 32];
            app.ViewFullPointCloudButton.Text = 'View Full Point Cloud';

            % Create TargetAreaPanel
            app.TargetAreaPanel = uipanel(app.OBJECTDETECTIONPanel);
            app.TargetAreaPanel.TitlePosition = 'centertop';
            app.TargetAreaPanel.Title = 'Target Area';
            app.TargetAreaPanel.Position = [18 289 697 244];

            % Create EditField_Xmin
            app.EditField_Xmin = uieditfield(app.TargetAreaPanel, 'numeric');
            app.EditField_Xmin.HorizontalAlignment = 'left';
            app.EditField_Xmin.Position = [41 158 52 22];
            app.EditField_Xmin.Value = -0.5;

            % Create EditField_Ymin
            app.EditField_Ymin = uieditfield(app.TargetAreaPanel, 'numeric');
            app.EditField_Ymin.HorizontalAlignment = 'left';
            app.EditField_Ymin.Position = [42 126 52 22];

            % Create EditField_Ymax
            app.EditField_Ymax = uieditfield(app.TargetAreaPanel, 'numeric');
            app.EditField_Ymax.Position = [132 126 52 22];
            app.EditField_Ymax.Value = 0.4;

            % Create EditField_Xmax
            app.EditField_Xmax = uieditfield(app.TargetAreaPanel, 'numeric');
            app.EditField_Xmax.Position = [132 158 52 22];
            app.EditField_Xmax.Value = 0.5;

            % Create EditField_Zmin
            app.EditField_Zmin = uieditfield(app.TargetAreaPanel, 'numeric');
            app.EditField_Zmin.HorizontalAlignment = 'left';
            app.EditField_Zmin.Position = [42 93 52 22];
            app.EditField_Zmin.Value = 1.2;

            % Create EditField_Zmax
            app.EditField_Zmax = uieditfield(app.TargetAreaPanel, 'numeric');
            app.EditField_Zmax.Position = [132 92 52 22];
            app.EditField_Zmax.Value = 1.7;

            % Create XLabel
            app.XLabel = uilabel(app.TargetAreaPanel);
            app.XLabel.HorizontalAlignment = 'center';
            app.XLabel.Position = [98 158 28 22];
            app.XLabel.Text = '<X<';

            % Create YLabel
            app.YLabel = uilabel(app.TargetAreaPanel);
            app.YLabel.HorizontalAlignment = 'center';
            app.YLabel.Position = [98 126 28 22];
            app.YLabel.Text = '<Y<';

            % Create ZLabel
            app.ZLabel = uilabel(app.TargetAreaPanel);
            app.ZLabel.HorizontalAlignment = 'center';
            app.ZLabel.Position = [98 93 27 22];
            app.ZLabel.Text = '<Z<';

            % Create GetTargetAreaButton
            app.GetTargetAreaButton = uibutton(app.TargetAreaPanel, 'push');
            app.GetTargetAreaButton.ButtonPushedFcn = createCallbackFcn(app, @GetTargetAreaButtonPushed, true);
            app.GetTargetAreaButton.Position = [48 50 132 22];
            app.GetTargetAreaButton.Text = 'Get Target Area';

            % Create Image
            app.Image = uiimage(app.TargetAreaPanel);
            app.Image.Position = [236 1 442 235];
            app.Image.ImageSource = 'App Designer Kinect Diagram.png';

            % Create ViewTargetAreaButton
            app.ViewTargetAreaButton = uibutton(app.TargetAreaPanel, 'push');
            app.ViewTargetAreaButton.ButtonPushedFcn = createCallbackFcn(app, @ViewTargetAreaButtonPushed, true);
            app.ViewTargetAreaButton.Position = [48 20 132 22];
            app.ViewTargetAreaButton.Text = 'View Target Area';

            % Create REGIONOFINTERESTPanel
            app.REGIONOFINTERESTPanel = uipanel(app.OBJECTDETECTIONPanel);
            app.REGIONOFINTERESTPanel.Title = 'REGION OF INTEREST';
            app.REGIONOFINTERESTPanel.Position = [18 15 338 257];

            % Create SelectRegionofInterestforContoursPanel
            app.SelectRegionofInterestforContoursPanel = uipanel(app.REGIONOFINTERESTPanel);
            app.SelectRegionofInterestforContoursPanel.TitlePosition = 'centertop';
            app.SelectRegionofInterestforContoursPanel.Title = 'Select Region of Interest for Contours';
            app.SelectRegionofInterestforContoursPanel.Position = [0 0 338 62];

            % Create Label
            app.Label = uilabel(app.SelectRegionofInterestforContoursPanel);
            app.Label.HorizontalAlignment = 'right';
            app.Label.Position = [70 10 25 22];
            app.Label.Text = '';

            % Create DropDownSelectROIForContour
            app.DropDownSelectROIForContour = uidropdown(app.SelectRegionofInterestforContoursPanel);
            app.DropDownSelectROIForContour.Items = {'Full Object', 'ROI'};
            app.DropDownSelectROIForContour.Position = [70 10 197 22];
            app.DropDownSelectROIForContour.Value = 'Full Object';

            % Create SelectFullObjectButton
            app.SelectFullObjectButton = uibutton(app.REGIONOFINTERESTPanel, 'push');
            app.SelectFullObjectButton.ButtonPushedFcn = createCallbackFcn(app, @SelectFullObjectButtonPushed, true);
            app.SelectFullObjectButton.Position = [18 162 303 61];
            app.SelectFullObjectButton.Text = 'Select Full Object';

            % Create SelectROIButton
            app.SelectROIButton = uibutton(app.REGIONOFINTERESTPanel, 'push');
            app.SelectROIButton.ButtonPushedFcn = createCallbackFcn(app, @SelectROIButtonPushed, true);
            app.SelectROIButton.Position = [18 85 303 61];
            app.SelectROIButton.Text = 'Select ROI';

            % Create CONTOURSPanel
            app.CONTOURSPanel = uipanel(app.OBJECTDETECTIONPanel);
            app.CONTOURSPanel.Title = 'CONTOURS';
            app.CONTOURSPanel.Position = [378 15 337 257];

            % Create UIAxesObjectContours
            app.UIAxesObjectContours = uiaxes(app.CONTOURSPanel);
            app.UIAxesObjectContours.Box = 'on';
            app.UIAxesObjectContours.Position = [18 47 274 160];

            % Create ShowContoursButton
            app.ShowContoursButton = uibutton(app.CONTOURSPanel, 'push');
            app.ShowContoursButton.ButtonPushedFcn = createCallbackFcn(app, @ShowContoursButtonPushed, true);
            app.ShowContoursButton.Position = [110 23 100 22];
            app.ShowContoursButton.Text = 'Show Contours';

            % 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 = APLICACAO_IMG_FINAL_FINAL_FINAL_REUNIAORMVS

            % Create UIFigure and components
            createComponents(app)

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

            % Execute the startup function
            runStartupFcn(app, @startupFcn)

            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