Buscar en este blog

Mostrando entradas con la etiqueta opencv. Mostrar todas las entradas
Mostrando entradas con la etiqueta opencv. Mostrar todas las entradas

viernes, 18 de mayo de 2007

PROCESAMIENTO DE IMAGENES - TEMPLATE MATCHING

Template Matching es una técnica dentro del procesamiento de imagenes que nos sirve para encontrar partes pequeñas de una imagen (template), dentro de una imagen completa. http://en.wikipedia.org/wiki/Template_matching
Es una medida de qué tan bien un template en niveles de gris g(x,y) se ajusta a una imagen f(x,y) dada. Se puede usar una función de distancia o una NCC (normalized cross-correlation). http://rkb.home.cern.ch/rkb/AN16pp/


Es una técnica de reconocimiento de patrones que consiste en buscar en una imagen I, una imagen mas pequeña denominada patron o template (T).

Dada una imagen A de tamaño (WxH), y P una imagen mas pequeña denominada patron de tamaño (wxh), el resultado es una imagen M de tamaño (W-w+1)x(H-h+1), en donde cada uno de sus pixeles indica la verosimilitud o probabilidad de que el rectangulo [x,y], [x+w-1, y+h-1] de A contenga el patron P.





El siguiente código ilustra el uso de la función cvMatchTemplate() de Open CV


MatchTemplate
Compares template against overlapped image regions
void cvMatchTemplate( const CvArr* I, const CvArr* T,CvArr* result, int method );
I
Image where the search is running. It should be single-chanel, 8-bit or 32-bit floating-point.
T
Searched template; must be not greater than the source image and the same data type as the image.
R
Image of comparison results; single-channel 32-bit floating-point. If I is W×H and T is w×h then R
must be W-w+1×H-h+1.
method
Specifies the way the template must be compared with image regions (see below).


The function cvMatchTemplate [p 202] is similiar to cvCalcBackProjectPatch [p 199] . It slids through I,
compares w×h patches against T using the specified method and stores the comparison results to result.
Here are the formular for the different comparison methods one may use (the summation is done over
template and/or the image patch: x’=0..w-1, y’=0..h-1):

method=CV_TM_SQDIFF:
R(x,y)=sum x’,y’ [T(x’,y’)-I(x+x’,y+y’)] 2

method=CV_TM_SQDIFF_NORMED:
R(x,y)=sum x’,y’ [T(x’,y’)-I(x+x’,y+y’)] 2 /sqrt[sum x’,y’ T(x’,y’) 2 ·sum x’,y’ I(x+x’,y+y’) 2 ]

method=CV_TM_CCORR:
R(x,y)=sum x’,y’ [T(x’,y’)·I(x+x’,y+y’)]


method=CV_TM_CCORR_NORMED:
R(x,y)=sum x’,y’ [T(x’,y’)·I(x+x’,y+y’)]/sqrt[sum x’,y’ T(x’,y’) 2 ·sum x’,y’ I(x+x’,y+y’) 2 ]

method=CV_TM_CCOEFF:
R(x,y)=sum x’,y’ [T’(x’,y’)·I’(x+x’,y+y’)],
where T’(x’,y’)=T(x’,y’) - 1/(w·h)·sum x",y" T(x",y") (mean template brightness=>0)
I’(x+x’,y+y’)=I(x+x’,y+y’) - 1/(w·h)·sum x",y" I(x+x",y+y") (mean patch brightness=>0)

method=CV_TM_CCOEFF_NORMED:
R(x,y)=sum x’,y’ [T’(x’,y’)·I’(x+x’,y+y’)]/sqrt[sum x’,y’ T’(x’,y’) 2 ·sum x’,y’ I’(x+x’,y+y’) 2 ]

After the function finishes comparison, the best matches can be found as global minimums
(CV_TM_SQDIFF*) or maximums (CV_TM_CCORR* and CV_TM_CCOEFF*) using cvMinMaxLoc


#include "cv.h"
#include "highgui.h "
#include "stdio.h"


int main() {


IplImage* im = cvLoadImage( "../cam1.jpg", -1); //-1 indica que cargue la imagen en sus colores y caracteristicas originales

if( im == 0 ) {
std::cerr << "Error al cargar la imagen: " <<>
return 1;
}

IplImage* imG = cvCreateImage(cvSize(im->width, im->height), 8, 1);//direcciona un espacio en memoria con las dimensiones de ancho y alto de im, con 8 bits y 1 canal

cvCvtColor(im, imG, CV_BGR2GRAY);//img cambia su espacio de color al espacio de color de im, (BGR2GRAY)


//coordenadas iniciales del rectángulo
int xVal = 150;
int yVal = 50;
int neighLength = 25;
CvRect rect = cvRect(xVal,yVal,neighLength,neighLength);//traza una area rectangular

CvMat* tplate = cvCreateMat(neighLength, neighLength, CV_8UC1);//cvCreateMat crea una matriz(renglones, columnas, tipo de elemento)CV_8UC1(8 bits unsigned, 1 canal)

cvGetSubRect(imG, tplate, rect );//obtiene de img el area definida por rect y la asigna a tplate

//se especifica el tamaño necesario para realizar la función matching
int resultW = imG->width - tplate->width + 1;
int resultH = imG->height - tplate->height +1;

//direcciona el espacio para cada imagen
IplImage* result0 = cvCreateImage(cvSize(resultW, resultH), IPL_DEPTH_32F, 1);
IplImage* result1 = cvCreateImage(cvSize(resultW, resultH), IPL_DEPTH_32F, 1);
IplImage* result2 = cvCreateImage(cvSize(resultW, resultH), IPL_DEPTH_32F, 1);
IplImage* result3 = cvCreateImage(cvSize(resultW, resultH), IPL_DEPTH_32F, 1);
IplImage* result4 = cvCreateImage(cvSize(resultW, resultH), IPL_DEPTH_32F, 1);
IplImage* result5 = cvCreateImage(cvSize(resultW, resultH), IPL_DEPTH_32F, 1);

//se aplican cada una de las técnicas de matching
cvMatchTemplate(imG, tplate, result0, CV_TM_SQDIFF);
cvMatchTemplate(imG, tplate, result1, CV_TM_SQDIFF_NORMED);
cvMatchTemplate(imG, tplate, result2, CV_TM_CCORR);
cvMatchTemplate(imG, tplate, result3, CV_TM_CCORR_NORMED);
cvMatchTemplate(imG, tplate, result4, CV_TM_CCOEFF);
cvMatchTemplate(imG, tplate, result5, CV_TM_CCOEFF_NORMED);

//se muestra el resultado del matching
cvNamedWindow("SQDIFF", 0 );
cvNamedWindow("SQDIFF_NORMED",0);
cvNamedWindow("CCORR",0);
cvNamedWindow("CCORR_NORMED",0);
cvNamedWindow("CCOEFF",0);
cvNamedWindow("CCOEEFF_NORMED",0);

cvShowImage("SQDIFF", result0);
cvShowImage("SQDIFF_NORMED", result1);
cvShowImage("CCORR", result2);
cvShowImage("CCORR_NORMED", result3);
cvShowImage("CCOEFF", result4);
cvShowImage("CCOEEFF_NORMED", result5);

//marca el área en la imagen original de donde se obtuvo el template
cvRectangle(imG, cvPoint(xVal,yVal), cvPoint(xVal+neighLength,yVal+neighLength),
CV_RGB(255,0,255),2 , 8, 0);

//muestra la imagen y el template
cvNamedWindow("Image",0);
cvNamedWindow("Template",0);
cvShowImage("Image", imG);
cvShowImage("Template", tplate);

cvWaitKey(0);

cvReleaseImage(&imG);
cvReleaseMat(&tplate);
cvReleaseImage(&result0);
cvReleaseImage(&result1);
cvReleaseImage(&result2);
cvReleaseImage(&result3);
cvReleaseImage(&result4);
cvReleaseImage(&result5);

cvDestroyAllWindows();

return 0;

}


SIMULANDO EL FUNCIONAMIENTO DE UNA CÁMARA FOTOGRÁFICA CON OPENCV (18-Mayo-07)

En este apartado se presenta el código fuente de un programa que permite enfocar la imagen observada en la computadora para posteriormente almacenarla en el disco duro. El programa permite guardar 10 imagenes.

#include "stdio.h"
#include "conio.h"
#include "cv.h"
#include "highgui.h"
#include "cxcore.h"
#include "cvaux.h"

int main(){

char* nomImages[] = {".\img_1.jpg", ".\img_2.jpg", ".\img_3.jpg", ".\img_4.jpg", ".\img_5.jpg", ".\img_6.jpg", ".\img_7.jpg", ".\img_8.jpg", ".\img_9.jpg", ".\img_10.jpg"};

CvCapture* capture = cvCaptureFromCAM(-1);
if(!capture){
printf("Error: Capture = NULL\n");
getchar();
return -1;
}

cvNamedWindow("cvSaveImage", 1);

for(int i=0; i<10;>

while(1){

IplImage* frame = cvQueryFrame(capture);

if(!frame) {
printf("Error: Frame = NULL\n");
getchar();
return -1;
}

cvShowImage("cvSaveImage", frame);

if((cvWaitKey(10) & 255)==27) break;

}

IplImage* frame = cvQueryFrame(capture);

if(!frame) {
printf("Error: Frame = NULL\n");
getchar();
return -1;
}

cvShowImage("cvSaveImage", frame);

cvSaveImage(nomImages[i], frame);

printf("imagen %d",i);

cvWaitKey(0);

}

cvReleaseCapture(&capture);
cvDestroyWindow("cvSaveImage");
return(0);

}

miércoles, 14 de marzo de 2007

CAPTURANDO IMAGENES CON OPENCV (13 de Marzo de 2007)

Busqué en Internet algunos códigos para capturar imágenes desde una cámara, encontré uno en el foro wiki de opencv, que al parecer daba algunos problemas, lo analicé y tomé la parte de código que me serviría para capturar imágenes desde la webcam, el código que generé fue el siguiente:

1- #include "highgui.h"
2- #include "cv.h"
3- #include "stdio.h"
4- #include "iostream.h"
5-
6- int main() {
7-
8- CvCapture* capture = cvCaptureFromCAM(-1);
9- if (!capture){
10- fprintf(stderr, "Error: capture = NULL\n");
11- getchar();
12- return -1;
13- }
14-
15- cvNamedWindow("Ventana", 1);
16-
17- IplImage* frame = cvQueryFrame(capture);
18- if (!frame) {
19- fprintf(stderr, "Error: frame = NULL\n");
20- getchar();
21- return -1;
22- }
23- cvShowImage("Ventana", frame);
24- cvWaitKey(0);
25- cvReleaseCapture(&capture);
26- cvDestroyWindow("Ventana");
27- return(0);
28- }

El programa anterior crea un capture (línea 8) para hacer referencia a la webcam instalada en la máquina, también crea una variable (frame) que apuntará a la imagen que recibe la cámara. Posteriormente se crea una ventana en donde se mostrará lo sensado por la cámara y finalmente se liberará el capture y se destruirá la ventana.
Si se quiere capturar una secuencia de cuadros, es decir un flujo de video, hay que agregar el siguiente código:

while(1){ //mientras sea verdadero
IplImage* frame = cvQueryFrame(capture);//graba un cuadro tomado por la cámara
if (!frame) {
fprintf(stderr, "Error: frame = NULL\n");
getchar();
return -1;
}
cvShowImage("Ventana", frame);//muestra el cuadro tomado por la cámara
if((cvWaitKey(10) & 255)==27) break;//rompe el ciclo while si se oprime la tecla esc
}