En esta práctica el objetivo es segmentar algún objeto que se encuentra en un vídeo que se nos proporciona. En este caso el objeto puede ser una única pelota o varias de diferentes colores. Para lograr dicho objetivo emplearemos un filtro de color, y será necesario emplear la plataforma JdeRobot, el lenguaje Python, y la librería OpenCV.
Para la realización de la práctica emplearemos el componente cameraserver, que nos proporcionará las imágenes obtenidas de un vídeo o una cámara. Para ejecutar este componente ponemos en el terminal lo siguiente:
cameraserver --Ice.Config=cameraserver_conf.cfg
Para ejecutar nuestro código tenemos que poner en el terminal:
1. Lo primero que tendremos que hacer es obtener la imagen de la cámara (la cual vamos a segmentar) mediante input_image = self.camera.getImage() (este paso ya nos lo proporcionan). Si conseguimos la imagen entonces podemos mostrarla en la imagen que nos proporciona la imagen de color filter mediante la siguiente sentencia:
2. El segundo paso es emplear un filtro de suavizado puesto que la imagen tiene mucho ruido e imperfecciones. Lo recomendable es emplear un filtro gaussiano:
./color_filter.py --Ice.Config=color_filter_conf.cfg
1. Lo primero que tendremos que hacer es obtener la imagen de la cámara (la cual vamos a segmentar) mediante input_image = self.camera.getImage() (este paso ya nos lo proporcionan). Si conseguimos la imagen entonces podemos mostrarla en la imagen que nos proporciona la imagen de color filter mediante la siguiente sentencia:
self.camera.setColorImage(input_image)
2. El segundo paso es emplear un filtro de suavizado puesto que la imagen tiene mucho ruido e imperfecciones. Lo recomendable es emplear un filtro gaussiano:
gaussian_image = cv2.GaussianBlur(input_image, (5,5), 0.2)
3. Convertimos nuestra imagen que esta en el espacio de color RGB al espacio de color HSV:
hsv_image = cv2.cvtColor(gaussian_image, cv2.COLOR_RGB2HSV)
4. Aplicamos un filtro de color con unos valores mínimo y máximo para el tono, la saturación y la intensidad. Con dicha función obtendremos una imagen donde los objetos deseados aparecerá en blanco y el resto en negro.
image_HSV_filtered = cv2.inRange(hsv_image, value_min_HSV, value_max_HSV)
5. Realizamos la operación mofológica cierre para que se rellenen los huecos que quedan en la pelota:
| kernel = np.ones((19,19), np.uint8) |
image_HSV_filt_close=cv2.morphologyEx(image_HSV_filtered, cv2.MORPH_CLOSE, kernel)
self.camera.setThresoldImage(image_HSV_filt_close)
image_HSV_filtered_Copy = np.copy(image_HSV_filt_close)
input_image_Copy = np.copy(input_image)
7. Detectamos el contorno del objeto:
_, contours, hierarchy = cv2.findContours(image_HSV_filtered_Copy, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
8. Elegimos el color verde para realizar el bounding box de la pelota. Para ello he creado una función llamada bounding. Primero en la función realizamos una aproximación a rectángulos, mediante la cual se obtienen varios rectángulos, por lo que habrá que filtrarlos para quedarse con el cuadrado de mayor tamaño. Dicha función es la siguiente:
def bounding(self, contours, colors, input_image_Copy):
| area = 0 |
| cnt = cv2.approxPolyDP(contours[0], 3, True) |
for cnt in contours:
| # Approximates a polygonal curve(s) with the specified precision. |
| cnt = cv2.approxPolyDP(cnt, 3, True); | |||||||||||||||||||||||||||||||||
| ||
| rectX = x |
| rectY = y |
| rectH = h |
| if (len(contours) != 0): |
colors = [0, 255, 0]
self.bounding(contours, colors, input_image_Copy)
self.camera.setColorImage(input_image_Copy)
Los vídeos de la práctica son los siguiente:
El código está en el siguiente enlace:
https://github.com/RoboticsURJC-students/2016-tfg-vanessa-fernandez/tree/master/Practices%20of%20robotics/color_filter
No hay comentarios:
Publicar un comentario