Escrito por

Software Architect at Visum
Artigo Yuri Marx · Fev. 5, 2022 8m read

Detecção de Objetos com Embedded Python e IRIS

A partir do IRIS 2021.2 é possível escrever métodos de classe usando a linguagem Python. Usei esse novo recurso para detectar pessoas e objetos em imagens, usando o ImageAI (https://github.com/OlafenwaMoses/ImageAI). O criador do ImageAI o define como: "Uma biblioteca python de código aberto criada para permitir aos desenvolvedores criarem aplicativos e sistemas com recursos autônomos de Deep Learning e Visão Computacional usando poucas linhas de código". Neste artigo, você aprenderá como aplicar a ImageAI para detectar objetos e pessoas dentro de imagens.

Passos para analisar imagens usando o ImageAI

  1. Vá em https://openexchange.intersystems.com/package/AI-Image-Object-Detector e clique Download para ir ao Projeto Git
  2. Clone/git pull no repositório para qualquer pasta local
$ git clone https://github.com/yurimarx/image-analyzer.git
  1. Abra o terminal e vá no diretório onde o projeto foi criado e execute:
$ docker-compose build
  1. Execute o IRIS container:
$ docker-compose up -d 
  1. Vá no seu Postman (ou outros clientes REST) e configure a requisição de acordo com a imagem:

Request Image Analysis input

  1. Clique em enviar e obtenha uma resposta como esta:

Request Image Analysis output

Os bastidores - o código-fonte

O Dockerfile

Esse é um passo importante. Para usar as bibliotecas do python você precisa instalar isto antes, preste atenção do diretório correto do Python que o IRIS utiliza (/usr/irissys/mgr/python):

 

Dockerfile

FROM intersystemsdc/iris-community

 

USER root

 

ENV DEBIAN_FRONTEND noninteractive

 

# instala as bibliotecas requeridas do ImageAI/OpenCV para processar imagens e vídeos
RUN apt-get -y update \
    && apt-get -y install apt-utils \
    && apt-get install -y build-essential unzip pkg-config \
        zlib1g-dev libncurses5-dev libgdbm-dev libnss3-dev \
        libssl-dev libreadline-dev libffi-dev wget \
    && apt-get install -y ffmpeg libsm6 libxext6  

 

# use o pip3 (o zpm do python) para instalar o imageai e as dependências do imageai
RUN pip3 install --upgrade pip setuptools wheel
RUN pip3 install --target /usr/irissys/mgr/python tensorflow==2.4.0
RUN pip3 install --target /usr/irissys/mgr/python keras==2.4.3 numpy==1.19.3 pillow==8.1.1 scipy==1.4.1 h5py==2.10.0 matplotlib==3.3.2 opencv-python keras-resnet==0.2.0
RUN pip3 install --target /usr/irissys/mgr/python imageai --upgrade

 

USER root  
WORKDIR /opt/irisbuild
RUN chown ${ISC_PACKAGE_MGRUSER}:${ISC_PACKAGE_IRISGROUP} /opt/irisbuild
USER ${ISC_PACKAGE_MGRUSER}

 

WORKDIR /opt/irisbuild
COPY  python python
COPY input input
COPY output output
COPY models models
COPY  src src
COPY module.xml module.xml
COPY iris.script iris.script

 

# realiza o download do modelo treinado para detectar pessoas e objetos na imagem

 

USER root
RUN chmod -R 777 input
RUN chmod -R 777 output
RUN chmod -R 777 models

 

USER ${ISC_PACKAGE_MGRUSER}

 

RUN iris start IRIS \
    && iris session IRIS < iris.script \
    && iris stop IRIS quietly
  • pip3 é uma ferramenta do python para instalar novas bibliotecas, como o imageai, opencv, tensorflow e outras.
  • o parâmetro target é utilizado para instalar as bibliotecas do python onde o IRIS precisa, na pasta /usr/irissys/mgr/python.
  • O ImageAI utiliza as seguintes bibliotecas:
    • TensorFlow: "é uma biblioteca de código aberto para computação numérica e aprendizado de máquina em larga escala. O TensorFlow reúne uma série de modelos e algoritmos de aprendizado de máquina e aprendizado profundo (também conhecido como rede neural) e os torna úteis por meio de uma metáfora comum. Ele usa Python para fornecer uma API de front-end conveniente para criar aplicativos com a estrutura correta, enquanto executa esses aplicativos em C++ em alto desempenho" (fonte: https://www.infoworld.com/article/3278008/what-is-tensorflow-the -machine-learning-library-explained.html)
    • Keras: "Keras é uma API de aprendizado profundo escrita em Python, executada na plataforma de aprendizado de máquina TensorFlow. Ela foi desenvolvida com foco em permitir a experimentação rápida. Ser capaz de ir da ideia ao resultado o mais rápido possível é a chave para fazer boa pesquisa." (fonte: https://keras.io/about/)
    • OpenCV: "(Open Source Computer Vision Library) é uma biblioteca de software de visão computacional e aprendizado de máquina de código aberto. OpenCV foi construído para fornecer uma infraestrutura comum para aplicativos de visão computacional e acelerar o uso de percepção de máquina nos produtos comerciais" (fonte: https://opencv.org/about/).
  • O ImageAI é um framework que combina oTensorFlow, Keras e OpenCV para te permitir treinar e usar modelos de mercado de deep learning facilmente, visando:
    • Predição de imagens;
    • Detecção de Objetos;
    • Detecção de objetos em vídeo e o acompanhamento em tempo real do vídeo;
    • Análise de Vídeos;
    • Treinamento de modelos customizados (como o treinamento de um modelo para risco de queda em hospital, por exemplo).
  • O ImageAI trabalha com 3 modelos principais de Computação Visual para detecção de objetos:
    • RetinaNet (Tamanho = 145 mb, longo tempo de resposta, mas ótima acurácia)
    • YOLOv3 (Tamanho = 237 mb, tempo de resposta e acurácia moderadas)
    • TinyYOLOv3 (Tamanho = 34 mb, ótimo tempo de resposta e acurácia moderada)
  • A pasta input armazena as imagens a serem analisadas;
  • A pasta output armazena os resultados (imagens com as marcações);
  • A pasta models armazena os modelos treinados para utilização no imageai.
  • Este exemplo usa o modelo RetinaNet (restnet50)

Implementação do Embedded Python no IRIS

A implementação do código fonte é simples, e em poucas linhas fazemos a detecção de objetos (razão do uso do ImageAI). Se o tensorflow fosse usado diretamente com OpenCV e Keras, muito mais linhas de código teriam sido escritas. Veja o código comentado:

 

Implementação do ImageAI

/// Detecção de pessoas e objetos em imagens e videos
Class dc.imageanalyzer.Detector
{

 

/// Detecta dentro da imagem passada por parametro
ClassMethod GetImageFeatures(Image) [ Language = python ]
{
    # importa as libs do imageai e json
    from imageai.Detection import ObjectDetection
    import json
   
    # instancia o imageai
    detector = ObjectDetection()

 

    # seta o retinanet como modelo de deteccao
    model_path = "/opt/irisbuild/models/resnet50_coco_best_v2.1.0.h5"
    # seta a pasta para receber a imagem a ser processada
    input_path = "/opt/irisbuild/input/" + Image
    # seta pasta que armazena os resultados (imagem processada com as tags)
    output_path = "/opt/irisbuild/output/" + Image

 

    # instancia o modelo retina
    detector.setModelTypeAsRetinaNet()
   
    # seta o modelo de detecção retina
    detector.setModelPath(model_path)
    # carrega o modelo
    detector.loadModel()
    # detecta os objetos e pessoas
    detection = detector.detectObjectsFromImage(input_image=input_path, output_image_path=output_path)
    # retorna o json com os resultados
    # você pode ver a imagem processada no diretorio output
    return json.dumps(detection)
}

 

/// Get JSON
ClassMethod GetJSON(pythonObj) [ Language = python ]
{
    import json
    return json.dumps(pythonObj)
}

 

/// Description
ClassMethod GetImageAI(Image) As %Status
{
    Set sc = $$$OK
    Write ..GetImageFeatures(Image)
    Return sc
}

 

}

A API do IRIS para export a detecção de Objetos como um Microsserviço do IRIS

É muito fácil chamar o classmethod python, é semelhante chamar qualquer classmethod objectscript, veja:

 

Microsserviço IRIS para detectar objetos dentro de imagens

Class dc.imageanalyzer.ImageAnalyzerRESTApp Extends %CSP.REST
{

 

Parameter CHARSET = "utf-8";

 

Parameter CONVERTINPUTSTREAM = 1;

 

Parameter CONTENTTYPE = "application/json";

 

Parameter Version = "1.0.0";

 

Parameter HandleCorsRequest = 1;

 

XData UrlMap [ XMLNamespace = "http://www.intersystems.com/urlmap" ]
{
<Routes>

 

<!-- Detecta objetos dentro da imagem -->
<Route Url="/analyzeImage" Method="POST" Call="AnalyzeImage" />

 

</Routes>
}

 

// Detecta objetos dentro da imagem

 

ClassMethod AnalyzeImage() As %Status
{
    Set tSC = $$$OK
   
    try {
        // obtem o arquivo em requisicao multipart
        Set source = %request.GetMimeData("file")
       
        // salva o arquivo para a pasta input, para ser processado pelo imageai
        Set destination=##class(%Stream.FileBinary).%New()
        Set destination.Filename="/opt/irisbuild/input/"_source.FileName
        set tSC=destination.CopyFrom(source) //o reader abre o arquivo
        set result=destination.%Save()
       
        Set %response.ContentType = ..#CONTENTTYPEJSON
        Set %response.Headers("Access-Control-Allow-Origin")="*"

 

        //chama o classmethod do embedded python para detectar objetos e escrever os resultados como um objeto json
        Write ##class(dc.imageanalyzer.Detector).GetImageAI(source.FileName)

 

        Set tSC=$$$OK
   
    //retorna erro se houver
    } catch e {
        Set tSC=e.AsStatus()
        Set pOutput = tSC
    }

 

    Quit tSC
}


 

}

Você pode fazer muitas coisas com Embedded Python e ImageAI. Saiba mais sobre ImageAI em: https://github.com/OlafenwaMoses/ImageAI.

Este aplicativo de exemplo usando imageai participará do concurso Python, se você gostou, vote nele. Obrigado!