Sei sulla pagina 1di 39

Instalar opencv para java

Tambin podemos crear proyectos opencv con java y el IDE de nuestra preferencia, en nuestro
caso usaremos Netbeans 7.2, la configuracin de los proyectos es muy sencilla:

Creamos un proyecto java tipo java application.



Una vez tenemos el proyecto creado, debemos agregar los archivos jar que contienen las
libreras opencv, la podemos encontrar en el directorio de instalacin C:\opencv\build\java
con el nombre de opencv-246.jar, el numero 246 puede variar segn la versin de opencv.

Para agregar la librera hacemos lo siguiente:



Buscamos la librera opencv-246.jar



Por ultimo debemos agregar la dll opencv_java246.dll que se encuentra en la carpeta x86 para
plataformas de 32 bits o x64 para 64 bits. Lo ms sencillo que podemos hacer es copiar la dll y
pegarla en el directorio raz de nuestro proyecto.

1 2 3 4 5 6 7 8 9 10 11 12
13 14
package opencv;

import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;

public class Opencv {
public static void main(String[] args) {

System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
System.out.println("Opencv-" +
Core.VERSION);
Mat m = Mat.eye(3, 3, CvType.CV_8UC1);
System.out.println("m = " + m.dump());
}
}
view raw opencv.java hosted with by GitHub
Si todo esta correcto podremos ejecutar este cdigo.
Introduccin a OpenCV
Una vez hemos instalado opencv podemos comenzar a crear nuestra primera aplicacin, en
opencv una librera de computacin visual trabajaremos la mayora del tiempo con imgenes y
videos por lo cual lo primero que veremos ser como mostrar imgenes 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 tamao automtico o ajustable
namedWindow( "ventana", CV_WINDOW_AUTOSIZE);

//Espera a que se presione una tecla
waitKey(0);

//destruye la ventana
destroyWindow( "ventana" );

}

Con este cdigo creamos una ventana vaca. 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" );

}


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.



Mostrar un video en OpenCV

Para reproducir un video se hace de forma similar a una imagen ya que un video no es ms que
una secuencia de imgenes, por lo que deberemos cargar las imgenes del video y mostrarla
una tras otras, veamos cmo se hace:

namedWindow( "ventana", CV_WINDOW_AUTOSIZE );

//cargar el archivo de video especificado
VideoCapture vc("video.mp4");

//verificar si se ha podio cargar el video
if(!vc.isOpened()) return -1;

//obtener los cuadros por segundo
double fps = vc.get(CV_CAP_PROP_FPS);

// calcular el tiempo de espera entre cada imagen a mostrar
int delay = 1000 / fps;

while (true)
{
Mat frame;

//cargar el primer cuadro o imagen del video en frame
vc >> frame;

imshow("ventana", frame);

//esperar un periodo de tiempo especificado por delay
//si se presiona la tecla 27 (ESC) salir del loop
if(waitKey(delay) == 27) break;
}

destroyWindow( "ventana" );

El archivo video.mp4 se reproducir, si deseamos reproducir otro video debemos indicar la
ruta completa.

vc >> frame esta lnea de cdigo carga cada cuadro del video dentro de frama para luego
mostrarlo, en cada iteracin del loop se avanza hacia el siguiente cuadro, este cdigo lo
pudimos haber escrito de esta forma: vc.read(frame);

if(waitKey(delay) == 27) break; la funcin waitKey(0) espera a indefinidamente a que se
presione una tecla, si indicamos un nmero mayor que cero ser el periodo de tiempo en ms
que esperara a que se presione una tecla, si en ese periodo no se ha presionado nada
continua.

Descarga Codigo C++ OpenCV - Proyecto Introduccin a OpenCV
Dibujar Formas y Texto
Opencv posee varias funciones con las que podemos crear figuras geomtricas o formas ms
complejas, dibujar textos sobre las imgenes, vamos a ver cules son estas funciones y cmo
usarlas en nuestros proyectos con opencv.

Lo primero que necesitamos es donde dibujar por lo que crearemos una imagen (Mat) vaca
sobre la cual representaremos nuestros dibujos, el siguiente cdigo 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: Scalar(azul, verde, rojo),
podemos usar el macro CV_RGB(rojo, verde, azul) si nos resulta ms cmodo.

Ahora podemos comenzar a dibujar, la primera funcin que veremos es circle la cual nos sirve
para dibujar un circulo, es muy sencilla veamos cmo se usa:

circle(img, Point(cols / 2, rows / 2), 250, Scalar(255,0,0), 3);

Para usar esta funcin 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 parmetros de esta
funcin pero son opcionales, en este caso el ultimo 3 indica el grosor de la lnea de dibujo.

Adems existen la funciones line, rectangle, entre otras cuyo uso es muy similar.

Otra funcin interesante de dibujo es la funcin 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 (FONT_HERSHEY_SIMPLEX,
FONT_HERSHEY_PLAIN, FONT_HERSHEY_DUPLEX, FONT_HERSHEY_COMPLEX,
FONT_HERSHEY_TRIPLEX, FONT_HERSHEY_COMPLEX_SMALL,
FONT_HERSHEY_SCRIPT_SIMPLEX, FONT_HERSHEY_SCRIPT_COMPLEX ), el tamao, color, y
grosor del texto.

putText(img, "OpenCV 2", Point(180,320), FONT_HERSHEY_SCRIPT_COMPLEX, 3,
CV_RGB(125,12,145), 2);


Podemos encontrar algunos ejemplos de como dibujar en opencv en la
carpeta: C:\Opencv\samples\cpp\tutorial_code\core\Matrix

Cdigo de ejmplo:

#include <opencv2\opencv.hpp>

using namespace cv;

void main()
{
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);
}



Procesamiento de imgenes en OpenCV
En opencv contamos con diferentes funciones que nos permiten procesar las imgenes, ya sea
cambiar una imagen a escala de grises o aplicarle otros algoritmos ms complicados como los
que veremos en seguida.

GaussianBlur
GaussianBlur(img, dst, Size(13,7), 8);

img: Imagen original.
dst: Matriz donde se almacenara la nueva imagen.
Size(width, height): Tamao del kernel, deben ser positivos e impares.
8: desviacin estndar en el eje X.


gaussianblur

MedianBlur
medianBlur(img, dst, 5);

5: ksize debe ser un valor mayor que 1 e impar.


medianblur

Erode
erode(img, dst, krl);



erode

Dilate
dilate(img, dst, krl);



dilate
Guardar una imagen

Una vez hemos procesado la imagen tal vez nos interese guardar en disco una copia de la
imagen procesada, opencv nos proporciona la funcin imwrite para almacenar una imagen en
un archivo indicado, disponemos de distintos formatos como JPG, PNG, TIFF.

vector<int> compression_params;
compression_params.push_back(CV_IMWRITE_PNG_COMPRESSION);
compression_params.push_back(9);

imwrite("alpha.png", dst, compression_params);





1 2 3 4
5 6 7 8
9 10 11
12 13
14 15
16 17
18 19
20 21
22 23
24 25
26 27
28 29
#include <opencv2\opencv.hpp>

using namespace cv;

int main()
{
Mat img = imread("imagen.jpg");
Mat dst, krl;

GaussianBlur(img, dst, Size(11,7), 1.5);
Canny(dst, dst, 0, 30, 3);
//blur(img, dst, Size(10,20));
//medianBlur(img, dst, 5);
//erode(img, dst, krl);
//dilate(img, dst, krl);

vector<int> compression_params;
compression_params.push_back(CV_IMWRITE_PNG_COMPRESSION);
compression_params.push_back(9);

imwrite("alpha.png", dst, compression_params);


imshow("Imagen Original", img);
imshow("Imagen Prosesada", dst);

waitKey(5000);
return 1;
}
view raw writeImage.cpp hosted with by GitHub
Tutorial opencv Trackbar y Mouse
Opencv nos provee con funciones para crear y manipular el trackbar as como tambin
funciones para manejar los eventos del mouse, el uso de estas funciones es fcil, en este
tutorial opencv aprenderemos como hacerlo.

Tutorial opencv crear un trackbar

Lo primero que debemos hacer es crear una ventana como ya aprendimos en los tutoriales
opencv anteriores. Para crear un trackbar basta con llamar a la funcin createTrackbar a la cual
hay que pasarle como parmetro el nombre del trackbar, el nombre de la ventana en donde
deseamos agregarlo, la direccin de memoria de la variable en donde almacenaremos el valor
actual del trackbar, el valor mximo, y la funcin que se ejecutara cada vez que cambie el calor
del trackbar.

createTrackbar( TrackbarName, "Linear Blend", &alpha_slider,
alpha_slider_max, on_trackbar );

Como ejemplo utilizaremos uno disponible en el tutoriales opencv, se muestra como aadir
mescla a dos imgenes el valor alfa es cambiado con el trackbar.

void on_trackbar( int, void* )
{
alpha = (double) alpha_slider/alpha_slider_max ;
beta = ( 1.0 - alpha );
addWeighted( src1, alpha, src2, beta, 0.0, dst);
imshow( "Linear Blend", dst );
}



Si necesitamos saber en qu posicin est el trackbar podemos llamar a la funcin
getTrackbarPos pasndole el nombre del trackbar y de la ventana, esta funcion nos devolver
un int que representa la posicin del trackbar.

Este cdigo se encuentra disponible en
C:\opencv\samples\cpp\tutorial_code\HighGUI\AddingImagesTrackbar.cpp

Debemos recordar cambiar la ruta de las imgenes para que el proyecto se pueda ejecutar.


Tutorial opencv Mouse

Para controlar los eventos que produce el mouse contamos con la funcin setMouseCallback al
cual le debemos pasar como parmetro el nombre de la ventana que deseamos usar, y la
funcin que controlara los eventos, en este tutorial opencv veremos cmo usar esta funcin.

setMouseCallback( "Uso del raton", onMouse);


La funcin onMouse debe tener el siguiente formato, donde event representa el evento
ocurrido y los enteros x, y las coordenadas donde se encuentra el mouse.

static void onMouse( int event, int x, int y, int, void* )
{
switch (event)
{
case CV_EVENT_MOUSEMOVE: break;
case CV_EVENT_LBUTTONDOWN : break;
case CV_EVENT_RBUTTONDOWN : break;
case CV_EVENT_MBUTTONDOWN : break;
case CV_EVENT_LBUTTONUP : break;
case CV_EVENT_RBUTTONUP : break;
case CV_EVENT_MBUTTONUP : break;
case CV_EVENT_LBUTTONDBLCLK : break;
case CV_EVENT_RBUTTONDBLCLK : break;
case CV_EVENT_MBUTTONDBLCLK : break;
}
}

Estos son los diferentes eventos que produce el mouse, por lo general hacen lo que dice su
nombre y si queremos podemos probar a ver cundo se produce cada uno de ellos, por
ejemplo si quisiramos saber cundo se mueve el ratn usaramos CV_EVENT_MOUSEMOSE, x
, y seran las coordenadas a las que se movi.


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
16 17 18 19 20 21 22 23 24 25 26
27 28 29 30 31 32 33 34 35 36 37
#include <opencv2\opencv.hpp>

using namespace cv;
using namespace std;

static void onMouse( int event, int x, int
y, int, void* )
{
string msg = "mouse - movido: X = " +
to_string(x) + " Y = " + to_string(y);
Mat img(200, 650, CV_8UC3);

switch (event)
{
case CV_EVENT_MOUSEMOVE:
putText(img, msg,
Point(10,100), 4, 1, CV_RGB(0,255,0), 0,
CV_AA );
imshow("Uso del raton",
img);
break;
case CV_EVENT_LBUTTONDOWN :
break;
case CV_EVENT_RBUTTONDOWN :
break;
case CV_EVENT_MBUTTONDOWN :
break;
case CV_EVENT_LBUTTONUP :
break;
case CV_EVENT_RBUTTONUP :
break;
case CV_EVENT_MBUTTONUP :
break;
case CV_EVENT_LBUTTONDBLCLK :
break;
case CV_EVENT_RBUTTONDBLCLK :
break;
case CV_EVENT_MBUTTONDBLCLK :
break;
}

}

int main( int argc, char** argv )
{
namedWindow( "Uso del raton", 0 );
setMouseCallback( "Uso del raton",
onMouse);
waitKey();

return 0;
}
view raw mouse.cpp hosted with by GitHub

Acceso a la webcam con opencv
Con opencv podemos acceder a la cmara web que tengamos instalada en el computador,
tambin podremos procesar estas imgenes capturadas por la webcam mediante opencv y por
su puesto grabar videos de la cmara.

Webcam desde opencv

Para acceder a la webcam lo hacemos de manera parecida a como mostramos un video solo
que en lugar de especificar un archivo de video a la clase VideoCapture indicaremos el nmero
de dispositivo que deseamos usar cero si tenemos solo una cmara.

Cdigo C++:

#include <opencv2\opencv.hpp>

using namespace cv;

int main()
{
VideoCapture cap(0);

if(!cap.isOpened())
return -1;

namedWindow("webcam");

for(;;)
{
Mat frame;
cap >> frame;
imshow("webcam", frame);
if(waitKey(50) >= 0) break;
}

return 0;
}

Cdigo Python:

from cv2 import *

namedWindow("webcam")
vc = VideoCapture(0);

while True:
next, frame = vc.read()
imshow("webcam", frame)
if waitKey(50) >= 0:
break;

Si deseamos procesar cada uno de los cuadros del video capturado podemos hacerlo del
mismo modo como lo hicimos de un video pregrabado, veamos un ejemplo:

Cdigo C++:

for(;;)
{
Mat frame, edges;
cap >> frame;

cvtColor(frame, edges, CV_BGR2GRAY);
GaussianBlur(edges, edges, Size(7,7), 1.5, 1.5);
Canny(edges, edges, 0, 30, 3);

imshow("webcam", edges);
if(waitKey(50) >= 0) break;
}

Cdigo Python:

while True:
next, frame = vc.read()

gray = cvtColor(frame, COLOR_BGR2GRAY)
gauss = GaussianBlur(gray, (7,7), 1.5, 1.5)
can = Canny(gauss, 0, 30, 3)

imshow("webcam", can)
if waitKey(50) >= 0:
break;

Almacenar video en disco

Si deseamos grabar el video proveniente de la webcam en disco, podemos hacerlo mediante la
clase VideoWriter, en el constructor o el mtodo open debemos indicar el nombre con que
deseamos guardar el archivo con extensin, el cdec que usaremos, los cuadros por segundo y
la resolucin del video.

VideoWriter wtr("webcam.avi", CV_FOURCC('M','J','P','G'), 30, Size(640,480));
CV_FOURCC(P,I,M,1) para codec MPEG-1 codec.
CV_FOURCC(M,J,P,G) para cdec motion-jpeg.

Existen ms cdec puedes verlos aqu: http://www.fourcc.org/codecs.php
Para finalizar solo nos falta escribir cada cuadro, lo podemos hacer de dos modos:

wtr.write(dest);
wtr << dest;


1 2 3 4 5 6 7 8 9 10 11 12 13 14
15 16 17 18 19 20 21 22 23 24
25 26 27 28 29 30 31 32 33 34
35
#include <opencv2\opencv.hpp>

using namespace cv;

int main()
{
VideoCapture cap(0);
VideoWriter wtr("webcam.avi",
CV_FOURCC('P','I','M','1'), 20, Size(640,480));

if(!cap.isOpened() || !wtr.isOpened())
return -1;

namedWindow("webcam");

for(;;)
{
Mat frame, edges, dest;
cap >> frame;

cvtColor(frame, edges,
CV_BGR2GRAY);
GaussianBlur(edges, edges,
Size(7,7), 1.5, 1.5);
Canny(edges, edges, 0, 30, 3);

cvtColor(edges, dest,
CV_GRAY2BGR);

wtr << dest;

imshow("webcam", edges);
if(waitKey(50) >= 0) break;
}

wtr.release();

return 0;
}
view raw saveWebcamVideo.cpp hosted with by GitHub
OpenCV Detectar Lneas
Las funciones de OpenCV HoughLines y HoughLinesP son usadas para
detectar lneas en una imagen, ambas funciones usan el mtodo HoughTransform usado
para buscar lneas, crculos y otras formas bsicas.


Para la deteccin de lneas usamos dos mtodos:
El mtodo estndar HougLines Standard Hough Line Transform.
El mtodo probabilstico es ms eficiente HougLinesP Probabilistic Line
Transform.
Antes de usar alguna de estas funciones primero aplicaremos dos funciones a la imagen,
Canny para detectar los bordes de la imagen y cvtColor para cambiar la imagen de
escala de grises a BGR y poder mostrar los resultados.
1 Canny(src, dst, 50, 200, 3);
2 cvtColor(dst, cdst, CV_GRAY2BGR);
Aplicar el mtodo HoughLines con los parmetros indicados, de las lnea # 3 a 13 se
dibujan la lneas encontradas:
dst: proporcionado por Canny.
lines: almacena las lineas detectadas.
rho : usaremos 1 pixel.
theta: usaremos 1 grado (CV_PI/180).
threshold: numero mnimo de lneas a detectar.
srn and stn: zero por defecto.
1 vector<Vec2f> lines;
2 HoughLines(dst, lines, 1, CV_PI/180, 200, 0, 0 );
3 for ( size_t i = 0; i < lines.size(); i++ ) {
4 float rho = lines[i][0], theta = lines[i][1];
5 Point pt1, pt2;
6 double a = cos(theta), b = sin(theta);
7 double x0 = a*rho, y0 = b*rho;
8 pt1.x = cvRound(x0 + 1000*(-b));
9 pt1.y = cvRound(y0 + 1000*(a));
10 pt2.x = cvRound(x0 - 1000*(-b));
11 pt2.y = cvRound(y0 - 1000*(a));
12 line( cdst, pt1, pt2, Scalar(0,0,255), 3, CV_AA);
13 }

Para aplicar el mtodo HoughLinesP se hace de manera similar solo cambian algunos
parmetros y la manera como devuelve las lineas:
dst: proporcionado por Canny.
lines: almacena las lineas detectadas.
rho : usaremos 1 pixel.
theta: usaremos 1 grado (CV_PI/180).
threshold: numero mnimo de lneas a detectar.
minLinLength: mnimo de puntos que forman una lnea.
1 vector<Vec4i> lines;
2 HoughLinesP(dst, lines, 1, CV_PI/180, 50, 50, 10 );
3 for ( size_t i = 0; i < lines.size(); i++ ) {
4 Vec4i l = lines[i];
5 line( cdst, Point(l[0], l[1]),
6 Point(l[2], l[3]), Scalar(0,0,255),
7 3, CV_AA);
8 }



OpenCV Detectar Crculos
Del mismo modo como detectamos las lneas en una imagen opencv cuenta
con funciones para detectar los crculos HoughCircles, en este caso la funcin nos devolver el
punto central del circulo (x,y) y el radio del mismo r.


Con el siguiente cdigo lo que hacemos es convertir la imagen a escala de grises y luego aplicar
GaussianBlur para reducir la deteccin de crculos no existentes.
1 cvtColor(img, gray, CV_BGR2GRAY);
2 GaussianBlur( gray, gray, Size(9, 9), 2, 2 );
Aplicamos el mtodo Houg Circle Transform con los siguiente parmetros, donde el primero es
la imagen a analizar y el segundo es donde se almacenaran los datos de los crculos
encontrados, gary.rows / 2 indica la distancia mnima entre los centros.
1 vector<Vec3f> circles;
2 HoughCircles(gray, circles, CV_HOUGH_GRADIENT,
3 2, gray.rows/2, 200, 100 );
Por ultimo dibujamos los crculos que encontramos en la imagen
1 for ( size_t i = 0; i < circles.size(); i++ ) {
2 Point center(cvRound(circles[i][0]),
3 cvRound(circles[i][1]));
4 int radius = cvRound(circles[i][2]);
5
6 circle( img, center, 3, Scalar(0,255,0), 3);
7 circle( img, center, radius, Scalar(0,0,255), 3);
8 }



En rojo se muestra el rea circular encontrada y en verde el centro del circulo.
Deteccin de rostros
Opencv nos facilita la terea de detectar rostros pues ya cuenta con clasificadores
entrenados para esta tarea almacenados en archivos xml, pero en caso de que lo
necesitemos podemos crear nuestros propios clasificadores, adems de contar con todas
las funciones necesarias para esta tarea.

Deteccin de rostros en opencv

Para detectar un rostro primero debemos procesar la imagen en la cual deseamos buscar
un rostro, luego de cargar la imagen debemos aplicar los siguientes pasos:

Convertir la imagen a escala de grises, necesario para el correcto funcionamiento de los
algoritmos de deteccin de rostros usados por opencv. Para convertir una imagen a
escala de grises u otro formato contamos con la funcin cvtColor.

cvtColor(imagen, imagen, CV_BGR2GRAY);


Lo siguiente que debemos hacer es aplicar ecualizacin de histograma a la imagen en
grises para estandarizar el contraste y brillo de la imagen, esto para que distintas
condiciones de iluminacin no afecten la deteccin del rosto en la imagen.

equalizeHist(imagen, imagen);


Con esto tendremos este resultado:



Para aumentar la velocidad de deteccin del algoritmo podemos escalar la imagen a un
tamao ms pequeo no demasiado.

Con la imagen procesada ahora debemos cargar el detector que deseamos utilizar,
pasaremos el nombre del clasificador al mtodo load de la clase CascadeClassifier, los
archivos .xml que debemos cargar se encuentran en C:\Opencv\data aqu encontraremos
varias carpetas que contienes distintos clasificadores, en la carpeta
C:\Opencv\data\haarcascades se encuentran varios clasificadores no solo para detectar
rostros sino tambin para la deteccin de ojos, boca, nariz, entre otros.

Para detectar rostros de frente usaremos haarcascade_frontalface_alt.xml, para detectar
cuerpo completo podemos usar haarcascade_fullbody.xml, para detectar ojos contamos
con haarcascade_eye.xml, existen muchos otros.

CascadeClassifier detector;

if(!detector.load("haarcascade_frontalface_alt.xml"))
cout << "No se puede abrir clasificador."<< endl;


Ahora podemos detectar los rostros presentes en la imagen

vector<Rect> rect;
detector.detectMultiScale(dest, rect);


Las caras detectadas sern almacenadas en el vector rect, solo debemos recorrerlo y
marcar las caras encontradas

for(Rect rc : rect)
{
rectangle(imagen,
Point(rc.x, rc.y),
Point(rc.x + rc.width, rc.y + rc.height),
CV_RGB(0,255,0), 2);
}




Cdigo C++Deteccin de Rostros:

1 2 3 4 5 6
7 8 9 10 11
12 13 14
15 16 17
18 19 20
21 22 23
24 25 26
27 28 29
30 31 32
33 34 35
36
#include <opencv2\opencv.hpp>

using namespace cv;
using namespace std;

int main()
{
Mat dest, gray;
Mat imagen = imread("lena.jpg");

CascadeClassifier detector;

if(!detector.load("haarcascade_frontalface_alt.xml"))
cout << "No se puede abrir clasificador." <<
endl;

cvtColor(imagen, gray, CV_BGR2GRAY);
equalizeHist(gray, dest);

vector<Rect> rect;
detector.detectMultiScale(dest, rect);

for(Rect rc : rect)
{
rectangle(imagen,
Point(rc.x, rc.y),
Point(rc.x + rc.width, rc.y +
rc.height),
CV_RGB(0,255,0), 2);
}

imshow("Imagen original", imagen);
imshow("Imagen en escala de grises", gray);
imshow("Imagen al aplicar ecualizacion de
histograma",dest);

waitKey(0);
return 1;
}
view raw FaceDetectImage.cpp hosted with by GitHub

Deteccin de rostros en tiempo real

Para detectar rostros en tiempo real solo debemos leer las imgenes de la webcam y
aplicarle a cada una de ellas el procedimiento descrito anteriormente, para ver cmo
usar la webcam.

Cdigo de ejemplo para detectar rostros en tiempo real mediante el uso de la cmara
web opencv.
Parmetros de la funcin de deteccin de rostros:

detectMultiScale(const Mat& image, vector<Rect>& objects, double scaleFactor=1.1, int
minNeighbors=3, int flags=0, Size minSize=Size(), Size maxSize=Size())
image: imagen prosesada.
objectcs: vector donde se almacenara las coordenadas de las caras encontradas.
scaleFactor: factor de escala, 1.2 ms rpido.
minNeighbors: factor para prevenir falsas detecciones.
flags: parmetro actualmente no es usado, indicar 0.
minSize, maxSize: tamao mximo y mnimo de ventana usado para detectar
rostros, limita la deteccin de rostros muy pequeo o demasiado grandes.
1 2 3 4 5 6
7 8 9 10 11
12 13 14
15 16 17
18 19 20
21 22 23
24 25 26
27 28 29
30 31 32
33 34 35
36 37 38
39 40 41
42 43
#include <opencv2\opencv.hpp>

using namespace cv;
using namespace std;

int main()
{
VideoCapture cap;
CascadeClassifier detector;

if(!detector.load("haarcascade_frontalface_alt.xml"))
cout << "No se puede abrir clasificador." <<
endl;

if(!cap.open(0))
cout << "No se puede acceder a la webcam." <<
endl;

while(true)
{
Mat dest, gray, imagen;

cap >> imagen;

cvtColor(imagen, gray, CV_BGR2GRAY);
equalizeHist(gray, dest);

vector<Rect> rect;
detector.detectMultiScale(dest, rect, 1.2, 3,
0, Size(60,60));

for(Rect rc : rect)
{
rectangle(imagen,
Point(rc.x, rc.y),
Point(rc.x + rc.width, rc.y +
rc.height),
CV_RGB(0,255,0), 2);
}

imshow("Deteccion de rostros", imagen);

if(waitKey(1) >= 0) break;
}

return 1;
}
view raw FaceDetectWebcam.cpp hosted with by GitHub

Espero les sirva de ayuda, ms adelante veremos como reconocer o identificar un rostro,
hasta la prxima.

Detector de ojos
Una vez hemos detectado un rostro con opencv quizs nos interesa la deteccin de ojos,
opencv cuenta con clasificadores en cascada entrenados para la deteccin de ojos, podemos
detectar los ojos cerrados o abiertos.

Clasificadores para detectar ojos abiertos o cerrados:
haarcascade_mcs_lefteye.xml, haarcascade_mcs_righteye.xml
haarcascade_lefteye_2splits.xml, haarcascade_righteye_2splits.xml

Clasificadores que detectan ojos abiertos:
haarcascade_eye.xml
haarcascade_eye_tree_eyeglasses.xml

Para que la deteccin de ojos funcione correctamente debemos definir una regin de
bsqueda que no es ms que una porcin de la imagen donde deseamos detectar el ojo, si ya
tenemos la regin que contiene el rostro (mira deteccin de rostros) podemos usar estos
valores para determinar la regin correspondiente para cada clasificador:

Clasificador EYE_SX EYE_SY EYE_SW EYE_SH
haarcascade_eye.xml 0.16 0.26 0.30 0.28
haarcascade_mcs_lefteye.xml 0.10 0.19 0.40 0.36
haarcascade_lefteye_2splits.xml 0.12 0.17 0.37 0.36

Veamos como extraer los rectngulos que contienen la regin para los ojos izquierdo y
derecho, ya que debemos usar un detector diferente para el ojo izquierdo y derecho, este
cdigo extrae las regiones para ambos ojos:

int leftX = cvRound(face.cols * EYE_SX);
int topY = cvRound(face.rows * EYE_SY);
int widthX = cvRound(face.cols * EYE_SW);
int heightY = cvRound(face.rows * EYE_SH);
int rightX = cvRound(face.cols * (1.0-EYE_SX-EYE_SW));

Mat topLeftOfFace = faceImg(Rect(leftX, topY, widthX,heightY));
Mat topRightOfFace = faceImg(Rect(rightX, topY,
widthX,heightY));
1
2
3
4
5
6
7
8
9
1
0
1
1
1
2
1
#include <opencv2\opencv.hpp>

using namespace cv;
using namespace std;

int main()
{
float EYE_SX = 0.16f;
float EYE_SY = 0.26f;
float EYE_SW = 0.30f;
float EYE_SH = 0.28f;

Mat dest, gray;
Mat imagen = imread("images.jpg");

CascadeClassifier detector, eyes_detector;

if(!detector.load("haarcascade_frontalface_alt2.xml"))
cout << "No se puede abrir clasificador." << endl;

if(!eyes_detector.load("haarcascade_eye_tree_eyeglasses.xml")
)
cout << "No se puede abrir clasificador para los
3
1
4
1
5
1
6
1
7
1
8
1
9
2
0
2
1
2
2
2
3
2
4
2
5
2
6
2
7
2
8
2
9
3
0
3
1
3
2
3
3
3
4
3
5
ojos." << endl;

cvtColor(imagen, gray, CV_BGR2GRAY);
equalizeHist(gray, dest);

vector<Rect> rect;
detector.detectMultiScale(dest, rect);

for(Rect rc : rect)
{
rectangle(imagen,
Point(rc.x, rc.y),
Point(rc.x + rc.width, rc.y + rc.height),
CV_RGB(0,255,0), 2);
}

if(rect.size() > 0)
{
Mat face = dest(rect[0]).clone();
vector<Rect> leftEye, rightEye;

int leftX = cvRound(face.cols * EYE_SX);
int topY = cvRound(face.rows * EYE_SY);
int widthX = cvRound(face.cols * EYE_SW);
int heightY = cvRound(face.rows * EYE_SH);
int rightX = cvRound(face.cols * (1.0-EYE_SX-
EYE_SW));

Mat topLeftOfFace = face(Rect(leftX, topY, widthX,
heightY));
Mat topRightOfFace = face(Rect(rightX, topY, widthX,
heightY));

eyes_detector.detectMultiScale(topLeftOfFace,
leftEye);
eyes_detector.detectMultiScale(topRightOfFace,
rightEye);

if((int)leftEye.size() > 0)
{
rectangle(imagen,
Point(leftEye[0].x + leftX +
rect[0].x, leftEye[0].y + topY + rect[0].y),
Point(leftEye[0].width + widthX +
rect[0].x - 5, leftEye[0].height + heightY + rect[0].y),
CV_RGB(0,255,255), 2);
}

if((int)rightEye.size() > 0)
{
rectangle(imagen,
Point(rightEye[0].x + rightX + leftX +
rect[0].x, rightEye[0].y + topY + rect[0].y),
Point(rightEye[0].width + widthX +
rect[0].x + 5, rightEye[0].height + heightY + rect[0].y),
CV_RGB(0,255,255), 2);
}
}

imshow("Ojos", imagen);

3
6
3
7
3
8
3
9
4
0
4
1
4
2
4
3
4
4
4
5
4
6
4
7
4
8
4
9
5
0
5
1
5
2
5
3
5
4
5
5
5
6
5
7
5
waitKey(0);
return 1;
}
8
5
9
6
0
6
1
6
2
6
3
6
4
6
5
6
6
6
7
6
8
6
9
7
0
7
1
7
2
7
3
7
4
7
5
7
6
view raw DetectorOjos.cpp hosted with by GitHub


Proyecto opencv en qt
Luego de haber configurado nuestro proyecto qt para usar las libreras de opencv, vamos
desde luego a aprender cmo crear una aplicacin sencilla en la que crearemos una ventana,
abriremos una imagen la procesaremos y mostraremos la imagen original ms la procesada.

En este punto ya debemos tener configurado nuestro proyecto si no lo has hecho mira cmo
hacerlo aqu.

En la carpeta Form veremos el archivo mainwindow.ui, le damos doble clic para editarlo con el
diseador de qt.

Lo primero que haremos ser cambiar el tamao de la ventana, para ello seleccionamos la
ventana y en el panel de propiedades ubicamos la propiedad geometry y establecemos sus
valores de esta manera:



Lo siguiente que haremos ser agregar un botn al que llamaremos abrir y dos etiquetas a las
que llamaremos original y nueva.



Para cambiar el nombre de los objetos que acabamos de agregar hacemos clic derecho
Change objectName y cambiamos los nombres a los mencionados anteriormente, tambin
podemos cambiar el nombre que muestra el objeto haciendo clic derecho Change text para
el botn y Change plain text para las etiquetas, hacemos las modificaciones necesarias para
que quede de este modo:



Con esto tendremos preparada nuestra interfaz grfica de usuario, ahora para darle
funcionalidad haremos que al darle clic al botn abra un cuadro para buscar una imagen, para
hacer esto hacemos clic derecho sobre el botn Go to slot y seleccionamos clicked().



Esta accin nos creara una funcin llamada on_abrir_clicked en el archivo mainwindow.cpp
que se ejecutara cada vez que hagamos clic en el botn.

La primera funcionalidad que demos programas es la de abrir un cuadro de dialogo para
buscar una imagen en nuestro sistema de archivo. El siguiente cdigo hace este trabajo
debemos agregar #include <QFileDialog> para que funcione.


QString fileName = QFileDialog::getOpenFileName(this,
tr("Open Image"), ".",
tr("Image Files (*.png *.jpg *.jpeg
*.bmp)"));

Lo siguiente que debemos hacer es convertir la matriz (Mat) que contiene nuestra imagen a la
clase QImage, luego el objeto QImage lo usaremos para obtener un QPixmap que le
asignaremos a la etiqueta donde mostraremos la imagen, este es un ejemplo del cdigo:

const uchar *qImage2 = (const uchar*)org.data;
QImage img2(qImage2, org.cols, org.rows, org.step, QImage::Format_RGB888);
ui->original->setPixmap(QPixmap::fromImage(img2.rgbSwapped()));

Adems debemos agregar los archivo de inclusin requeridos por opencv, el siguiente
fragmento de cdigo abre la imgenes con opencv la procesa y la muestra en las etiquetas que
ya hemos creado.

Este es el cdigo completo de la funcin on_abrir_clicked:

void MainWindow::on_abrir_clicked()
{
QString fileName = QFileDialog::getOpenFileName(this,
tr("Open Image"), ".",
tr("Image Files (*.png *.jpg *.jpeg
*.bmp)"));
Mat mat = imread(fileName.toStdString());

if(!mat.empty())
{
QSize sz = ui->original->frameSize();
cv::resize(mat, mat, Size(sz.width(), sz.height()));

Mat org = mat.clone();

GaussianBlur(mat, mat, Size(11,7), 1.5);
Canny(mat, mat, 0, 30, 3);

const uchar *qImage1 = (const uchar*)mat.data;
const uchar *qImage2 = (const uchar*)org.data;

QImage img1(qImage1, mat.cols, mat.rows, mat.step, QImage::Format_Indexed8);
QImage img2(qImage2, org.cols, org.rows, org.step, QImage::Format_RGB888);

ui->nueva->setPixmap(QPixmap::fromImage(img1.rgbSwapped()));
ui->original->setPixmap(QPixmap::fromImage(img2.rgbSwapped()));
}
else
std::cout << "No se ha cargado - " << fileName.toStdString() << std::endl;
}

Debemos recordar agregar los namespace para opencv y los include necesarios ms
informacin, si por algn motivo al ejecutar nuestra aplicacin nos da error podemos probar
borrando la carpeta build del proyecto para iniciar la construccin desde cero.


Opencv en Qt5
Qt5 es un framework multiplataforma con que podemos crear aplicaciones de todo tipo con
C++, usando el IDE qtcreator podemos configurar nuestros proyectos para crear aplicaciones
con opencv, vamos a ver cmo crear proyectos opencv con qt5 y el compilador msvc2012.

Creacin de un proyecto opencv con qt

Lo primero que debo decir es que los configuraciones que haremos solo son vlidas para la
versin qt para Windows y el compilador VS 2012. Podemos descargar qt aqu.

Una vez hayamos descargado e instalado qt5 procedemos a crear un proyecto de interfaz
grfica de usuario Qt GUI Application.











Con esto hemos creado un proyecto llamado opencvAndQt el cual contiene varios archivos, el
primer archivo que debemos modificar es el que tiene la extensin .pro que es el archivo de
configuracin del proyecto.

Para poder usar las libreras opencv que previamente ya instalamos (instalacin de opencv),
debemos agregarlas a nuestro proyecto qt, para hacerlo abrimos el archivo opencvAndQt.pro y
agregamos el siguiente cdigo:

INCLUDEPATH += C:/opencv/build/include

La primera lnea indica donde se encuentran los archivos de inclusin si instalamos opencv en
la carpeta C: la ruta ser c:/opencv/build/include.

win32:CONFIG(release, debug|release): LIBS += -LC:/opencv/build/x86/vc11/lib/ -
lopencv_core246
else:win32:CONFIG(debug, debug|release): LIBS += -LC:/opencv/build/x86/vc11/lib/ -
lopencv_core246d

Las siguientes lneas indican donde se encuentran las libreras .lib las cuales se encuentran
dentro de la carpeta build, x86 o x64 segn sea necesario y vc11 para el compilador msvc-
2012.
En la carpeta C:/opencv/build/x86/vc11/lib encontraremos varias libreras por lo que debemos
agregar este cdigo por cada librera que deseemos utilizar.



Con esto ya podremos crear un proyecto opencv, en el siguiente post veremos cmo crear una
aplicacin sencilla que abra una imgen la procese con opencv y la muestre en una ventana
creada con qt.

Potrebbero piacerti anche