Aplicação de exemplo - edgebr/huawei-smart-cities-wiki GitHub Wiki
A vertente front-end dessa aplicação consiste em um dashboard que apresenta dados por meio de contadores, gráficos e listas, juntamente com a exibição de imagens e informações relevantes à respeito delas. O projeto pode ser acessado por meio do link: Front-end.
O front-end para essa aplicação foi feito utilizando as seguintes tecnologias:
-
Vue.js
- Vue.js é um framework baseado em JavaScript que tem como principais características: curva de aprendizado leve, boa documentação e boa capacidade de integração
-
Vuetify
- É um framework semântico voltado para User Interface(UI) com foco em angariar recursos para facilitar e otimizar o desenvolvimento de componentes gráficos por meio do sistema de design Material Design
-
ApexCharts
- É uma biblioteca voltada para construção de gráficos interativos para soluções Web.
-
Axios
- Axios é uma biblioteca baseada em comunicação através do protocolo HTTP por meio de promises. Funciona tanto no back-end quanto no front-end utilizando a mesma base de código, utilizando módulo HTTP com Node.js, enquanto no front-end utiliza XMLHttpRequests, ou seja, é isomórfico.
Figura 1: Tela de início
A página inicial consiste em 6 cards, um menu lateral e um botão. Os cards são distribuídos entre categorias: contagem, lista e gráfico. Sendo assim, a aplicação contém 3 cards de contagem, 2 cards de gráficos e 1 card de lista.
Detalhando cada um dos componentes desta tela:
-
- Tem como objetivo ser o controle central entre as telas principais da aplicação, portanto, contém 2 botões, um que direciona o usuário para a tela principal e outro que direciona para a tela de análise das câmeras.
-
- É o componente responsável por mudar todo o idioma da aplicação, dando ao usuário a opção de escolher entre português e inglês
-
- São exibidos os dados referentes à quantidade de pessoas com objetos que foram detectados como hostis pelo modelo
-
- São exibidos os dados referentes à quantidade de pessoas com armas de fogo detectadas pelo modelo
-
- São exibidos os dados referentes à quantidade de pessoas com capacete detectadas pelo modelo
-
- Este componente retorna uma lista contendo as leituras de pessoas, armas e capacetes no formato mensal, ao longo dos 12 meses do ano.
-
- O componente em questão compõe um gráfico de linha contendo uma série de dados referente ao número de pessoas detectadas por hora
-
- Este componente compõe um gráfico de linha contendo três séries de dados referentes à temperatura(em Celsius), pressão(em mmHg) e umidade(em g/m^3) do ambiente em que a câmera está localizada
Figura 2: Tela de exibição das câmeras
Essa página é responsável por exibir as câmeras cadastradas pelo usuário, para isso há um carousel com as câmeras cadastradas, um controlador para mover entre as câmeras, um scroll lateral para exibir por completo a lista de câmeras cadastradas e um botão que redireciona o usuário para a página de detalhes da câmera indicada no controlador.
Detalhando cada um dos componentes desta tela:
-
- O carousel de câmeras apresenta 3 estados diferentes que são baseados na presença de câmeras no banco de dados e de imagens salvas nas câmeras
- Quando há câmeras cadastradas e essa câmera contém imagens, a aplicação apresenta a última imagem presente na câmera em destaque. Da forma que é mostrado na imagem principal desta seção.
- O carousel de câmeras apresenta 3 estados diferentes que são baseados na presença de câmeras no banco de dados e de imagens salvas nas câmeras
-
Sem câmeras cadastradas
- Quando não há câmeras cadastradas, a aplicação apresenta uma mensagem indicando que não existe nenhuma câmera cadastrada pelo usuário.
Figura 3: Carousel de exibição das câmeras quando não há câmeras registradas
-
Sem imagens cadastradas na câmera
- Quando há câmera cadastrada, mas essa câmera não tem imagens adicionadas, a aplicação apresenta uma mensagem indicando que não existe nenhuma imagem salva pela câmera.
Figura 4: Carousel de exibição das câmeras quando não há imagens cadastradas numa câmera
-
- O intuito deste botão é controlar a movimentação entre as câmeras cadastradas para que o usuário consiga ter controle sobre qual câmera ele quer acessar os detalhes.
-
- A funcionalidade deste slider é dispor em uma lista com scroll todas as câmeras cadastradas e tem o objetivo de mostrar o acervo de câmeras para o usuário sem que ele tenha que verificar cada uma delas.
-
- Dá acesso à página de detalhes de uma câmera, ou seja, redireciona o usuário para uma tela que contém dados referentes às imagens, ao mapa de calor e às contagens da câmera.
Figura 5: Tela de detalhes das câmeras
Esta tela tem como foco exibir as imagens capturadas pela câmera, além da leitura de calor e contagem de entidades(Aglomerações, pessoas, armas de fogo e capacetes) de cada imagem. Para conseguir exibir isso, a tela contém 3 componentes distribuídos entre carousel, imagem e card com dados.
-
- Este componente apresenta todas as imagens capturadas pela câmera e as dispõe com a ajuda de um controlador localizado logo abaixo dele. Cada vez que esse controlador é utilizado para avançar ou recuar as imagens, a leitura de calor e os dados são atualizados para respeitarem a imagem que estiver em destaque. Além disso, a imagem em destaque traz caixas e labels para destacar entidade detectada pelo modelo com suas respectivas cores e valor de confiança. Este componente tem dois estados, quando há imagens e quando não há.
-
Carousel de imagens com imagens cadastradas
- Este estado é o que está acontecendo na imagem em destaque nesta seção.
-
Carousel de imagens sem imagens cadastradas
- Quando não existem imagens cadastradas, consequentemente, não existem detecções cadastradas, um componente apresenta uma mensagem notificando o ocorrido.
Figura 6: Carousel de imagens quando não há imagens cadastradas
-
- A leitura de calor está relacionada à análise de aglomeração de cada imagem. Como qualquer mapa de calor, cores mais próximas ao vermelho indicam maior aglomeração de pessoas, enquanto cores mais próximas do espectro azul indicam baixa aglomeração. Este componente também tem dois estados, quando há mapa de calor e quando não há
-
Exibição de imagem com leitura de calor cadastrada
- Este estado é o que está acontecendo na imagem em destaque nesta seção
-
Exibição de imagem sem leitura de calor cadastrada
- Quando não há nenhuma leitura de calor associada à imagem em destaque pelo carousel, uma mensagem é exibida indicando que não foi encontrada nenhuma leitura para aquela imagem
Figura 7: Componente de exibição de mapa de calor quando não há nenhum mapa de calor registrado
-
- Este card apresenta diferentes informações a respeito da imagem em destaque no carousel
-
URL da imagem em destaque:
- Basicamente, exibe uma URL que direciona para a imagem em uma aba separada no navegador
-
Contagem de pessoas na imagem:
- Exibe uma estimativa da quantidade de aglomerações presentes na imagem, havendo uma métrica para verificar o que é uma aglomeração que pode ser checada pelo mapa de calor
-
Número de pessoas detectadas:
- Exibe o valor referente à quantidade de pessoas detectadas na imagem
-
Número de armas detectadas:
- Exibe o valor referente à quantidade de armas detectadas na imagem
-
Número de capacetes detectados:
- Exibe o valor referente à quantidade de capacetes detectados na imagem
O back-end dessa aplicação busca receber os dados dos modelos de detecção de objetos, armazená-los em um banco de dados e enviá-los ao front-end em um formato adequado.
Para criação do back-end da aplicação de exemplo buscou-se por ferramentas de código aberto que facilitem o desenvolvimento, em uma linguagem altamente difundida. Por isso, optou-se pela utilização dos frameworks web, em python, Django e o Django REST.
O banco de dados escolhidos para essa aplicação foi o PostgreSQL que é um banco de dados objeto relacional, de código aberto, que possui fácil integração com o Django.
Um modelo é a fonte única e definitiva de informações sobre os dados da aplicação. Ele contém os campos e comportamentos essenciais dos dados que serao armazenados. Assim, nessa aplicação foram desenvolvidos cinco modelos, sendo eles: Camera, Frame, Detection, Agglomeration e Measurement.
Esse modelo é a representação das cameras da nossa aplicação. Possui os seguintes atributos:
- Data de criação;
- Data de atualização;
- Nome;
- URL.
Esse modelo é a representação dos frames de uma camera, assim, cada objeto Frame está ligado a um objeto Camera. Possui o seguintes atributos:
- Data de criação;
- Data de atualização;
- Dados da imagem (binário);
- Largura da imagem;
- Altura da imagem;
- Camera relacionada.
Esse modelo é a representação das detecções presentes em cada frame, assim, cada objeto Detection está ligado a um objeto Frame. Possui os seguintes atributos:
- Data de criação;
- Data de atualização;
- Tipo de detection (pessoa, arma ou capacete);
- Coordenada x da caixa delimitadora;
- Coordenada y da caixa delimitadora;
- Largura da caixa delimitadora;
- Altura da caixa delimitadora;
- Confiança da detecção;
- Frame relacionado.
Esse modelo é a representação da aglomeração presente em cada frame, assim, cada objeto Agglomeration está ligado a um objeto Frame. Possui os seguintes atributos:
- Data de criação
- Data de atualização
- Contagem de pessoas;
- Dados do mapa de calor (binário);
- Largura do mapa de calor;
- Altura do mapa de calor;
- Frame relacionado.
Esse modelo é a representação das medições feitas pelos sensores do hardware. Possui os seguintes atributos:
- Data de criação;
- Tipo da medição (temperatura, pressão ou umidade);
- Valor da medição;
- Unidade da medição;
Uma view, em Django, é uma função em python que recebe um pedido web e retorna uma resposta web. Assim, são os pontos de acesso do modelo de detecção para o back-end e do back-end para a interface do usuário. Para isso, foram desenvolvidas sete views, foram elas: DashboardView, CameraFramesView, CameraView, SubmissionView, CameraDetailsView, DetectionsHeatmapView e MeasurementSubmissionView.
View que recebe uma requisição GET e retorna os dados necessários para a página inicial do aplicativo.
- /system/api/dashboard/
- num_of_persons (inteiro)
- Número de detecção do tipo "pessoa" que ocorreram no dia.
- num_of_guns (inteiro)
- Número de detecção do tipo "arma" que ocorreram no dia.
- num_of_helmets (inteiro)
- Número de detecção do tipo "capacete" que ocorreram no dia.
- num_of_persons_by_hour (lista)
- Lista contendo o número de detecção do tipo "pessoa" por hora do dia.
- data_history (dicionário)
- Dicionário contendo o número de de detecção do tipo "pessoa", "arma" e "capacete" por mês.
- temperature_each_hour (lista)
- Lista contendo a média da temperatura por hora do dia.
- pression_each_hour (lista)
- Lista contendo a média da pressão por hora do dia.
- humidity_each_hour (lista)
- Lista contendo a média da umidade por hora do dia.
View que ao receber uma requisição GET retorna o ID e URL das câmeras cadastradas no aplicativo, e ao receber uma requisição POST cadastra uma nova câmera.
- /system/api/cameras/
- nome (string)
- Nome da camera a ser cadastrada.
- url (string)
- URL da camera a ser cadastrada.
- nome (string)
- Nome das cameras cadastradas.
- url (string)
- URL das cameras cadastradas.
View que recebe uma requisição GET e retorna o último frame de cada câmeracadastrada.
- /system/api/cameras/frames/
- cameras (dicionário)
- Dicionário contendo os nomes das cameras (name), os respectivos dados dos frames em forma de string em base64 (src), e os IDs dos frames em forma de inteiros (frame_id).
View que recebe uma requisição POST de um frame e suas detecções (opcionais), executa o modelo aglomeração para o frame enviado e salva tudo no banco de dados.
- /system/api/cameras/
- camera_name (inteiro)
- Nome da camera da qual o frame é originado.
- img_data (string)
- Dados da imagem codificados em base64.
- img_width (inteiro)
- Largura da imagem.
- img_height (inteiro)
- Altura da imagem.
- detections (lista) [opcional]
- Lista com dicinários contendo os dados de cada detecção do frame.
- label (inteiro): tipo de detecção (1- pessoa, 2- arma ou 3- capacete)
- x (inteiro): coordenada x da origem da bounding box da detecção.
- y (inteiro): coordenada y da origem da bounding box da detecção.
- w (inteiro): largura da bounding box da detecção.
- h (inteiro): altura da bounding box da detecção.
- confidence (float): confiança da detecção.
View que recebe uma requisição GET com o ID da camera e a quantidade de frames requeridos (10 por padrão), e retorna o nome, a URL e os últimos frames dela.
- /system/api/cameras/view/int:camID/int:frAmount/
- camera_name (string)
- Nome da camera.
- camera_url (string)
- URL da camera.
- frames (lista) [opcional]
- Lista com dicinários contendo os dados de cada frame.
- id (inteiro): número de identificação do frame.
- src (string): dados da imagem codificados em base64.
View que recebe uma requisição GET que recebe o ID do frame e retorna a imagem do frame com as detecções desenhadas, os dados de detecção e os de aglomeração.
- /system/api/frames/int:frameID/detections/
- src (string)
- Dados da imagem do frame codificados em base64.
- heatmap (string)
- Dados da imagem do mapa de calor codificados em base64.
- num_of_persons (inteiro)
- Número de detecção de pessoas.
- num_of_guns (inteiro)
- Número de detecção de armas.
- num_of_helmets (inteiro)
- Número de detecção de capacetes.
- agg_count (inteiro)
- Contagem de pessoas feita pela modelo de aglomeração.
View que recebe uma requisição POST da medição de um sensor.
- /system/api/sensors/submission/
- type (inteiro)
- Tipo de medida que o sensor capturou. (0- Temperatura , 1- Pressão ou 2- Umidade)
- value (inteiro)
- Valor medido pelo sensor.
- unit (inteiro)
- Unidade de medida do valor capturado pelo sensor.