Técnicas digitales III –Problema de ingeniería- UNIVERSIDAD TECNOLÓGICA NACIONAL FACULTAD REGIONAL SAN NICOLÁS INGENIERIA ELECTRÓNICA TÉCNICAS DIGITALES III Problema de ingeniería “Seguimiento y conteo de botellas mediante visión artificial” Integrantes: Villarruel, Cristian Correa, Sergio Serra, Pedro E. Docentes: Ing. Poblete, Felipe Ing. González, Mariano AÑO 2015 1 Técnicas digitales III –Problema de ingeniería- Seguimiento y conteo de botellas mediante visión artificial. Objetivos: En éste trabajo practico, implementaremos la detección, reconocimiento de botellas y seguimiento en tiempo real, sobre una imagen de cámara de video, para ser contadas por unidad, a los fines de conocer la producción de la planta. Convengamos que se le puede dar mas usos además de conteo (como ser grabación de las imágenes para usos de control de calidad, medición de velocidad, etc), frente a un sistema de conteo por sensores industriales. También se puede adaptar para contar vehículos sobre una carretera, gente en un centro comercial, otras piezas de producción en movimiento, etc. 2 Técnicas digitales III –Problema de ingeniería- Introducción Para simular el sistema, se utilizó una maqueta de la cinta transportadora, una PC con windows XP, una webcam Genius , y como software específico, Visual Studio Express y OpenCV 2.4.9 para el lenguaje de programación C/C++. La cámara de video Genius tipo webcam de 640x480 pixeles , es usada en la maqueta por su bajo costo, pero puede mejorarse. 3 Técnicas digitales III –Problema de ingeniería- Diagrama de bloques del sistema de conteo: Uno de los aspectos más importantes de la visión artificial es sin duda el reconocimiento de objetos, de patrones, o identificación de figuras y formas. Este reconocimiento puede ir desde ejemplos muy simples (reconocer en una imagen el único objeto de color rojo), hasta posibilidades muy complejas y útiles que aún hoy son prácticamente imposibles (como cámaras de aeropuerto que detecten terroristas automáticamente reconociendo su cara). Este problema plantea un gran reto, pero son infinitas sus posibilidades y aplicaciones. En un futuro se plantea que los robots humanoides tengan un sistema avanzado de reconocimiento de objetos, siendo capaz como los humanos de reconocer a las personas por sus caras, y los demás objetos de su entorno. 4 Técnicas digitales III –Problema de ingeniería- 1. Breve funcionamiento de la cámara: La luz de la imagen pasa por la lente, esta se refleja en un filtro RGB (Red-Green-Blue), el cuál descompone la luz en tres colores básicos: rojo, verde y azul. Esta división de rayos se concentra en un chip sensible a la luz denominado CCD ("Charged Coupled Device"), el cuál asigna valores binarios a cada píxel y envía los datos digitales para su codificación en video y posterior almacenamiento ó envío a través de Internet. 2. OpenCV OpenCV (Open Source Computer Vision Library) es un marco de trabajo de código abierto y software de aprendizaje desarrollado por Intel. Fue construido para proporcionar una infraestructura común para aplicaciones de visión por computador y para acelerar el uso de la percepción de la máquina en los productos comerciales. Al ser un producto con licencia libre, OpenCV hace que sea fácil para las empresas a utilizar y modificar el código. La biblioteca cuenta con más de 2.500 algoritmos optimizados, que incluye un amplio conjunto para el aprendizaje. Estos algoritmos se pueden utilizar para detectar y reconocer rostros, identificar objetos, clasificar las acciones humanas en los videos, rastrear los movimientos de cámara, seguimiento de objetos en movimiento, extraer modelos 3D de objetos, encontrar imágenes similares a partir de una base de datos de 5 Técnicas digitales III –Problema de ingeniería- imágenes, eliminar los ojos rojos de las imágenes tomadas con flash, siguir los movimientos del ojo, reconocer paisajes, etc OpenCV cuenta con muchos usuarios y el número estimado de descargas superiores a 7 millones. La biblioteca se utiliza ampliamente en las empresas, grupos de investigación y los organismos gubernamentales. Empresas bien establecidas como Google, Yahoo, Microsoft, Intel, IBM, Sony, Honda, Toyota, hacen un amplio uso de OpenCV. Aplicaciones desplegadas de OpenCV abarcan desde streetview, detección de intrusiones en video de vigilancia en Israel, los equipos de vigilancia de minas en China, ayudando a los robots navegar y recoger objetos, la detección en la piscina de accidentes por ahogamiento en Europa, corriendo arte interactivo en España y Nueva York, comprobando pistas de escombros en Turquía, la inspección de las etiquetas de los productos en las fábricas de todo el mundo ,etc. Bibliotecas de software Una biblioteca de software consiste en un conjunto de funciones descritas en un lenguaje de programación en específico que permiten agilizar el trabajo y brindar una interface de desarrollo al programador o API ―Application Program Interface en el tema de visión por computadora existen distintas de estas bibliotecas, en nuestro grupo de investigación la biblioteca usada es OpenCV . OpenCV es un conjunto de bibliotecas de código abierto u Open Source desarrolladas en un principio por Intel. Están desarrolladas en lenguaje C, con puertos a C++, phyton y octave. Además, se pueden ejecutar desde diversos sistemas operativos como 6 Técnicas digitales III –Problema de ingeniería- Windows, GNU/Linux y Mac OS X y desde diversas plataformas de hardware basadas en procesadores x86, ARM y PowerPC. Estas bibliotecas ofrecen código diseñado eficientemente, orientado a aplicaciones capaces de ejecutarse en tiempo real en procesadores modernos. Estas bibliotecas tienen como objetivo proveer las funciones más usadas en Visión por computadora y tiene más de 500 funciones implementadas. Se usan ampliamente en Vigilancia, imágenes médicas, inspección industrial, interfaces de usuario, calibración de cámaras y recientemente se han usado estas bibliotecas en imágenes aéreas y mapas de calles, por ejemplo en la herramienta Google’s Street View. Se hace uso de la calibración de cámara y de funciones de OpenCV para hacer el proceso de stitching, que consiste en combinar múltiples imágenes para producir una imagen panorámica o una imagen de alta resolución. 3. Introducción a Visual Studio Express Visual Studio es un conjunto completo de herramientas de desarrollo para la generación de aplicaciones web ASP.NET, Servicios Web XML, aplicaciones de escritorio y aplicaciones móviles. Visual Basic, Visual C# y Visual C++ utilizan todos el mismo entorno de desarrollo integrado (IDE), que habilita el uso compartido de herramientas y facilita la creación de soluciones en varios lenguajes. Asimismo, dichos lenguajes utilizan las funciones de .NET Framework, las cuales ofrecen acceso a tecnologías clave para simplificar el desarrollo de aplicaciones web ASP y Servicios Web XML. 4. ¿Qué es una imagen?: Aunque una imagen es la reproducción de la figura de un objeto por la combinación de los rayos de luz que inciden en el, dentro de un ordenador una imagen no es más que una gran secuencia de ceros y unos que podemos leer y modificar a nuestro antojo. Como ya sabemos, el tamaño de las imágenes se mide en píxeles, que es precisamente la superficie homogénea más pequeña de las que componen una imagen, que se define por su brillo y color. Si cambiamos la resolución de nuestra pantalla veremos la misma imagen (de 600×400 píxeles) más pequeña o más grande. 7 Técnicas digitales III –Problema de ingeniería- Cada píxel está además definido por su color o brillo. Las imágenes en blanco y negro son las más básicas, pudiendo tomar sus píxeles valores entre 0 (completamente negro) y 255 (completamente blanco). Sin embargo las imágenes de color contienen tres canales de colores distintos (los famosos RGB (R : rojo, G : verde, B : Azul). Cada canal puede tomar un valor entre 0 y 255, por ejemplo un R = 255, G = 0, y B = 0 será un píxel completamente rojo. Si los tres valores son 255 el píxel será blanco, y si los tres valen 0 el píxel será negro. Existe además el sistema HSB (Hue, Saturation, Brightness (Matiz, Saturación, Luminosidad)), con el que también se puede crear cualquier color, y que tiene transformación directa a su representación en el sistema RGB: Por tanto, ¿cuántos valores hay en una imagen?: el cálculo es sencillo: altura x anchura x canales. Para recorrer una imagen en OpenCV se va de izquierda a derecha, y de arriba a abajo. Teniendo en cuenta además que los canales están ordenados en BGR (azul, verde y rojo), si quisiésemos acceder al valor rojo del píxel número 40 de la fila 24 tendríamos que acceder al dato: anchura_fila*23 + numero_canales*39 + 2, donde anchura_fila será la anchura de la imagen multiplicada por el número de canales. Está 8 Técnicas digitales III –Problema de ingeniería- es la única forma de recorrer imágenes, y se implementa con bucles anidados como veremos posteriormente. Estimación de primer plano En visión por computador es común tener el caso del análisis de un video proveniente de una cámara fija en la que los pixeles de la imagen pueden ser separados en dos clases: el fondo y el primer plano. La primera clase correspondería a el fondo de la imagen que corresponde a los objetos estáticos en la imagen o objetos que presentan un movimiento constante, por ejemplo en una escena de un bosque los arboles harían parte del fondo, sus troncos totalmente fijos y sus hojas que son movidas por el viento, o en una escena del interior de un centro comercial, si una cámara ve hacia unas escaleras eléctricas, estas harían parte del fondo junto con el piso y las barandas. La segunda clase corresponde al primer plano, que son pixeles distintos al fondo de la escena que presenten un movimiento deseable a analizar. Del fondo y el primer plano es posible crear una imagen lógica, se acostumbra asignar un uno lógico al primer plano y un cero lógico al fondo. Existen técnicas distintas para obtener esta máscara de primer plano, las más básicas consisten en encontrar una imagen que corresponde al fondo, realizar una resta en valor absoluto entre esta imagen de fondo y el cuadro de video y umbralizar el resultado. Este tipo de algoritmo de obtención del primer plano mediante una imagen de fondo tiene la desventaja de solo poder modelar un fondo de la escena, por ejemplo en la escena del bosque, los troncos de los arboles serian bien modelados, pero las hojas movidas por el viento no, además se generan falsos positivos de primer plano con los cambios bruscos de iluminación o con las sombras de los objetos móviles. Se puede llegar a un modelo más complejo que el anterior usando imágenes creadas a partir de la media, de la varianza y la covarianza por pixel de las imágenes del video. 9 Técnicas digitales III –Problema de ingeniería- 5. Primer programa con OpenCV: Una vez que lo hemos instalado podemos comenzar a crear nuestra primera aplicación, en opencv (una librería de computación visual) trabajaremos la mayoría del tiempo con imágenes y videos por lo cual lo primero que veremos será como mostrar imágenes y videos en nuestros proyectos. Mostrar una imagen en OpenCV Lo primero es crear un proyecto opencv con la plantilla que previamente creamos. #include <opencv2\opencv.hpp> using namespace cv; int main( int argc, char** argv ) { //crea una ventana llamada ‘ventana’ de tamaño automático o ajustable namedWindow( "ventana", CV_WINDOW_AUTOSIZE); //Espera a que se presione una tecla 10 Técnicas digitales III –Problema de ingeniería- waitKey(0); //destruye la ventana destroyWindow( "ventana" ); } Con este código creamos una ventana vacía. Lo siguiente que debemos hacer es cargar la imagen y mostrarla en la pantalla que acabamos de crear, algunos formatos admitidos son: jpg, png, tiff. #include <opencv2\opencv.hpp> using namespace cv; int main( int argc, char** argv ) { namedWindow( "ventana", CV_WINDOW_AUTOSIZE); //carga la imagen indicada y la devuelve en una matriz Mat m1 = imread("imagen.jpeg"); //Muestra la imagen la ventana indicada imshow("ventana", m1); waitKey(0); destroyWindow( "ventana" ); } 11 Técnicas digitales III –Problema de ingeniería- Con esto tenemos nuestro primer programa listo, el cual muestra una imagen en una ventana, debemos presionar una tecla para salir, en nuestro caso la imagen debe estar en el proyecto si se encuentra fuera debemos indicar la ruta completa. 6. ¿Cómo detectar un objeto de determinado color?: Para detectar un objeto de determinado color necesitaremos detectar todos los píxeles que lo componen. Para ello iremos buscando en todos los píxeles de la imagen, calculando si son o no del color deseado. ¿Como sabemos si por ejemplo es rojo?. En primer lugar tenemos que ver qué datos característicos tiene dicho color. En este caso es sencillo, su dato más característico será que el canal con mayor valor será el del rojo. También deberíamos tener en cuenta que los valores de los demás canales no deberían ser muy altos, por lo menos no lo suficiente como para acercarse al valor del canal del rojo, ya que estos valores podrían corresponder a colores como el morado o el naranja. Con un color que no sea de los tres básicos la cosa se complica un poco; en este caso lo mejor es abrir la imagen con un editor de imágenes (el Paint por ejemplo), y mirar que valores RGB tienen los píxeles del color deseado. Así podremos sacar las características que nos determinarán dicho color. Una vez tengamos todos los píxeles del objeto podemos hacer varias cosas: podríamos cambiar de color los píxeles y mostrar la imagen resultante por pantalla para ver si ha detectado bien el objeto. Podemos además llevar un contador de cuantos píxeles llevamos, y una suma de sus posiciones, lo que nos serviría para calcular lo que sería el punto medio de nuestro objeto. Estás coordenadas del punto medio serán bastante precisas si contamos con una gran cantidad de píxeles del objeto, y ésto será de gran utilidad para emplazar dicho objeto con respecto a un robot por ejemplo. 7. Dibujar formas y texto : 12 Técnicas digitales III –Problema de ingeniería- Opencv posee varias funciones con las que podemos crear figuras geométricas o formas más complejas, dibujar textos sobre las imágenes, vamos a ver cuáles son estas funciones y cómo usarlas en nuestros proyectos con opencv. Lo primero que necesitamos es donde dibujar por lo que crearemos una imagen (Mat) vacía sobre la cual representaremos nuestros dibujos, el siguiente código crea un objeto de la clase Mat que representa nuestra imagen en opencv de 800x600 pixeles, de 3 canales BGR, e inicializada en 0 o sea color negro. Mat img(rows, cols, CV_8UC3, Scalar::all(0)); rows: cantidad de filas o pixeles de alto que tendrá nuestra imagen 600. cols: cantidad de columnas o pixeles de ancho de nuestra imagen 800. CV_8UC3: puede ser alguno de los valores mencionados abajo seguido de C3 para tres canales, o C1, C2, C4 para 1, 2, 4, canales respectivamente: CV_8U - 8-bit unsigned integers ( 0..255 ) CV_8S - 8-bit signed integers ( -128..127 ) CV_16U - 16-bit unsigned integers ( 0..65535 ) CV_16S - 16-bit signed integers ( -32768..32767 ) CV_32S - 32-bit signed integers ( -2147483648..2147483647 ) CV_32F - 32-bit floating-point numbers ( -FLT_MAX..FLT_MAX, INF, NAN ) CV_64F - 64-bit floating-point numbers ( -DBL_MAX..DBL_MAX, INF, NAN ) Scalar::all(0): Scalar representa el color de la imagen en formato BGR, podemos establecer un color diferente estableciendo los diferentes canales de este modo: 13 Técnicas digitales III –Problema de ingeniería- Scalar(azul, verde, rojo), podemos usar el macro CV_RGB(rojo, verde, azul) si nos resulta más cómodo. Ahora podemos comenzar a dibujar, la primera función que veremos es circle la cual nos sirve para dibujar un circulo, es muy sencilla veamos cómo se usa: circle(img, Point(cols / 2, rows / 2), 250, Scalar(255,0,0), 3); Para usar esta función debemos indicar en qué imagen vamos a dibujar, el punto donde se ubicara el centro del circulo seguido del radio y el color, existen otros parámetros de esta función pero son opcionales, en este caso el ultimo 3 indica el grosor de la línea de dibujo. Además existen la funciones line, rectangle, entre otras cuyo uso es muy similar. Otra función interesante de dibujo es la función putText la cual dibuja en texto, para la misma debemos especificar la imagen donde vamos a dibujar, el texto a representar, el punto donde será dibujado el texto (la parte izquierda inferior), el tipo de letra , el tamaño, color, y grosor del texto. putText(img, "OpenCV 2", Point(180,320), FONT_HERSHEY_SCRIPT_COMPLEX, 3,CV_RGB(125,12,145), 2); Código de ejmplo: #include <opencv2\opencv.hpp> using namespace cv; void main() { 14 Técnicas digitales III –Problema de ingeniería- int rows = 600; int cols = 800; int rec = 150; //crear una imagen de 800x600 pixeles //canal BGR de tipo CV_8U( valores de 0 a 255) //inicializamos a 0 (color negro) Mat img(rows, cols, CV_8UC3, Scalar::all(0)); //dibuja un circulo en el centro de la imagen de un radio de 250 circle(img, Point(cols / 2, rows / 2), 250, Scalar(255,0,0), 3); //dibuja una linea line(img, Point(), Point(cols, rows), CV_RGB(255,0,0), 2, CV_AA); //dibuja un rectangulo rectangle(img, Point(rec, rec), Point(cols - rec, rows - rec),CV_RGB(0,255,255)); //dibuja el texto Opencv 2 putText(img, "OpenCV 2", Point(180,320), FONT_HERSHEY_SCRIPT_COMPLEX, 3, CV_RGB(125,12,145), 2); imshow("Drawing", img); waitKey(0); } 15 Técnicas digitales III –Problema de ingeniería- 8. Ejemplo de funciones : Operaciones morfológicas : “Erode” y “Dilate” Visualmente realizan lo siguiente en la imagen Erode erode(img, dst, krl); A medida que se explora la imagen, se calcula el valor mínimo de píxeles solapado y se reemplaza la imagen en el punto de anclaje con ese valor mínimo. Dilate dilate(img, dst, krl); erode Como se puede deducir, esta operación hace la maximización de las regiones luminosas en una imagen para hacerla "crecer" (por lo tanto el nombre de dilatación). : 16 Técnicas digitales III –Problema de ingeniería- 9. Codigo fuente de nuestro proyecto: #include #include #include #include #include #include <sstream> <string> <iostream> <opencv\highgui.h> <opencv\cv.h> <windows.h> int cont = 0; int bandera = 0; using namespace cv; //inicializo valores de filtrado min and max HSV . //los modificamos usando las barras de seguimiento int H_MIN = 0; int H_MAX = 256; int S_MIN = 0; int S_MAX = 256; int V_MIN = 0; int V_MAX = 256; //defino por defecto ancho y altura const int FRAME_WIDTH = 640; const int FRAME_HEIGHT = 480; //numero maximo de objetos a ser detectados en la pantalla const int MAX_NUM_OBJECTS=50; //maximo y minimo del objecto const int MIN_OBJECT_AREA = 20*20; const int MAX_OBJECT_AREA = FRAME_HEIGHT*FRAME_WIDTH/1.5; //nombres de las pantallas const string windowName = " Imagen Original"; const string windowName1 = "Imagen HSV "; const string windowName2 = "Imagen Objeto filtrado"; const string windowName3 = "Despues de Operaciones Morfologicas "; const string trackbarWindowName = "Barras de seguimiento"; void on_trackbar( int, void* ){ } string intToString(int number){ std::stringstream ss; 17 Técnicas digitales III –Problema de ingenieríass << number; return ss.str(); } void createTrackbars(){ //crea la pantalla de barras de seguimiento namedWindow(trackbarWindowName,0); //Almaceno memoria char TrackbarName[50]; sprintf( TrackbarName, "H_MIN", H_MIN); sprintf( TrackbarName, "H_MAX", H_MAX); sprintf( TrackbarName, "S_MIN", S_MIN); sprintf( TrackbarName, "S_MAX", S_MAX); sprintf( TrackbarName, "V_MIN", V_MIN); sprintf( TrackbarName, "V_MAX", V_MAX); //creo barras e inserto en pantalla //con 3 parametros: la direccion de la variable que cambia cuando muevo la barra (ejemplo H_LOW), //el valor maximo que se puede lograr (ejemplo H_HIGH), //y la funcion que se llama al mover la barra ( on_trackbar) // ----> ----> ----> createTrackbar( "H_MIN", trackbarWindowName, &H_MIN, H_MAX, on_trackbar ); createTrackbar( "H_MAX", trackbarWindowName, &H_MAX, H_MAX, on_trackbar ); createTrackbar( "S_MIN", trackbarWindowName, &S_MIN, S_MAX, on_trackbar ); createTrackbar( "S_MAX", trackbarWindowName, &S_MAX, S_MAX, on_trackbar ); createTrackbar( "V_MIN", trackbarWindowName, &V_MIN, V_MAX, on_trackbar ); createTrackbar( "V_MAX", trackbarWindowName, &V_MAX, V_MAX, on_trackbar ); } void drawObject(int x, int y,Mat &frame){ //uso funciones de openCV para dibujar la mira //sobre la imagen original //se usa 'if' y 'else' para prevenir errores de memoria // (ejemplo (-25,-25) no existe en pantalla) circle(frame,Point(x,y),20,Scalar(0,255,0),2); if(y-25>0) line(frame,Point(x,y),Point(x,y-25),Scalar(0,255,0),2); else line(frame,Point(x,y),Point(x,0),Scalar(0,255,0),2); if(y+25<FRAME_HEIGHT) line(frame,Point(x,y),Point(x,y+25),Scalar(0,255,0),2); else line(frame,Point(x,y),Point(x,FRAME_HEIGHT),Scalar(0,255,0),2); if(x-25>0) line(frame,Point(x,y),Point(x-25,y),Scalar(0,255,0),2); else line(frame,Point(x,y),Point(0,y),Scalar(0,255,0),2); if(x+25<FRAME_WIDTH) line(frame,Point(x,y),Point(x+25,y),Scalar(0,255,0),2); else line(frame,Point(x,y),Point(FRAME_WIDTH,y),Scalar(0,255,0),2); putText(frame,intToString(x)+","+intToString(y),Point(x,y+30),1,1,Scalar(0,255,0),2); //Codigo para conteo que pasen por la linea if(x>300 && x<340 && bandera == 0){ cont++; 18 Técnicas digitales III –Problema de ingenieríabandera = 1;} if(x<300) bandera = 0; } void morphOps(Mat &thresh){ //creo estructura para "dilatar" y "erosionar" la imagen. Mat erodeElement = getStructuringElement( MORPH_RECT,Size(3,3)); //dilata para hacerlo visible Mat dilateElement = getStructuringElement( MORPH_RECT,Size(8,8)); erode(thresh,thresh,erodeElement); erode(thresh,thresh,erodeElement); dilate(thresh,thresh,dilateElement); dilate(thresh,thresh,dilateElement); } void trackFilteredObject(int &x, int &y, Mat threshold, Mat &cameraFeed){ Mat temp; threshold.copyTo(temp); //vectores necesitados para la salida de " findContours" vector< vector<Point> > contours; vector<Vec4i> hierarchy; //Halla contornos de la imagen filtrada usando la funcion de openCV "findContours" findContours(temp,contours,hierarchy,CV_RETR_CCOMP,CV_CHAIN_APPROX_SIMPLE ); //para hallar nuestro objeto filtrado double refArea = 0; bool objectFound = false; if (hierarchy.size() > 0) { int numObjects = hierarchy.size(); //si el numero de objetos es mayor que MAX_NUM_OBJECTS tenemos mucho ruido if(numObjects<MAX_NUM_OBJECTS){ for (int index = 0; index >= 0; index = hierarchy[index][0]) { Moments moment = moments((cv::Mat)contours[index]); double area = moment.m00; //si el area es menor que 20 x20 px es probable que sea ruido //si el area es igual que 3/2 del tamaño de la imagen, probablemente sea mal filtrado //nosotros queremos el objeto con mayor area asi que nos aseguramos un area de referencia //que interactua y se compara con el area de la proxima iteracion if(area>MIN_OBJECT_AREA && area<MAX_OBJECT_AREA && area>refArea){ x = moment.m10/area; y = moment.m01/area; objectFound = true; refArea = area; }else objectFound = false; 19 Técnicas digitales III –Problema de ingeniería- } //dejo saber al usuario que se encontro el objeto putText(cameraFeed,"cantidad de objetos ="+intToString(cont),Point(10,450),1,1,Scalar(0,0,255),2); line(cameraFeed,Point(FRAME_WIDTH/2,0),Point(FRAME_WIDTH/2,480),Scalar(0,255,0),2); if(objectFound == true){ putText(cameraFeed,"objeto trackeado",Point(0,50),2,1,Scalar(0,255,0),2); //dibujo ubicacion de objeto en pantalla drawObject(x,y,cameraFeed);} }else putText(cameraFeed,"MUCHO RUIDO...AJUSTE EL FILTRO",Point(0,50),1,2,Scalar(0,0,255),2); } } int main(int argc, char* argv[]) { //variables buleanas para diferentes usos bool trackObjects = true; bool useMorphOps = true; //Matriz para guardar cada imagen que proviene de la webcam Mat cameraFeed; //Matriz para guardar imagen HSV Mat HSV; //Matriz para guardar imagen threshold Mat threshold; //coordenadas x e y para ubicacion de objeto int x=0, y=0; //crea barras deslizantes para filtraje HSV createTrackbars(); //objeto de captura de video, para la alimentacion de webcam VideoCapture capture; //abrir el objeto de captura en ubicacion 0 (ubicacion por default de webcam) capture.open(0); //setea ancho y alto de la trama de captura capture.set(CV_CAP_PROP_FRAME_WIDTH,FRAME_WIDTH); capture.set(CV_CAP_PROP_FRAME_HEIGHT,FRAME_HEIGHT); //lazo infinito donde la alimentacion de webcam se copia a la matriz cameraFeed //all of our operations will be performed within this loop while(1){ //guarda imagen en la matriz capture.read(cameraFeed); //convierte la trama de BGR a HSV cvtColor(cameraFeed,HSV,COLOR_BGR2HSV); //filtrado de la imagen HSV entre los valores y guarda la imagen filtrada en la matriz threshold inRange(HSV,Scalar(H_MIN,S_MIN,V_MIN),Scalar(H_MAX,S_MAX,V_MAX),threshold); //realiza operaciones morfologicas sobre la imagen filtradapara eliminar ruido y enfatizar el objeto filtrado if(useMorphOps) morphOps(threshold); //pasa la trama filtrada a nuestra funcion de seguimiento de objetos //esta funcion retornara las coordenadas x e y de nuestro objeto trackeado if(trackObjects) trackFilteredObject(x,y,threshold,cameraFeed); //displayar pantallas 20 Técnicas digitales III –Problema de ingenieríaimshow(windowName2,threshold); imshow(windowName,cameraFeed); imshow(windowName1,HSV); waitKey(30); } return 0; } Captura de pantalla de nuestro proyecto funcionando: 21 Técnicas digitales III –Problema de ingeniería- 10.Conclusión: Con éstas funciones de OpenCV y muchas mas (existen miles disponibles), mas las creadas por el usuario, podemos trabajar la imagen de video original, y así implementar sistemas de reconocimiento de figuras o cuerpos, de distintos maneras, por color, forma, etc. Esto lo aplicamos en control de tránsito, tele vigilancia, producción industrial, robótica,etc. La selección de hardware de la plataforma permite uno o más configuraciones, como ser velocidad en cuadros por segundo de cámaras, pc utilizada y demás, que serán elegidas de acuerdo a las prestaciones que se requieran y su presupuesto. Con éste trabajo se pretendió incursionar en el ámbito de digitalización y procesamiento de imagen en tiempo real, lo cual tiene gran auge y aplicaciones. Anexos: 1) Video de ensayos de nuestro sistema, montado en una maqueta, simulando la planta de envasado (ver archivo en DVD provisto) 2) Algunas consideraciones prácticas de iluminación y alarmas. 3) Instalación y configuración del software 22 Técnicas digitales III –Problema de ingeniería- Anexo 2: Algunas consideraciones prácticas de iluminación y alarmas El ambiente de la línea de producción debe ser tal que nuestro sistema se encuentre en un ambiente preferentemente cerrado con una iluminación dedicada y constante, para poder lograr un preciso filtrado del objeto, y seguimiento del mismo. La falla de iluminación puede producir errores en la medición, por esto, además de construir un ambiente propicio, en nuestro sistema pueden adicionarse funciones de alarmas. Se pueden programar múltiples alarmas, por parada de producción y falencias en la línea de producción, iluminación, etc generando un registro histórico y señales en la pantalla del panel de control. Un cartel de aviso en el sistema, lo programamos en la línea de código: putText(cameraFeed,"MUCHO RUIDO...AJUSTE EL FILTRO",Point(0,50),1,2,Scalar(0,0,255),2); 23 Técnicas digitales III –Problema de ingeniería- Anexo 3: Instalación y configuración del software Instalar OpenCV 2.4.9 en Windows 7/x86/x64 Procedimiento: 1.- Descargar OpenCV 2.4.9 desde el siguiente link: https://sourceforge.net/projects/opencvlibrary/files/opencv-win/2.4.9/opencv-2.4.9.exe/download 2.- Dar doble clic en el ejecutable descargado y extraer OpenCV en el directorio raíz: “C:\” (ESTO ES IMPORTANTE) 3.- Después de terminada la extracción se creará una carpeta llamada “opencv” en “C:\” que contendrá las librerías de OpenCV 2.4.9. 24 Técnicas digitales III –Problema de ingeniería- 4.- Abrir el Panel de Control -> Sistema y seguridad -> Sistema 5.- En la parte izquierda dar clic en “Configuración avanzada del sistema”. 6.- Dar clic en “Variables de entorno”. Se abrirá una nueva ventana. 7.- Ubicar la variable “Path” en las “Variables del sistema” 8.- Dar clic en “Editar” 25 Técnicas digitales III –Problema de ingeniería- 9.- Las variables del entorno se separan por puntos y coma. Como se va agregar una nueva variable se debe situar al final de la cadena e ingresar “;”, después agregar la variable según se indica en el siguiente paso. 10.- Ingresar la dirección de donde se encuentren ubicadas las bibliotecas dinámicas según la versión: • para compilar en x86, Visual 2010 agregar: C:\opencv\build\x86\vc10\bin; • • • para compilar en x86, Visual 2012 agregar: C:\opencv\build\x86\vc11\bin; para compilar en x64, Visual 2010 agregar: C:\opencv\build\x64\vc10\bin; para compilar en x64, Visual 2012 agregar: C:\opencv\build\x64\vc11\bin; 11.- En nuestro caso utilizaremos el Visual Studio Express compilando en x64. 11.- Dar clic en aceptar en las ventanas abiertas y reiniciar la computadora. 26 Técnicas digitales III –Problema de ingeniería- Configurar un proyecto de OpenCV 2.4.9 en Visual Studio Express. Procedimiento: En los siguientes pasos se muestra como configurar un proyecto de Visual Studio Express con OpenCV 2.4.9. 1.- Abrir el Visual Studio Express y crear un nuevo proyecto de “Aplicación de Consola Win32”. Colocar nombre del proyecto. Aceptar. Figura 1.- Nueva aplicación de consola en Visual Studio Express 27 Técnicas digitales III –Problema de ingeniería- 2.- Teclear Alt + F7 para abrir las propiedades de proyecto (figura 2). Figura 2.- Menu -> Proyecto -> Propiedades del proyecto Tener en cuenta seleccionar “Debug Win32” (B) antes de seleccionar “proyecto” en el menú, debido a que puede desplegarse otra ventana con opciones diferentes o faltantes en la opción “propiedades”. Lo mismo es para el “Release Win 32” del pto 7. 28 Técnicas digitales III –Problema de ingeniería- 3.- En “Propiedades de configuración (Configuracion Propiedades)” -> “C/C++”, > “General” seleccionar “Directorios de inclusión adicionales (Additional Include Directories)” y escribir C:\opencv\build\include como se muestra en la figura 3. Figura 3.- Directorios de inclusión adicionales 29 Técnicas digitales III –Problema de ingeniería- 4.En “Propiedades de configuración” -> “Vinculador (Linker)” >“General”, seleccionar“Directorios de bibliotecas adicionales (Additional Library Directories)” y escribir C:\opencv\build\x64\vc10\lib si se desea compilar y se configuro en x64 o C:\opencv\build\x86\vc10\lib si fue en x86. Figura 4.- Directorios de bibliotecas adicionales x86 en Visual 2010 30 Técnicas digitales III –Problema de ingeniería- 5.-En “Propiedades de configuración” -> “Vinculador (Linker)” ->“Entrada (Input)”, seleccionar “Dependencias adicionales (Additional Dependencies)”. Seleccionar la flecha que apunta hacia abajo y después “<Editar…>” (figura 5). Figura 5.- Dependencias adicionales 6.- En la ventana que se abre escribir las siguientes bibliotecas: opencv_core249d.lib opencv_calib3d249d.lib opencv_imgproc249d.lib opencv_objdetect249d.lib opencv_highgui249d.lib opencv_contrib249d.lib opencv_ml249d.lib opencv_legacy249d.lib opencv_video249d.lib opencv_flann249d.lib opencv_features2d249d.lib 31 Técnicas digitales III –Problema de ingeniería- 7. -Dar clic en OK y cambiar la configuración de “Active(Debug)” a “Release” aceptando el mensaje que a continuación aparece (Figura 6). Figura 6.- Cambiar configuración de Active(Debug) a Release. Igual que en el punto 2 pero con “Release” 8.- Como en el paso 5 en “Propiedades de configuración” -> “Vinculador (Linker)” >“Entrada (Input)”, seleccionar “Dependencias adicionales (Additional Dependencies)”. Técnicas digitales III –Problema de ingeniería- Seleccionar la flecha que apunta hacia abajo y después “<Editar…>” y agregar las siguientes bibliotecas: opencv_core249.lib opencv_imgproc249.lib opencv_highgui249.lib opencv_ml249.lib opencv_video249.lib opencv_features2d249.lib opencv_calib3d249.lib opencv_objdetect249.lib opencv_contrib249.lib opencv_legacy249.lib opencv_flann249.lib 9.- Dar clic en OK y después Aceptar. 10.- Escribir el siguiente ejemplo para cargar y mostrar una imagen con OpenCV: #include "stdafx.h" #include "opencv2/opencv.hpp" int main() { IplImage* img = cvLoadImage("C:/Tulum.jpg",1 cvWaitKey(); return 0; } 33 cvShowImage("Tulum",img); Técnicas digitales III –Problema de ingeniería- Crear programa C++ 1.- En la pestaña de “explorador de soluciones”, en “archivos de código fuente” apretamos botón derecho del mouse, “agregar” y luego según corresponda “nuevo elemento” o “elemento ya existente”4 34 Técnicas digitales III –Problema de ingeniería- 2.- Nótese que: 3.- En la pestaña de “administrador de propiedades”, sobre “debug Win32”, botón derecho del mouse, “agregar hoja4” 35 Técnicas digitales III –Problema de ingeniería- 4.- Buscar en tu PC el Archivo (anexado en el cd): 5.- En la misma pestaña del punto 2 elegir ahora “Release Win32”, botón derecho del mouse, “agregar hoja4” 6.- Buscar en tu PC el Archivo (anexado en el cd): 36 Técnicas digitales III –Problema de ingeniería- Listo, ya está todo listo para programar y simular. NOTA: Todo esto llevo tiempo de investigación, puesto que casi en ningún sitio aclara todos los pasos anteriormente nombrados. Al igual que la necesidad de los dos archivos “OPENCV_DEBUG” Y “OPENCV_RELEASE”, los cuales fueron una de las principales causas de retraso al proyecto. Ambos archivos son adjuntados en el CD. NOTA2: Con respecto a la instalación del Visual Studio Express, es normal como cualquier otro programa por lo cual no vimos la necesidad de explicarlo. 37