fbpixel
Etiquetas: ,
0
(0)

Uma aplicação interessante na robótica é o reconhecimento de formas. Neste tutorial vamos utilizar a biblioteca OpenCV num código Python, que nos permitirá detectar o meio de uma linha. Para podermos acompanhar a linha, vamos realizar um tratamento de imagem com o OpenCV.

Isso permitirá, na sequência, regular de modo a manter o meio da linha sempre no centro da câmera, e assim seguir a sua trajetória! Decidimos fazer este tutorial no Raspberry Pi, pois o nosso propósito é realizar processamento de imagens por um robô utilizando a câmera Pi.

Material

Implementação

  • Instalação da OpenCV no Raspberry Pi
  • Uma fotografia de um cabo ou linha preta (como padrão, faça o download da fotografia abaixo – tirada com a câmera Pi – para trabalhar com o mesmo exemplo.)

Código

Antes de tudo, para podermos reutilizar a detecção da linha ou cabo num vídeo (sucessão de imagens), vamos implementar uma classe. O parâmetro dessa classe será o caminho da imagem. Como padrão, se a imagem estiver na mesma pasta que o código, será suficiente colocar o nome da imagem, por exemplo: “cam.jpg”).

Depois, é preciso salvar o código python abaixo num arquivo com o nome suivi_ligne.py

# -*- coding: utf-8 -*-
"""
@author: AranaCorp
"""
import cv2
import time
import numpy as np
import matplotlib.pyplot as plt


class LineTracking():
	"""
	Classe permettant le traitement d'image, la délimitation d'un contour et permet de trouver le centre de la
	forme detectée
	"""
	def __init__(self,img_file):
		"""The constructor."""
		self.img = cv2.imread(img_file)
		self.img_inter = self.img
		self.img_final = self.img
		self.cendroids = []
		self.mean_centroids = [0,0]

	def processing(self):
		"""Méthode permettant le traitement d'image"""
		#self.img=cv2.resize(self.img,(int(self.img.shape[1]*0.2),int(self.img.shape[0]*0.2))) #redimensionner l'image d'origine
		print(self.img.shape)
		#self.img = self.img[199:391, 149:505] #on recentre l'image en excluant les zones extérieures afin d'avoir une plus grande précision pour la suite
		gray = cv2.cvtColor(self.img, cv2.COLOR_BGR2GRAY) #on passe l'image en nuances de gris
		blur = cv2.GaussianBlur(gray,(5,5),0) #on floute l'image
		ret,thresh = cv2.threshold(blur,60,255,cv2.THRESH_BINARY_INV) #on binarise l'image

		self.img_inter=thresh
		"""Une ouverture permet d'enlever tous les élements qui sont plus petits que l'élement structurant (ou motif)
		Une fermeture permet de "combler" les trous qui ont une taille inférieur à l'élement structurant """
		kernel_open = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5)) #on créé l'élement structurant de l'ouverture
		kernel_close = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(10,10)) #on créé l'élement structurant de la fermeture

		thresh = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel_open) #on fait une ouverture suivant un motif
		thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel_close) #on fait une fermeturesuivant un motif

		connectivity = 8

		output = cv2.connectedComponentsWithStats(thresh, connectivity, cv2.CV_32S) #permet de délimiter une forme
		num_labels = output[0]
		labels = output[1]
		stats = output[2]
		self.centroids = output[3] #donne les centres de la ou des formes de l'image

		for c in self.centroids :
			"""Permet de faire la moyenne des centres de la forme, en effet sur l'image test,
			   il y a deux centres qui sont très proches et la moyenne de deux convient.
			   On pourra imaginer que dans un cas général on modifie cela
			"""
			self.mean_centroids[0] += c[0]/len(self.centroids)
			self.mean_centroids[1] += c[1]/len(self.centroids)

		self.img_final = cv2.cvtColor(thresh, cv2.COLOR_GRAY2BGR)

		#permet de rajouter un carré rouge à l'endroit du centre de la forme
		#self.img_final[int(self.mean_centroids[1])-10 : int(self.mean_centroids[1])+20, int(self.mean_centroids[0])-10 : int(self.mean_centroids[0])+20] = [0,0,255]
		for c in self.centroids :
			self.img_final[int(c[1])-5 : int(c[1])+10, int(c[0])-5 : int(c[0])+10] = [0,255,0]

E finalmente, criar um novo script python, por exemplo: test_tracking.py

if __name__ == '__main__' :
	test = LineTracking('cam.png') #créer un objet LineTracking qui est la Classe créée au dessus .png ou .jpg
	test.processing() #lance le traitement d'image
	while True :
		cv2.imshow('image',test.img) #affiche l'image original après redimensionnement
		#cv2.imshow('process',test.img_inter ) #affiche l'image après traitement
		cv2.imshow('cable',test.img_final) #affiche l'image après traitement
		key= cv2.waitKey(1);
		if  key == ord(' '): #pour fermer les fenêtres appuyer sur la barre 'espace'
			break
	cv2.destroyAllWindows()

Temos agora todos os códigos para testar o processamento da imagem. Vamos lançar no terminal o comando:

python3 test_tracking.py

Resultado

Duas janelas se abrem, com a imagem original e a imagem processada. Vemos que um quadrado verde marca a posição do cabo. Este ponto pode ser usado para conduzir um robô ou uma câmara móvel.

Para parar a exibição, basta pressionar a barra de espaço.

Acabamos de concluir o processamento de uma imagem. Podemos agora implementá-lo num loop de processamento para um vídeo.

Aplicação

Agora pode utilizar a classe LineTracking no seu arquivo principal, que abre a câmara Raspberry. Para mais informações sobre como instalar uma PiCam no Raspberry Pi, veja o nosso tutorial: Gerir uma PiCam com o Raspberry Pi.

Fontes

How useful was this post?

Click on a star to rate it!

Average rating 0 / 5. Vote count: 0

No votes so far! Be the first to rate this post.

As you found this post useful...

Follow us on social media!

We are sorry that this post was not useful for you!

Let us improve this post!

Tell us how we can improve this post?