Processamento de Dados Não Estruturados da Nuvem à Borda
Dados não estruturados agora representam cerca de 80% dos dados que manipulamos, abrangendo desde texto e imagens até vídeos, áudio e formatos mais complexos. À medida que seu volume cresce, cresce também a necessidade de melhores formas de processá-los e analisá-los.
Em um webinar recente, Tim Spann, Principal Developer Advocate na Zilliz, compartilhou suas percepções sobre o gerenciamento de dados não estruturados, especialmente de ambientes em nuvem a dispositivos de borda. Ele também destacou como bancos de dados vetoriais, como o Milvus, são essenciais para dar sentido a esses dados.
Neste post, vamos recapitular os principais pontos de Tim, discutindo os desafios no tratamento de dados não estruturados e como os bancos de dados vetoriais lideram o caminho. Também veremos como dispositivos de borda impulsionados por esses bancos de dados estão promovendo novos avanços em IA. Se você tiver interesse em mais detalhes, recomendamos assistir à reprise completa da palestra de Tim no YouTube.
Entendendo os dados não estruturados
Dados não estruturados referem-se a informações que não têm um formato ou esquema predefinido. Diferentemente dos dados estruturados, que são organizados de forma ordenada em bancos de dados com campos e formatos específicos, os dados não estruturados são brutos e desorganizados. Eles frequentemente incluem:
Texto: Emails, documentos do Word, publicações em redes sociais
Imagens: Fotos, capturas de tela, diagramas
Vídeos: Reuniões gravadas, imagens de vigilância, conteúdo multimídia
Áudio: Gravações de voz, arquivos de música, podcasts
Com o aumento do conteúdo digital, os dados não estruturados cresceram exponencialmente, oferecendo tanto oportunidades quanto desafios para as organizações. Para aproveitar essa riqueza de informações, as empresas podem:
Aprimorar a experiência do cliente analisando interações e feedback dos clientes
Melhorar a eficiência operacional por meio de insights de dados de sensores e logs de sistemas
Impulsionar a inovação aproveitando conteúdo multimídia para o desenvolvimento de produtos
Bancos de dados tradicionais, projetados para lidar com dados estruturados, têm dificuldade com a irregularidade dos dados não estruturados, tornando difícil pesquisar, consultar ou extrair insights significativos. É aqui que os bancos de dados vetoriais se tornam essenciais, oferecendo uma solução para gerenciar e recuperar informações não estruturadas de forma eficiente.
Por que usar um banco de dados vetorial para processamento de dados não estruturados?
Um banco de dados vetorial é um banco de dados especializado projetado para armazenar, indexar e consultar representações vetoriais de dados (também conhecidas como embeddings vetoriais), frequentemente derivadas de dados não estruturados, como texto, imagens e áudio. Esses bancos de dados permitem buscas por similaridade eficientes em um espaço de alta dimensionalidade, tornando-os ideais para busca semântica, processamento de linguagem natural (NLP), sistemas de recomendação, buscas de imagens e geração aumentada por recuperação (RAG).
Bancos de dados vetoriais como Milvus e Zilliz Cloud oferecem uma variedade de funcionalidades além de capacidades de busca de alto desempenho que os tornam cruciais para gerenciar dados não estruturados.
Além da Busca de Alto Desempenho
Embora os bancos de dados vetoriais sejam frequentemente associados a recursos rápidos de busca por similaridade, sua utilidade vai muito além. Eles oferecem outras funções essenciais que garantem o gerenciamento e a utilização eficazes de dados não estruturados:
Operações CRUD: Bancos de dados vetoriais, assim como bancos de dados tradicionais, permitem Criar, Ler, Atualizar e Excluir (CRUD) dados. Isso garante que, apesar de trabalhar com tipos de dados complexos, as operações básicas permaneçam intuitivas e acessíveis.
Atualidade dos Dados: Um dos principais pontos fortes dos bancos de dados vetoriais é garantir que seus dados permaneçam atualizados. Em casos de uso como sistemas de recomendação, manter os dados atuais é essencial para gerar insights precisos.
Persistência: Ao contrário das estruturas de dados em memória, os bancos de dados vetoriais oferecem armazenamento persistente, o que significa que seus dados são armazenados com segurança e permanecem acessíveis mesmo após reinicializações do sistema.
Disponibilidade: Bancos de dados vetoriais mantêm os dados prontamente acessíveis para consultas e recuperação em tempo real. Isso garante que, mesmo à medida que seus dados crescem, você ainda possa realizar buscas rápidas e eficientes, permitindo decisões orientadas por IA sem demora.
Escalabilidade: À medida que os dados aumentam em volume, os bancos de dados vetoriais escalam de forma eficiente para acomodar esse crescimento sem degradação de desempenho. Isso é essencial ao gerenciar bilhões de pontos de dados não estruturados.
Gerenciamento Completo de Dados
Além das funções acima, os bancos de dados vetoriais fornecem ferramentas robustas para gerenciar seus dados não estruturados, incluindo ingestão de dados, indexação e consulta, permitindo a recuperação e análise eficientes até mesmo dos maiores conjuntos de dados. Recursos como backup e migração garantem que seus dados permaneçam seguros e recuperáveis, tornando os bancos de dados vetoriais uma escolha confiável para gerenciar informações críticas.
Facilidade Operacional
Os bancos de dados vetoriais também são projetados para simplificar a implantação e o gerenciamento:
Implantação na Nuvem ou On-Premise: Muitos bancos de dados vetoriais criados especificamente são versáteis e podem ser facilmente implantados em nuvens públicas ou infraestrutura on-premise, garantindo flexibilidade com base nas necessidades da organização.
Observabilidade: Muitos bancos de dados vetoriais oferecem ferramentas de monitoramento para acompanhar a integridade e o desempenho do banco de dados, permitindo que os usuários otimizem seus sistemas de forma proativa.
Multi-tenancy: Bancos de dados vetoriais como o Zilliz Cloud oferecem suporte a múltiplos usuários ou aplicações, garantindo acesso seguro e manipulação isolada de dados para cada tenant. Isso os torna ideais para implantações em larga escala nas quais várias equipes precisam de ambientes de dados isolados.
O Papel do Milvus no Gerenciamento de Dados Não Estruturados
Milvus é um banco de dados vetorial de código aberto projetado para armazenar, indexar e recuperar vetores de alta dimensionalidade em escala de bilhões de forma eficiente, tornando-o ideal para casos de uso envolvendo IA e machine learning, como sistemas de recomendação, reconhecimento de imagens ou geração aumentada por recuperação (RAG).
O Milvus oferece múltiplas opções de implantação para atender a necessidades diversificadas dos clientes.
Milvus de código aberto: De código aberto, autogerenciado, e pode ser hospedado em qualquer máquina com suporte da comunidade. O Milvus também oferece múltiplas opções de implantação para diversas necessidades e ambientes, incluindo Milvus Lite, Milvus Standalone e Milvus Distributed. Consulte a documentação do Milvus para mais detalhes.
Zilliz Cloud: versão totalmente gerenciada do Milvus, reprojetada para a nuvem e disponível nas principais nuvens públicas, como AWS, GCP e Azure.
Zilliz BYOC: Milvus pronto para empresas para VPCs privadas e pode ser implantado em sua nuvem privada virtual.
Fig 1- Ways of deploying Milvus .png
Fig 1: Formas de implantar o Milvus
Principais recursos do Milvus
O Milvus foi projetado para alto desempenho e escalabilidade, oferecendo recursos como:
Figure- Milvus key features .png
Figura: principais recursos do Milvus
Multilocação: o Milvus permite que vários usuários ou aplicações trabalhem no mesmo sistema sem interferir uns nos outros, fornecendo acesso seguro a dados isolados.
Computação acelerada por hardware: otimizado para aproveitar hardware como GPUs, tornando-o mais rápido e eficiente para tarefas intensivas em recursos, como inferência de modelos de IA.
Suporte a linguagens e APIs: o Milvus é altamente versátil, com suporte a Python, Java, Golang, NodeJS, etc., tornando-o acessível a uma ampla variedade de desenvolvedores.
Arquitetura escalável e elástica: o Milvus foi projetado para lidar com necessidades crescentes de dados. Ele escala automaticamente para atender à demanda, garantindo que o desempenho permaneça ideal à medida que os dados crescem.
Suporte a diversos índices: ele oferece suporte a vários tipos de índices, incluindo HNSW, PQ, Binary e DiskANN, permitindo flexibilidade na forma como os dados são armazenados e pesquisados.
Consistência ajustável: o Milvus permite ajustar os níveis de consistência dos seus dados, permitindo equilibrar desempenho e precisão dos dados com base nas necessidades da aplicação.
Para obter informações mais detalhadas, consulte a documentação do Milvus.
Tecnologias que impulsionam o Milvus para vários casos de uso
O Milvus é impulsionado por um conjunto de tecnologias que atende a diferentes tipos de aplicações, garantindo desempenho, flexibilidade e escalabilidade em vários ambientes:
Figure- Milvus technologies for various use cases .png
Figure: Tecnologias do Milvus para vários casos de uso
Tipos de computação: o Milvus é otimizado para diferentes ambientes de hardware, incluindo AVX512 (um conjunto de instruções de CPU para computação de alta velocidade), Neon para SIMD (Single Instruction, Multiple Data) e aceleração por GPU. Isso garante que o Milvus possa usar hardware de alto desempenho para oferecer processamento rápido e escalabilidade econômica.
Tipos de pesquisa: o Milvus oferece suporte a uma ampla variedade de métodos de pesquisa, como top-K ANN (Approximate Nearest Neighbors) para encontrar os pontos de dados mais semelhantes, ANN por intervalo, pesquisas esparsas e densas e pesquisas filtradas. Esses recursos nos permitem adaptar a funcionalidade de pesquisa às necessidades específicas de nossas aplicações, seja para identificar imagens, vídeos ou textos semelhantes.
Multilocação: o Milvus oferece suporte ao gerenciamento de coleções e partições, permitindo a multilocação. Esse recurso permite que diferentes equipes ou aplicações compartilhem o mesmo banco de dados sem interferir nos dados umas das outras, garantindo o tratamento seguro e isolado dos dados.
Tipos de Índice: O Milvus oferece uma ampla variedade de 15 tipos de indexação, incluindo HNSW (Hierarchical Navigable Small Worlds) para buscas de alta velocidade, PQ (Product Quantization) para armazenamento compacto e DiskANN para lidar com conjuntos de dados massivos. Você pode escolher o tipo de indexação que melhor equilibra desempenho, precisão e custo, dependendo do seu caso de uso.
Essas tecnologias tornam o Milvus uma boa escolha para uma ampla variedade de aplicações, desde implantações em nuvem em larga escala até dispositivos de borda com recursos limitados.
A Mudança para a Computação de Borda
À medida que a demanda por insights em tempo real a partir de dados não estruturados cresce, muitas organizações percebem que confiar apenas em ambientes de nuvem não é suficiente. Isso levou a uma mudança em direção à computação de borda, em que o processamento acontece mais próximo de onde os dados são gerados, oferecendo vantagens distintas para aplicações de IA sensíveis ao tempo.
Computação de borda refere-se à prática de processar dados mais perto de onde eles são gerados, frequentemente em dispositivos de borda como sensores, câmeras e dispositivos IoT. Em vez de enviar dados brutos de volta para data centers centralizados para processamento, a computação de borda permite cálculos nos próprios dispositivos ou em locais próximos.
Com a crescente disponibilidade de dispositivos de borda poderosos, tornou-se possível implantar modelos de machine learning e IA diretamente nesses dispositivos. Essa abordagem permite a tomada de decisões em tempo real em aplicações como veículos autônomos, cidades inteligentes e automação industrial.
Por que Processar Dados na Borda?
Processar dados não estruturados na borda tem várias vantagens:
Baixa Latência: Como os dados são processados perto de sua origem, há um atraso mínimo na obtenção dos resultados.
Largura de Banda Reduzida: Ao processar dados localmente, você reduz a necessidade de transmitir grandes volumes de dados brutos de volta para a nuvem.
Privacidade e Segurança: Dados sensíveis podem permanecer no dispositivo de borda, minimizando o risco de exposição durante a transmissão.
IA de Borda e Bancos de Dados Vetoriais
Embora a computação de borda aproxime o processamento de dados da fonte em dispositivos como sensores, câmeras e pequenos dispositivos como o Raspberry Pi, é o banco de dados vetorial que realmente capacita esses dispositivos a lidar com o crescente volume de dados não estruturados em tempo real.
Por exemplo, em um ambiente industrial, dispositivos de borda monitoram o desempenho de máquinas e detectam possíveis problemas usando dados de sensores. Um banco de dados vetorial como o Milvus capacita o dispositivo de borda a comparar rapidamente dados recebidos com padrões históricos, identificando anomalias que indicam necessidades de manutenção. Sem o banco de dados vetorial, o dispositivo de borda precisaria enviar todos os dados brutos para um servidor em nuvem para processamento (introduzindo atrasos e custos mais altos) ou correria o risco de perder insights críticos.
Milvus Lite: Capacitando Dispositivos de Borda com Recursos de IA
Milvus Lite é a versão leve do Milvus, projetada especificamente para ambientes com recursos limitados, como dispositivos de borda. Ela oferece todos os recursos essenciais de um banco de dados vetorial, mas é otimizada para implantação em hardware menor e menos potente. Isso a torna uma solução ideal para capacitar dispositivos de borda a lidar com tarefas complexas de IA, mesmo em ambientes com recursos limitados.
Com o Milvus Lite em execução em um dispositivo de borda, o dispositivo é transformado em um processador de dados com tecnologia de IA. Essa combinação permite que o dispositivo de borda realize reconhecimento de imagens local, buscas por similaridade de vídeo ou até mesmo processamento de linguagem natural. Em um ambiente de varejo, por exemplo, um sistema de checkout inteligente com Milvus Lite poderia reconhecer produtos instantaneamente e compará-los com um banco de dados vetorial armazenado de itens, acelerando as transações sem a necessidade de sistemas baseados em nuvem.
Vamos ver um exemplo prático em que o Milvus impulsiona um dispositivo de borda em execução em um Raspberry Pi.
Criando um Sistema de Estimativa de Pose em Tempo Real com Raspberry Pi e Milvus
Raspberry Pi é uma série de computadores pequenos, acessíveis e de placa única desenvolvidos pela Raspberry Pi Foundation. Neste exemplo, usaremos o Raspberry Pi como um dispositivo de borda e o Milvus Lite para lidar com dados não estruturados.
Este sistema de estimativa de pose capturará fluxos de vídeo, os processará para estimar poses humanas e armazenará os vetores de características extraídos no Milvus para recuperação eficiente por similaridade. Além disso, integraremos o Slack para notificações, alertando-nos quando poses específicas forem detectadas.
Você pode conferir o código-fonte deste exemplo no notebook do Tim no GitHub.
Pré-requisitos
Raspberry Pi (com GStreamer e Python instalados)
Configuração do Milvus (localmente ou em um servidor remoto)
Conta do Slack para notificações
Importando as Bibliotecas Necessárias e Configuração Inicial
Comece importando as bibliotecas necessárias e definindo algumas configurações iniciais:
import gi
gi.require_version('Gst', '1.0')
from gi.repository import Gst, GLib
import os
import argparse
import multiprocessing
import numpy as np
import setproctitle
import cv2
import time
from datetime import datetime
import uuid
import glob
import torch
from torchvision import transforms
from PIL import Image
import timm
from sklearn.preprocessing import normalize
from timm.data import resolve_data_config
from timm.data.transforms_factory import create_transform
from slack_sdk import WebClient
from slack_sdk.errors import SlackApiError
from pymilvus import connections
from pymilvus import utility
from pymilvus import FieldSchema, CollectionSchema, DataType, Collection
from pymilvus import MilvusClient
from pymilvus import MilvusClient
import hailo
from hailo_rpi_common import (
get_default_parser,
QUEUE,
get_caps_from_pad,
get_numpy_from_buffer,
GStreamerApp,
app_callback_class,
)
DIMENSION = 512
MILVUS_URL = "https://in05-7bd87b945683c8d.serverless.gcp-us-west1.cloud.zilliz.com"
COLLECTION_NAME = "rpipose"
TOKEN = os.environ["ZILLIZ_TOKEN"]
PATH = "/opt/demo/images"
time_list = [ 0, 5, 10, 20, 30, 40, 50, 59 ]
O código acima importa várias bibliotecas para processamento de vídeo (GStreamer), processamento de imagens (OpenCV), deep learning (PyTorch, timm), operações de banco de dados (pymilvus) e comunicação (Slack SDK). Ele também importa a biblioteca Hailo para trabalhar com o acelerador de IA, projetado para permitir aplicações de deep learning em dispositivos de borda. Configuramos variáveis globais para a configuração do banco de dados Milvus e definimos uma lista de horários para ações periódicas. MILVUSURL E TOKEN nos autenticarão na nuvem Zilliz.
Configuração do Banco de Dados Milvus
Em seguida, configuramos nossa conexão com o banco de dados vetorial Milvus. Usaremos o Milvus para armazenar as características extraídas do modelo de estimativa de pose.
# Connect to Milvus
# Milvus Lite
# milvus_client = MilvusClient(uri="pipose.db")
# Cloud Server
milvus_client = MilvusClient( uri=MILVUS_URL, token=TOKEN )
# Create Milvus collection which includes the id, filepath of the image, and image embedding
fields = [
FieldSchema(name='id', dtype=DataType.INT64, is_primary=True, auto_id=True),
FieldSchema(name='label', dtype=DataType.VARCHAR, max_length=200),
FieldSchema(name='lefteye', dtype=DataType.VARCHAR, max_length=200),
FieldSchema(name='righteye', dtype=DataType.VARCHAR, max_length=200),
FieldSchema(name='confidence', dtype=DataType.FLOAT),
FieldSchema(name='vector', dtype=DataType.FLOAT_VECTOR, dim=DIMENSION)
]
schema = CollectionSchema(fields=fields)
milvus_client.create_collection(COLLECTION_NAME, DIMENSION, schema=schema, metric_type="COSINE", auto_id=True)
index_params = milvus_client.prepare_index_params()
index_params.add_index(field_name = "vector", metric_type="COSINE")
milvus_client.create_index(COLLECTION_NAME, index_params)
Aqui, estamos configurando nosso banco de dados Milvus. Criamos uma conexão de cliente, definimos o esquema para nossa coleção (incluindo campos para ID, rótulo, posições dos olhos, confiança e o vetor de características), criamos a coleção e configuramos um índice para buscas de similaridade eficientes.
Configuração do Slack para Notificações
Em seguida, configure uma conexão com o Slack para enviar notificações:
slack_token = os.environ["SLACK_BOT_TOKEN"]
client = WebClient(token=slack_token)
Essa configuração nos permitirá enviar mensagens e arquivos para o Slack usando um token de bot armazenado como uma variável de ambiente.
Implementando o Extrator de Características
Nosso sistema de estimativa de pose requer um extrator de características para converter as poses detectadas em um formato adequado para armazenamento no Milvus. Vamos definir uma classe para isso.
class FeatureExtractor:
def __init__(self, modelname):
# Load the pre-trained model
self.model = timm.create_model(
modelname, pretrained=True, num_classes=0, global_pool="avg"
)
self.model.eval()
# Get the input size required by the model
self.input_size = self.model.default_cfg["input_size"]
config = resolve_data_config({}, model=modelname)
# Get the preprocessing function provided by TIMM for the model
self.preprocess = create_transform(**config)
def __call__(self, imagepath):
# Preprocess the input image
input_image = Image.open(imagepath).convert("RGB") # Convert to RGB if needed
input_image = self.preprocess(input_image)
# Convert the image to a PyTorch tensor and add a batch dimension
input_tensor = input_image.unsqueeze(0)
# Perform inference
with torch.no_grad():
output = self.model(input_tensor)
# Extract the feature vector
feature_vector = output.squeeze().numpy()
return normalize(feature_vector.reshape(1, -1), norm="l2").flatten()
extractor = FeatureExtractor("resnet34")
Esta classe FeatureExtractor transformará nossas imagens em vetores de características. Estamos usando um modelo ResNet34 pré-treinado para esta tarefa. O método __call__ abre uma imagem, a pré-processa, a executa pelo modelo e retorna um vetor de características normalizado.
Definindo uma Classe de Callback de Usuário
Continue e defina uma classe simples de callback de usuário.
class user_app_callback_class(app_callback_class):
def __init__(self):
super().__init__()
Esta classe herda de app_callback_class e não adiciona nenhuma nova funcionalidade. É um espaço reservado que permite personalização futura do comportamento do callback.
Criando uma Função de Callback da Aplicação
A função app_callback faz a maior parte do processamento. Esta função processa quadros de vídeo, estima poses e armazena os resultados no Milvus.
def app_callback(pad, info, user_data):
# Get the GstBuffer from the probe info
lefteye = ""
righteye = ""
buffer = info.get_buffer()
# Verifica se o buffer é válido
if buffer is None:
return Gst.PadProbeReturn.OK
# Usando user_data para contar o número de quadros
user_data.increment()
string_to_print = f"Contagem de quadros: {user_data.get_count()}\n"
# Obtém os caps do pad
format, width, height = get_caps_from_pad(pad)
# Se user_data.use_frame estiver definido como True, podemos obter o quadro de vídeo do buffer
frame = None
if user_data.use_frame and format is not None and width is not None and height is not None:
# Obtém o quadro de vídeo
frame = get_numpy_from_buffer(buffer, format, width, height)
# Obtém as detecções do buffer
roi = hailo.get_roi_from_buffer(buffer)
detections = roi.get_objects_typed(hailo.HAILO_DETECTION)
# Analisa as detecções
for detection in detections:
label = detection.get_label()
bbox = detection.get_bbox()
confidence = detection.get_confidence()
if label == "person":
string_to_print += (f"Detecção: {label} {confidence:.2f}\n")
# Pontos de referência da estimativa de pose a partir da detecção (se disponíveis)
landmarks = detection.get_objects_typed(hailo.HAILO_LANDMARKS)
if len(landmarks) != 0:
points = landmarks[0].get_points()
left_eye = points[1] # assumindo que 1 é o índice para o olho esquerdo
right_eye = points[2] # assumindo que 2 é o índice para o olho direito
# Os pontos de referência são normalizados para a caixa delimitadora, também precisamos convertê-los para o tamanho do quadro
left_eye_x = int((left_eye.x() * bbox.width() + bbox.xmin()) * width)
left_eye_y = int((left_eye.y() * bbox.height() + bbox.ymin()) * height)
right_eye_x = int((right_eye.x() * bbox.width() + bbox.xmin()) * width)
right_eye_y = int((right_eye.y() * bbox.height() + bbox.ymin()) * height)
string_to_print += (f" Olho esquerdo: x: {left_eye_x:.2f} y: {left_eye_y:.2f} Olho direito: x: {right_eye_x:.2f} y: {right_eye_y:.2f}\n")
if user_data.use_frame:
# Adiciona marcadores ao quadro para mostrar os pontos de referência dos olhos
cv2.circle(frame, (left_eye_x, left_eye_y), 5, (0, 255, 0), -1)
cv2.circle(frame, (right_eye_x, right_eye_y), 5, (0, 255, 0), -1)
if user_data.use_frame:
# Converte o quadro para BGR
framesave = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
user_data.set_frame(framesave)
time_now = datetime.now()
current_time = int(time_now.strftime("%S"))
if current_time in time_list and len(label) > 4:
# Salva a imagem
strfilename = PATH + "/personpose.jpg"
cv2.imwrite(strfilename, framesave)
lefteye = (f"x: {left_eye_x:.2f} y: {left_eye_y:.2f}")
righteye = (f"x: {right_eye_x:.2f} y: {right_eye_y:.2f}")
# Slack
try:
response = client.chat_postMessage(
channel="C06NE1FU6SE",
text=(f"Detecção: {label} {confidence:.2f}")
)
except SlackApiError as e:
# Você receberá um SlackApiError se "ok" for False
assert e.response["error"]
try:
response = client.chat_postMessage(
channel="C06NE1FU6SE",
text=(f" Olho esquerdo: x: {left_eye_x:.2f} y: {left_eye_y:.2f} Olho direito: x: {right_eye_x:.2f} y: {right_eye_y:.2f}\n")
)
except SlackApiError as e:
# Você receberá um SlackApiError se "ok" for False
assert e.response["error"]
try:
response = client.files_upload_v2(
channel="C06NE1FU6SE",
file=strfilename,
title=label,
initial_comment="Live Camera image ",
)
except SlackApiError as e:
assert e.response["error"]
# Milvus insert
try:
imageembedding = extractor(strfilename)
milvus_client.insert( COLLECTION_NAME, {"vector": imageembedding, "lefteye": lefteye, "righteye": righteye, "label": label, "confidence": confidence})
except Exception as e:
print("An error:", e)
print(string_to_print)
return Gst.PadProbeReturn.OK
Esta função de callback processa quadros de vídeo para detectar pessoas, concentrando-se na extração de detalhes como a caixa delimitadora, a confiança e os pontos de referência dos olhos. Ela marca as posições dos olhos detectados no quadro e salva a imagem do quadro se houver uma pessoa no quadro. Além disso, envia notificações para o Slack com os detalhes da detecção e a imagem marcada. Em seguida, a função extrai um vetor de embedding da imagem salva. Ela atualiza o Milvus com esses dados, incluindo o embedding (vector), as coordenadas dos olhos (lefteye e righteye), o rótulo do objeto (label) e a confiança da detecção (confidence).
Criando a Função Utilitária para Keypoints COCO
Crie uma função utilitária para obter keypoints COCO. Estes são pontos específicos no corpo humano que são usados para estimativa de pose.
def get_keypoints():
"""Get the COCO keypoints and their left/right flip correspondence map."""
keypoints = {
'nose': 1,
'left_eye': 2,
'right_eye': 3,
'left_ear': 4,
'right_ear': 5,
'left_shoulder': 6,
'right_shoulder': 7,
'left_elbow': 8,
'right_elbow': 9,
'left_wrist': 10,
'right_wrist': 11,
'left_hip': 12,
'right_hip': 13,
'left_knee': 14,
'right_knee': 15,
'left_ankle': 16,
'right_ankle': 17,
}
return keypoints
Esta função retorna um dicionário que mapeia partes do corpo para seus índices de keypoint correspondentes no formato do conjunto de dados COCO.
Criando o Pipeline GStreamer
Prossiga e crie a classe principal da aplicação que configurará um pipeline GStreamer. Esta é uma sequência de elementos que processam dados multimídia em uma ordem específica. Ela processará transmissões de vídeo ao vivo.
# This class inherits from the hailo_rpi_common.GStreamerApp class
class GStreamerPoseEstimationApp(GStreamerApp):
def __init__(self, args, user_data):
# Call the parent class constructor
super().__init__(args, user_data)
# Additional initialization code can be added here
# Set Hailo parameters these parameters should be set based on the model used
self.batch_size = 2
self.network_width = 640
self.network_height = 640
self.network_format = "RGB"
self.default_postprocess_so = os.path.join(self.postprocess_dir, 'libyolov8pose_post.so')
self.post_function_name = "filter"
self.hef_path = os.path.join(self.current_path, '../resources/yolov8s_pose_h8l_pi.hef')
self.app_callback = app_callback
# Set the process title
setproctitle.setproctitle("Hailo Pose Estimation with Milvus")
self.create_pipeline()
def get_pipeline_string(self):
if (self.source_type == "rpi"):
source_element = f"libcamerasrc name=src_0 auto-focus-mode=2 ! "
source_element += f"video/x-raw, format={self.network_format}, width=1536, height=864 ! "
source_element += QUEUE("queue_src_scale")
source_element += f"videoscale ! "
source_element += f"video/x-raw, format={self.network_format}, width={self.network_width}, height={self.network_height}, framerate=30/1 ! "
elif (self.source_type == "usb"):
source_element = f"v4l2src device={self.video_source} name=src_0 ! "
source_element += f"video/x-raw, width=640, height=480, framerate=30/1 ! "
else:
source_element = f"filesrc location={self.video_source} name=src_0 ! "
source_element += QUEUE("queue_dec264")
source_element += f" qtdemux ! h264parse ! avdec_h264 max-threads=2 ! "
source_element += f" video/x-raw,format=I420 ! "
source_element += QUEUE("queue_scale")
source_element += f"videoscale n-threads=2 ! "
source_element += QUEUE("queue_src_convert")
source_element += f"videoconvert n-threads=3 name=src_convert qos=false ! "
source_element += f"video/x-raw, format={self.network_format}, width={self.network_width}, height={self.network_height}, pixel-aspect-ratio=1/1 ! "
pipeline_string = "hailomuxer name=hmux "
pipeline_string += source_element
pipeline_string += "tee name=t ! "
pipeline_string += QUEUE("bypass_queue", max_size_buffers=20) + "hmux.sink_0 "
pipeline_string += "t. ! " + QUEUE("queue_hailonet")
pipeline_string += "videoconvert n-threads=3 ! "
pipeline_string += f"hailonet hef-path={self.hef_path} batch-size={self.batch_size} force-writable=true ! "
pipeline_string += QUEUE("queue_hailofilter")
pipeline_string += f"hailofilter function-name={self.post_function_name} so-path={self.default_postprocess_so} qos=false ! "
pipeline_string += QUEUE("queue_hmuc") + " hmux.sink_1 "
pipeline_string += "hmux. ! " + QUEUE("queue_hailo_python")
pipeline_string += QUEUE("queue_user_callback")
pipeline_string += f"identity name=identity_callback ! "
pipeline_string += QUEUE("queue_hailooverlay")
pipeline_string += f"hailooverlay ! "
pipeline_string += QUEUE("queue_videoconvert")
pipeline_string += f"videoconvert n-threads=3 qos=false ! "
pipeline_string += QUEUE("queue_hailo_display")
pipeline_string += f"fpsdisplaysink video-sink={self.video_sink} name=hailo_display sync={self.sync} text-overlay={self.options_menu.show_fps} signal-fps-measurements=true "
print(pipeline_string)
return pipeline_string
Esta classe configura nosso pipeline GStreamer. Ela executa um modelo de estimativa de pose em um Raspberry Pi usando um acelerador de IA Hailo, que é um processador de IA de borda projetado para executar tarefas de deep learning e inferência de IA em dispositivos de borda. Ela inicializa parâmetros como tamanho do lote, dimensões de entrada, formato de cor e caminhos de arquivos para o modelo de rede neural e o pós-processamento. Dependendo da fonte de entrada (por exemplo, câmera Raspberry Pi, câmera USB ou arquivo de vídeo), ela cria um pipeline GStreamer para capturar vídeo, processá-lo por meio do modelo Hailo, aplicar pós-processamento e exibir a saída. A configuração do pipeline é especificada no método get_pipeline_string, que monta os elementos GStreamer necessários para esta tarefa.
Executando o Programa
A etapa final é executar o programa.
if __name__ == "__main__":
# Create an instance of the user app callback class
user_data = user_app_callback_class()
parser = get_default_parser()
args = parser.parse_args()
app = GStreamerPoseEstimationApp(args, user_data)
app.run()
É aqui que conectamos tudo. Criamos uma instância da nossa user_app_callback_class, analisamos quaisquer argumentos de linha de comando, criamos nosso GStreamerPoseEstimationApp e o executamos.
Aqui está um exemplo do resultado que você pode esperar ao executar o programa.
Fig 2- Saída de um programa de estimativa de pose no Slack com marcos dos olhos marcados com pontos verdes.png
Fig 2: Saída de um programa de estimativa de pose no Slack com marcos dos olhos marcados com pontos verdes
Esta é a atualização no Slack quando uma pessoa é detectada. Ela tem uma pontuação de confiança de 81%, as coordenadas dos olhos esquerdo e direito, e a imagem com os marcos dos olhos marcados (círculos verdes nas posições dos olhos esquerdo e direito).
Casos de uso da combinação de IA e bancos de dados vetoriais
Combinar IA de borda e bancos de dados vetoriais traz inúmeros casos de uso. Abaixo estão alguns exemplos.
Robótica
IA de borda e bancos de dados vetoriais aprimoram as capacidades de robôs autônomos, permitindo que processem dados de sensores localmente e tomem decisões instantâneas. Essa tecnologia melhora significativamente a eficiência e a adaptabilidade em ambientes dinâmicos.
Exemplo: Na automação de armazéns, robôs móveis autônomos (AMRs) usam câmeras embarcadas e bancos de dados vetoriais locais para reconhecimento de objetos em tempo real. À medida que navegam pelo armazém, esses robôs identificam e categorizam produtos instantaneamente comparando dados visuais com vetores armazenados localmente. Isso permite que eles se adaptem às condições variáveis do armazém e otimizem suas rotas sem depender de infraestrutura em nuvem.
Cidades inteligentes
IA de borda e bancos de dados vetoriais desempenham um papel crucial na otimização das operações urbanas, desde a gestão de tráfego até a segurança pública. Essas tecnologias permitem processamento rápido de dados e tomada de decisões na borda, melhorando a eficiência da cidade e a qualidade de vida dos residentes.
Exemplo: Sistemas inteligentes de gestão de tráfego aproveitam IA de borda para processar localmente feeds de vídeo de câmeras em cruzamentos. O sistema converte padrões de tráfego em representações vetoriais e os compara com dados históricos armazenados em um banco de dados vetorial local. Isso permite ajustes em tempo real dos semáforos para reduzir congestionamentos, garantindo tempos de resposta rápidos sem a necessidade de transmissão constante de dados para servidores centrais.
Automação industrial
IA de borda e bancos de dados vetoriais impulsionam a manutenção preditiva e o monitoramento de equipamentos em ambientes de manufatura e industriais. Essa abordagem permite análise em tempo real da saúde das máquinas, prevenindo tempo de inatividade e otimizando processos de produção.
Exemplo: Fábricas inteligentes implantam sensores em maquinário crítico para coletar continuamente dados de vibração. Dispositivos de borda convertem esses dados em representações vetoriais e os comparam com padrões de vibração conhecidos como "saudáveis" e "defeituosos" armazenados em um banco de dados vetorial local. Essa análise em tempo real permite a detecção imediata de possíveis falhas de equipamentos, facilitando a manutenção proativa e minimizando interrupções custosas.
Saúde
IA de borda e bancos de dados vetoriais transformam o atendimento ao paciente ao permitir monitoramento contínuo da saúde sem comprometer a privacidade. Essas tecnologias permitem análise sofisticada de dados de saúde diretamente em dispositivos vestíveis ou sistemas locais.
Exemplo: Monitores de ECG vestíveis utilizam IA de borda para processar dados de ritmo cardíaco localmente. O dispositivo converte padrões de ECG em vetores e os compara com um banco de dados de ritmos normais e anormais armazenado no próprio dispositivo. Essa abordagem permite a detecção imediata de possíveis problemas cardíacos, mantendo dados de saúde sensíveis no dispositivo, melhorando tanto a capacidade de resposta quanto a privacidade do paciente.
Conclusão
À medida que os dados não estruturados crescem em escala e importância, soluções eficientes de processamento tornam-se cada vez mais cruciais. Tim fez um bom trabalho ao destacar o potencial transformador de bancos de dados vetoriais como o Milvus, oferecendo recursos avançados tanto para implantações na nuvem quanto na edge. Seja para aplicações de IA em larga escala ou dispositivos edge com recursos limitados, Milvus e sua contraparte leve, Milvus Lite, permitem que as organizações aproveitem dados não estruturados para tomada de decisões em tempo real, inovação e eficiência operacional. Com a flexibilidade para escalar da nuvem à edge, essas tecnologias estão na vanguarda das soluções modernas impulsionadas por IA.
Recursos adicionais
Projetos de IA do Tim no GitHub:
Processamento de dados não estruturados com um Raspberry Pi AI Kit
Modelos de IA de melhor desempenho para seus apps GenAI | Zilliz
Continue lendo

Zilliz Cloud Enterprise Vector Search Powers High-Performance AI on AWS
Zilliz Cloud on AWS powers secure, scalable, ultra-fast vector search for enterprise AI apps, with BYOC, sub-10ms latency, and zero-DevOps simplicity.

Introducing Zilliz MCP Server: Natural Language Access to Your Vector Database
Developers can easily manage and query vector databases with natural language via Zilliz MCP Server in AI-native environments.

DeepSeek Always Busy? Deploy It Locally with Milvus in Just 10 Minutes—No More Waiting!
Learn how to set up DeepSeek-R1 on your local machine using Ollama, AnythingLLM, and Milvus in just 10 minutes. Bypass busy servers and enhance AI responses with custom data.


