Sie sind auf Seite 1von 22

CS 188x: Inteligencia

Artificial
Deteccin de Objetos

Deteccin de Lneas y Bordes


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.

Deteccin de Lneas y Bordes


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.
// detectar bordes
Canny(src, dst, 50, 200, 3);
//conversin de color
cvtColor(dst, cdst, CV_GRAY2BGR);

Deteccin de Lneas y Bordes


El mtodo HoughLines con los parmetros comentados
vector<Vec2f> lines;

// lines: almacenara las lneas detectadas.

HoughLines(dst, lines, 1, CV_PI/180, 200, 0, 0 );

// dst: proporcionado por Canny,


// usaremos 1 pixel, 1 grado (CV_PI/180),
//threshold: numero mnimo de lneas a detectar,

for ( size_t i = 0; i < lines.size(); i++ ) {


float rho = lines[i][0], theta = lines[i][1];
Point pt1, pt2;
double a = cos(theta), b = sin(theta);
double x0 = a*rho, y0 = b*rho;
pt1.x = cvRound(x0 + 1000*(-b));
pt1.y = cvRound(y0 + 1000*(a));
pt2.x = cvRound(x0 - 1000*(-b));
pt2.y = cvRound(y0 - 1000*(a));
line( cdst, pt1, pt2, Scalar(0,0,255), 3, CV_AA);
}

// srn and stn: cero por defecto

Deteccin de Lneas y Bordes


El mtodo HoughLinesP con los parmetros comentados
vector<Vec4i> lines;

// lines: almacenara las lneas detectadas.

HoughLinesP(dst, lines, 1, CV_PI/180, 50, 50, 10 );

// dst: proporcionado por Canny, lines ,


// usaremos 1 pixel, 1 grado (CV_PI/180),

for ( size_t i = 0; i < lines.size(); i++ ) {


Vec4i l = lines[i];
line( cdst, Point(l[0], l[1]),
Point(l[2], l[3]), Scalar(0,0,255),
3, CV_AA);
}

// threshold: numero mnimo de lneas a


detectar,
// minLinLength: mnimo de puntos que forman
// una lnea.

Deteccin de Lneas y Bordes

Deteccin de 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.
cvtColor(img, gray, CV_BGR2GRAY);
GaussianBlur( gray, gray, Size(9, 9), 2, 2 );

Deteccin de Crculos
Luego 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.
vector<Vec3f> circles;
HoughCircles(gray, circles, CV_HOUGH_GRADIENT,2, gray.rows/2,
200, 100 );

Deteccin de Crculos
Por ultimo dibujamos los crculos que encontramos en
la imagen
for ( size_t i = 0; i < circles.size(); i++ ) {
Point center(cvRound(circles[i][0]),
cvRound(circles[i][1]));
int radius = cvRound(circles[i][2]);
circle( img, center, 3, Scalar(0,255,0), 3);
circle( img, center, radius, Scalar(0,0,255), 3);
}

Deteccin de Figuras Geomtricas


En las diapositivas anteriores se vio como detectar
lneas y crculos en una imagen, esta vez
avanzaremos un poco mas y detectaremos las
figuras geomtricas bsicas como: tringulos,
cuadrados, crculos y pentgonos, haciendo uso de
la librera opencv.
Previo a la deteccin de figuras geomtricas
aprenderemos a usar las siguientes funciones
implementadas a travs de opencv:
Deteccin

de contornos de una imagen.


Deteccin de figuras simples.

Deteccin de Figuras Geomtricas


Deteccin de contornos de una imagen
La funcin findContours devuelve un conjunto de puntos que
representan el contorno de una imagen, esta imagen debe ser
binaria, adems findContours modifica la imagen por lo que
debemos tener cuidado. Esta funcin nos servir de mucho para la
deteccin y reconocimiento de figuras geomtricas y de otros
objetos.
Una vez tengamos los contornos podemos mostrarlos usando la
funcin drawContours esta se encargara de unir con lneas los
puntos obtenidos por la funcin anterior, podemos indicar un grosor
de lnea en pixeles o indicar 1 para rellenar toda la figura.
Antes de buscar los contornos aplicaremos la funcin Canny para
buscar los bordes de la imagen. Le pasamos como parmetros la
imagen de entrada, la de salida, un umbral mximo y uno mnimo.

Mat src = imread("star.png", 1);


// Mostrar la imagen original en Visual Studio cambiar por SystemDrawing
imshow("Original", src);
Mat canny_output;
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
int thresh = 100;
// Detectar los bordes con un umbral min = 100 y max = 200
Canny(src, canny_output, thresh, thresh * 2);
// Mostrar los bordes detectados con Canny
imshow("Bordes", canny_output);
// Buscar los contornos de la imagen, se almacenan en contours
findContours(canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));

// Mostrar la Imagen modificada por la funcion findContours


imshow("Modificada", canny_output);
// Dibujar los contornos encontrados
Mat drawing = Mat::zeros(canny_output.size(), CV_8UC3);
for (size_t i = 0; i< contours.size(); i++)
{
Scalar color = CV_RGB(0, 255, 0);
drawContours(drawing, contours, (int)i, color, 2, 8, hierarchy, 0, Point());
}
// Mostrar la imagen final
imshow("Contours", drawing);

Deteccin de Figuras Geomtricas


Deteccin de figuras simples
Para reconocer una figura geomtrica haremos uso de la funcin
approxPolyDP la cual usa el algoritmo de Douglas-Peucker para
reducir el nmero de puntos que se aproxima a una curva.
Si

tiene tres vrtices de salida sabemos que es un triangulo.

Para

saber si es un rectngulo se deben cumplir los siguientes


parmetros:
La

funcin isContourConvex debe devolver true.

Debe
Los

tener 4 vrtices.

ngulos deben ser de 90 grados.

Para

un hexgono el nmero de vrtices debe ser 6 y los ngulos de


120 grados.

Para

un circulo tenemos las siguientes condiciones:

Mas

de 6 vrtices.

Tener

dimetro de igual dimensin en todas direcciones.

for (size_t i = 0; i < contours.size(); i++) {


// reducir el numero de puntos usando del algoritmo de Douglas-Peucker
cv::approxPolyDP(cv::Mat(contours[i]), approx, cv::arcLength(cv::Mat(contours[i]), true)*0.02, true);
// Si no cumple con estas condiciones es un objeto invalido
if (std::fabs(cv::contourArea(contours[i])) < 100 || !cv::isContourConvex(approx))
continue;
// Es un triangulo
if (approx.size() == 3)
{
setLabel(dst, "TRI", contours[i]);
}
else if (approx.size() >= 4 && approx.size() <= 6)
{
// Obtener el numero de vertices
int vtc = approx.size();
// Obtener todos los angulos (cosenos)
std::vector<double> cos;
for (int j = 2; j < vtc + 1; j++)
cos.push_back(angle(approx[j%vtc], approx[j - 2], approx[j - 1]));
//Ordenar los angulos obtenidos
std::sort(cos.begin(), cos.end());

// Obtener los angulos maximos y minimos


double mincos = cos.front();
double maxcos = cos.back();
//Obtener los angulos y determinar el tipo de figura segun los
//angulos obtenidos y el nuemero de vertices
if (vtc == 4 && mincos >= -0.1 && maxcos <= 0.3)
setLabel(dst, "RECT", contours[i]);
else if (vtc == 5 && mincos >= -0.34 && maxcos <= -0.27)
setLabel(dst, "PENTA", contours[i]);
else if (vtc == 6 && mincos >= -0.55 && maxcos <= -0.45)
setLabel(dst, "HEXA", contours[i]);
}
else
{
// Determinar si es un circulo
double area = cv::contourArea(contours[i]);
cv::Rect r = cv::boundingRect(contours[i]);
int radius = r.width / 2;
if (std::abs(1 - ((double)r.width / r.height)) <= 0.2 &&
std::abs(1 - (area / (CV_PI * std::pow(radius, 2)))) <= 0.2)
setLabel(dst, "CIR", contours[i]);
}
}

Caso de Aplicacin
Deteccin de Color y Distancia
Obsrvese el siguiente caso, un pequeo
robot NXT de lego, que encuentra en su
camino 2 esferas de diferente color,
deber de reconocer la esfera roja y
calcular la distancia que existe entre la
marca verde que maneja y el centro de la
esfera, la tarea a realizar consiste en:
1.Adquirir
2.Buscar

la imagen.

todos los puntos rojos de la

imagen.
3.Calcular

cul sera el centro de nuestro


objeto rojo.

4.Buscar

todos los puntos verdes de la

imagen.
5.Calcular

cul sera el centro de la punta

del NXT.
6.Calcular

distancia.

en que posicin relativa y la

Caso de Aplicacin
1). Adquirir la Imagen
Esto se puede realizar gracias a la clase cvCapture de OpenCV, el
cdigo seria como sigue:
CvCapture* captura;
captura = cvCaptureFromCAM(0);
IplImage* frame = cvQueryFrame(captura);

Caso de Aplicacin
2). Buscar los puntos del mismo color
Para detectar un objeto de determinado color necesitaremos detectar
todos los pxeles que lo componen. Para ello iremos buscando en todos
los pxeles 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 caractersticos tiene dicho color. En este caso es sencillo, su dato
ms caracterstico ser que el canal con mayor valor ser el del
rojo(Recuerde que una imagen tiene 3 canales Red Green y Blue).
Tambin deberamos tener en cuenta que los valores de los
dems canales no deberan ser muy altos, por lo menos no lo
suficiente como para acercarse al valor del canal del rojo, ya que estos
valores podran corresponder a colores como el morado o el naranja.
Con un color que no sea de los tres bsicos la cosa se complica un poco;
en este caso lo mejor es abrir la imagen con un editor de imgenes (el
Paint por ejemplo), y mirar que valores RGB tienen los pxeles del color
deseado. As podremos sacar las caractersticas que nos determinarn
dicho color.

Caso de Aplicacin
3). Calcular el Centro del Objeto
Una vez tengamos todos los pxeles del objeto podemos hacer varias
cosas: podramos cambiar de color los pxeles y mostrar la imagen
resultante por pantalla para ver si ha detectado bien el objeto:
Podemos adems llevar un contador de cuantos pxeles llevamos, y
una suma de sus posiciones, lo que nos servira para calcular lo que
sera el punto medio de nuestro objeto. Ests coordenadas del punto
medio sern bastante precisas si contamos con una gran cantidad de
pxeles del objeto, y nos ser de gran utilidad para emplazar dicho
objeto con respecto al robot NXT.

Caso de Aplicacin
4). Calcular la posicin del objeto respecto al robot NXT
Teniendo el punto medio del objeto calculado anteriormente el
proceso es sencillo. Ponemos a nuestro robot algo de color distintivo
en la punta, como el ladrillo verde que hemos puesto al nuestro.
Calculamos el punto medio de dicha punta verde, tal y como lo hemos
hecho para la bola roja. Una vez tenemos las coordenadas sabemos si
el objeto se encuentra a nuestra izquierda o derecha, y arriba o abajo
de nuestro robot. Adems podemos hallar la distancia al objeto (en
pxeles) mediante la famosa formula de traslacin de coordenadas.

Caso de Aplicacin
Captura del Aplicativo

Das könnte Ihnen auch gefallen