Introdução ao rastreamento de objetos usando OpenCV

Conteúdo

Este artigo foi publicado como parte do Data Science Blogathon

Introdução

OpenCV é uma ótima ferramenta para brincar com imagens e vídeos. Ou você deseja dar às suas fotos uma aparência em preto e branco do 90 ou realizar operações matemáticas complexas, OpenCV está sempre pronto para servir. Se você gosta de visão computacional, o conhecimento do OpenCV é essencial. A biblioteca inclui mais de 2500 algoritmos otimizados que podem ser usados ​​para realizar uma ampla variedade de tarefas. É usado por muitos gigantes da indústria como o Google, Microsoft, IBM e é amplamente utilizado em grupos de pesquisa. A biblioteca oferece suporte a vários idiomas, incluindo java, c ++ e python.

Este artigo mostrará como realizar a complexa tarefa de rastreamento de objetos usando algumas das funções básicas do OpenCV.

Você pode considerar um exemplo de um jogo de futebol. Você tem uma transmissão ao vivo da partida e sua tarefa é rastrear a posição da bola o tempo todo. A tarefa parece simples para um ser humano médio, mas é muito complexo até mesmo para a máquina mais inteligente. Como você vai saber, computadores só entendem números. Você não entende o que é uma imagem, mas os valores de pixel associados à imagem. Duas imagens que parecem ser exatamente iguais ao olho humano podem não ser o mesmo caso para o seu computador, uma vez que mesmo uma pequena mudança em um pixel resultará em uma diferença. Por isso, rastreamento de objetos é considerado uma das tarefas mais complexas em visão computacional. Embora complexo, não é algo inatingível.

O rastreamento de objetos pode ser feito usando aprendizado de máquina, bem como abordagens baseadas em aprendizado profundo. A abordagem de aprendizagem profunda, por um lado, fornece melhores resultados em tarefas complexas e é bastante difundida, requer muitos dados de treinamento. Embora as abordagens baseadas em ML sejam bastante diretas, mas não difundidas. Para este artigo, estamos usando uma abordagem baseada em ML em conjunto com várias técnicas de visão computacional que discutiremos posteriormente neste artigo.

A técnica é amplamente utilizada na vigilância, segurança, monitoramento de tráfego, visão de robô, comunicação de vídeo e muito mais. O que mais, rastreamento de objetos tem vários casos de uso, como contagem de multidão, veículos autônomos, detecção de rosto, etc. Você pode pensar em mais alguns exemplos em que pode usar o rastreamento de objetos em sua vida diária??

Devido a tantas aplicações da vida real, pesquisas constantes estão sendo feitas neste campo para obter maior precisão e tornar o modelo mais robusto.

Para este artigo, usaremos este vídeo. Como você verá, existe uma bola vermelha que se move através de um labirinto e nossa tarefa é detectar a localização da bola e encontrar seu centroide. Eu também pude ver um grande barulho (desculpe pessoas), fundo, para fazer lição de casa um pouco mais desafiador.

22521captura de tela2025-6154785

1.

Em primeiro lugar, importamos as bibliotecas necessárias para serem usadas.

import numpy as np
import cv2

2.

Estaremos definindo uma função que redimensionará as imagens para caber em nossa tela no caso de serem grandes o suficiente. este passo é completamente opcional e você pode ignorá-lo.

def redimensionar(img):
        retorno cv2.resize(img,(512,512)) # arg1- imagem de entrada, Arg- output_width, output_height

3.

Como você vai saber, vídeos são feitos de quadros. Os quadros são apenas uma das muitas imagens estádas que juntas formam toda a imagem em movimento.. O próximo passo será ler essas caixas usando o recurso VideoCapture. () em OpenCV e usando o loop while, podemos ver as pinturas se movendo. Você pode ajustar a velocidade de vídeo usando cv2.waitKey (x) que pausa a tela para x milissegundos.

cap=cv2. VideoCapture(vid_file_path)
direito,frame=cap.read()

enquanto ret==True:
    direito,frame=cap.read()
    cv2.imshow("quadro",redimensionar(quadro))
    key=cv2.waitKey(1)
    se key==ord('q'):
        break
cv2.waitKey(0)
cv2.destroyAllWindows()

4.

OpenCV lê imagens em formato BGR, então vamos converter o espaço de cores de BGR para HSV. Por que hsv e não BGR ou qualquer outro formato?

Estamos usando o formato de cor HSV porque é mais sensível a pequenas alterações na iluminação externa.. Portanto, vai dar máscaras mais precisas e, portanto, melhores resultados.

Depois de converter o espaço de cores, o que temos que fazer é filtrar o canal vermelho e criar um quadro de máscara.

O canal vermelho em formato hsv está presente em [0,230,170] para [255,255,220] distância.

cap=cv2. VideoCapture(vid_file_path)


direito,frame=cap.read()
l_b=np.array([0,230,170])# lower hsv bound for red
u_b=np.array([255,255,220])# upper hsv bound to red

while ret==True:
    direito,frame=cap.read()

    hsv = cv2.cvtColor(quadro,cv2.COLOR_BGR2HSV)
    mask = cv2.inRange(hsv,Libra,u_b)

    cv2.imshow("quadro",redimensionar(quadro))

    cv2.imshow("mascarar",mascarar)


    key=cv2.waitKey(1)
    se key==ord('q'):
        break
cv2.waitKey(0)
cv2.destroyAllWindows()

68572mascarado-4189669

(Esta imagem foi redimensionada)

5.

Até agora, criamos a imagem mascarada da moldura e filtramos a maior parte do ruído. O que se segue é obter os limites da bola. Para isso, usaremos o conceito de detecção de contorno. Os contornos nada mais são do que limites que cercarão nossa bola. Felizmente, não temos que encontrar esses limites por conta própria, uma vez que o OpenCV permite uma função findContours () que podemos usar para o nosso propósito. Obtém uma imagem mascarada e retorna uma série de contornos. Para obter mais informações sobre contornos, Visita mim. Idealmente, no nosso caso, o valor dos contornos deve ser um, já que só temos uma bola, mas porque algumas pessoas usavam chapéus vermelhos, vamos conseguir mais de um. Você consegue pensar em algo para reduzir ainda mais esse ruído?

Para lidar com este problema, usaremos outra função OpenCV que é cv2.contourArea (). Nós sabemos na imagem mascarada, a bola tem a maior área e também o seu contorno. Portanto, vamos obter o contorno com a maior área.

Temos os contornos da bola e podemos desenhar diretamente esses contornos usando a função cv2.drawContours (). Mas para tarefas de detecção, o que geralmente fazemos é usar um retângulo bem delimitado para mostrar que o objeto foi detectado. Para faze-lo, vamos usar a função cv2.boundingRect (). Esta função irá retornar as coordenadas do retângulo e então a função cv2.rectangle () vai desenhar o retângulo para nós.

cap=cv2. VideoCapture(vid_file_path)


direito,frame=cap.read()
l_b=np.array([0,230,170])# lower hsv bound for red
u_b=np.array([255,255,220])# upper hsv bound to red

while ret==True:
    direito,frame=cap.read()

    hsv = cv2.cvtColor(quadro,cv2.COLOR_BGR2HSV)
    mask = cv2.inRange(hsv,Libra,u_b)

    contornos,_ = cv2.findContours(mascarar,cv2.RETR_TREE,cv2. CHAIN_APPROX_SIMPLE)

    max_contour = contornos[0]
         para contorno em contornos:
                se cv2.contourArea(contorno)>cv2.contourArea(max_contour):

                      max_contour=contour

         contour=max_contour
         approx=cv2.approxPolyDP(contorno, 0.01*cv2.arcLength(contorno,Verdade),Verdade)
         x,e,C,h=cv2.delimitandoRect(aprox.)
         cv2.rectangle(quadro,(x,e),(x+w,y+h),(0,255,0),4)

    cv2.imshow("quadro",redimensionar(quadro))

    cv2.imshow("mascarar",mascarar)

528745-3351114

(Esta imagem foi redimensionada)

6.

O que mais, o que podemos fazer é detectar o centroid da bola simultaneamente. Para isso, vamos usar cv2.moments. cv2.moments calcula a soma média ponderada de intensidades de pixels dentro do contorno e, portanto, permite obter informações mais úteis a partir do blob, como seu rádio, centroide, etc. Certifique-se de converter a imagem em formato binário antes de usar o. Você pode aprender mais sobre momentos aqui.

cap=cv2. VideoCapture(vid_file_path)


direito,frame=cap.read()
l_b=np.array([0,230,170])# lower hsv bound for red
u_b=np.array([255,255,220])# upper hsv bound to red

while ret==True:
    direito,frame=cap.read()

    hsv = cv2.cvtColor(quadro,cv2.COLOR_BGR2HSV)
    mask = cv2.inRange(hsv,Libra,u_b)

    contornos,_ = cv2.findContours(mascarar,cv2.RETR_TREE,cv2. CHAIN_APPROX_SIMPLE)

    max_contour = contornos[0]
         para contorno em contornos:


                se cv2.contourArea(contorno)>cv2.contourArea(max_contour):

                  max_contour = contour

         approx=cv2.approxPolyDP(contorno, 0.01*cv2.arcLength(contorno,Verdade),Verdade)
         x,e,C,h=cv2.delimitandoRect(aprox.)
         cv2.rectangle(quadro,(x,e),(x+w,y+h),(0,255,0),4)

         M=cv2.moments(contorno)

cx = int (M['m10']//METRO['m00'])
cy = int (M['m01']//METRO['m00'])
cv2.circle (marco, (cx, cy), 3, (255,0,0), – 1)


    cv2.imshow("quadro",redimensionar(quadro))

    cv2.imshow("mascarar",mascarar)

    key=cv2.waitKey(1)
    se key==ord('q'):
        break
cv2.waitKey(0)
cv2.destroyAllWindows()

200486-8346694

(Esta imagem foi redimensionada)

Para onde ir a partir daqui

Neste artigo, usamos a detecção de objetos em cada quadro para a tarefa de rastreamento de objetos. Embora seja útil, pode não funcionar bem em todos os casos. Ao ler o artigo, várias perguntas podem ter atingido seu cérebro. E se houver mais de um objeto no vídeo? E se as imagens da máscara não ajudarem a detectar o objeto? E se o objeto estiver constantemente se movendo para dentro e para fora do quadro? E se não houver nenhum objeto?

A única maneira de encontrá-los é experimentá-los por conta própria.. Você sempre pode ajustar as entradas e tornar a tarefa um pouco mais desafiadora até que a diversão pare.

A mídia mostrada neste artigo não é propriedade da DataPeaker e é usada a critério do autor.

Assine a nossa newsletter

Nós não enviaremos SPAM para você. Nós odiamos isso tanto quanto você.