Está en la página 1de 61

TutorialdeOpenCV

23/04/08
RalIgual

CarlosMedrano

Tableofcontenst

Licencia................................................................................................................................................3
Historiadeldocumento.........................................................................................................................3
Instalacinycompilacin.....................................................................................................................4
TiposdedatosenOpencv....................................................................................................................8
LibreraOpencv....................................................................................................................................7
Funcionesinteresantes........................................................................................................................14
FuncionesarealizarconOpencv........................................................................................................15
Abririmgenes...............................................................................................................................15
Guardarimgenes..........................................................................................................................16
Accederaunpixel.........................................................................................................................19
Gestionardistintostiposdeimgenes................................................................................................25
Formatosdeficheros......................................................................................................................25
Tiposdeimgenes.........................................................................................................................28
Tiposdedatosdeunpxel.............................................................................................................29
Transformacionesafines.....................................................................................................................30
Traslacin.......................................................................................................................................30
Escalado.........................................................................................................................................34
Rotacin.........................................................................................................................................38
Binarizacindeimgenes...................................................................................................................43
Operacionesconmatrices...................................................................................................................47
Inversindematrices.....................................................................................................................47
Multiplicacindematrices.............................................................................................................48
BIBLIOGRAFA................................................................................................................................51
GNUFreeDocumentationLicense....................................................................................................54

Licencia
Copyright(c)2007RalIgualCataln,CarlosMedranoSnchez.
Permissionisgrantedtocopy,distributeand/ormodifythisdocumentunderthetermsoftheGNU
Free Documentation License, Version 1.2 orany later versionpublished bythe Free Software
Foundation;withnoInvariantSections,noFrontCoverTexts,andnoBackCoverTexts.Acopyof
thelicenseisincludedinthesectionentitled"GNUFreeDocumentationLicense".

Historiadeldocumento
Este documento seinicia dentro delTrabajoFindeCarreradeRalIgual,alumnodela E.U.
PolitcnicadeTeruel,sobrealgoritmosdeseguimientodeobjetosentiemporeal.EsteTrabajoFin
de Carrera ha sido financiado por la Fundacin Universitaria Antonio Gargallo,
(http://www.fantoniogargallo.org/).
Versininicial:RalIgual,
AadidodelaseccindeinstalacinydelasfuncionescvReleaseXX:CarlosMedrano
Formato:CarlosMedrano,29122007
Versinmodificada:RalIgual,22042008.Sehanaadidolassalidasdelosprogramasysehan
efectuadoalgunaspequeasmodificacionesenalgunospuntos.

Instalacinycompilacin
Parainstalarlalibrera,loprimeroquedebemosdehaceresdescargarnosladelsitio:
http://sourceforge.net/projects/opencvlibrary/
Siladescargamosconuntar.gz,habrquedescomprimirlacon
$tarxvzfopencv1.0.0.tar.gz

Ennuestrocasoeslaversin1.0.0.Despusbajaremosaldirectorioopencv1.0.0
$cdopencv1.0.0

DespusconsultaremoselficheroINSTALL,yseguiremoslasinstruccionesqueallse
expliquen. Segn este documento, hay que tener en cuenta que se necesitan tener
instaladasunaslibreras(porejemplolibpng).Estosepuedehacerdesdeelgestorde
paquetes de nuestro equipo. Por ejemplo, en kubuntu suele aparecer como Adept
(PackageManager)enformagrfica,odesdelalneadecomandosconaptitudeoapt.
Cuandonoshablendelibreraconficherosdedesarrollo(developmentfiles),habrque
instalarlaslib,perotambinlaslibdev(poeejemplo,libpng12dev).Unavezhechoesto,
lainstalacinserealizaconlasinstruccionesqueindicaelficheroINSTALL:
$./configure
$make
$sudomakeinstall

Conestoseinstalarennuestroequipo.Noobstante,paraqueencuentrelalibreraal
compilaresnecesarioindicarlelarutaadecuada.Paraellosepuedemodificarlavariable
deentornoLD_LIBRARY_PATH,queesunalistadedirectoriosseparadosporpuntoy
coma.Estohayquehacerloencadasesinobienennuestrofichero.bash_profilede
nuestrodicrectorio/home/usuario/.Otraformamscmodaesaadirlarutadelalibrera
OpenCV al fichero de configuracin /etc/ld.so.conf. En nuestro caso, la librera est
en/usr/local/libporloqueelarchivoqueda
$more/etc/ld.so.conf
/usr/lib/atlas
/usr/local/lib/

traslocualbastahacer
$sudoldconfigv

paraqueencuentrelalibreraalcompilar.
Pero, cmo compilar un programa que usa la librera? Veamos un ejemplo con el
siguienteprograma,quecargarlaimagenlena.jpg,lomostrarenunaventana,yluego
lo guardar en saliendo.jpg. Debe tener la imagen en el directorio de trabajo (al
descomprimiropencvesaimagenseencuentratambinenalgunaruta).
#include"cv.h"
#include"highgui.h"
#include<stdio.h>
charname0[]="lena.jpg";//sedefineelficheroacargar
intmain()
{
IplImage*imagen=NULL;//inicializoimagen
imagen=cvLoadImage(name0,1);//cargamoslaimagen,
//secargaentrescolores
cvNamedWindow("test",1);//creamoslaventanadenombre"test"
//indicndoleconel1queajuste
//sutamaoaldelaimagen
cvShowImage("test",imagen);//representamoslaimagenenlaventana
cvSaveImage("saliendo.jpg",imagen);//guardamoslaimagen
cvWaitKey(0);//sepulsateclaparaterminar
cvDestroyAllWindows();//destruimostodaslasventanas
cvReleaseImage(&imagen);
return0;
}

Suponiendoqueesteprogramasellamaload_save.c,sepuedecompilarcon:
$ gcc load_save.c o load_save I/usr/local/include/opencv/
L/usr/local/liblcvlhighgui

EsrecomendablehacerunMakefile,quepodraseras:
INC=/usr/local/include/opencv/

LIB=/usr/local/lib
all:load_save
load_save:load_save.c
gcc Wall load_save.c o load_save I$(INC) L$(LIB) lcv
lhighgui
clean:
rmload_save

LaopcinWallengccdagrancantidaddeinformacin.Aunqueespesada,conviene
tenerlaavecespuesnosindicaposiblesfallosenelprograma.Conesteficherobasta
hacer:
$make

omakeallcadavezquequeramoscompilar.

LibreraOpencv
Las siglas Opencv provienen de los trminos anglosajones Open Source
Computer Vision Library. Por lo tanto, Opencv es una librera de tratamiento de
imgenes,destinadaprincipalmenteaaplicacionesdevisinporcomputadorentiempo
real.
Conesteinformesepretendeproveerdeladescripcindealgunasfuncionesde
inters, as como exponer ejemplos completos y compilables de su uso, ya que esto
facilitar en gran medida su posterior aplicacin. Tambin es necesario definir los
principalestiposdedatosqueutilizaOpencv,yqueestninvolucradosconelempleode
lasfunciones,lamayoradeestostiposdedatossonestructurasdinmicas.

AlgunosapuntessobreOpencv

Es importante no confundir las funciones, con los tipos de datos propios de


Opencv.Paraello,lapropialibrerautilizaunasintaxisdistintaparacadacaso,conligeras
diferencias, aunque en principio si no se presta la debida atencin, es fcil confundir
ambassintaxis.
CadaunadelasfuncionesreferenciadasenOpencvcomienzaconlassiglascv,
seguidadelnombredelafuncin,conlaprimeraletradecadaunadelaspalabrasque
componen dicho nombre en mayscula. Por ejemplo: cvCreateImage, cvInvert,
cvMatMulAdd...
Parareferirnosalostiposdedatoslasintaxisesmuysimilaraladelasfunciones,
aunqueconlanicadiferenciadequelostiposcomienzanconlasiglasCv.Porejemplo:
CvScalar, CvMat... No obstante existen algunos tipos que se declaran de forma
totalmentedistinta(IplImage...).Paraconcretarestasindicacionespasamosaexponerlos
principalestiposdedatos.

TiposdedatosenOpencv
Opencvproporcionaunostiposdedatosbsicosparasuutilizacin.Tambinnos
proveedetiposdedatosintroducidoscomoayudaalprogramador,parahacerqueel
accesoainformacindeintersseamssimple.Comenzamosladescripcindelostipos
dedatos:

CvArr
Esmuyimportantecomprenderqueestenoesuntipodedatosreal,sinoloquese
denominaunmetatype,esdecir,untipodedatoficticioqueseutilizadeformagenrica
alahoradedescribirlosparmetrosdelasfunciones.LanomenclaturaCvArr*seutiliza
sloparaindicarquelafuncinaceptaarraysdemsdeuntipo,comopuedenser
IplImage*CvMat*oinclusoCvSeq*.

IplImage
El tipo de datos bsico en Opencv es el IplImage. Con este tipo de datos se
representanlasimgenesseandeltipoquesean:BGR,intensidad...
Pasamosamostrarlaordenacinyloscamposdeestaestructura:
typedefstruct_IplImage{
intnSize;/*tamaodelaestructuraiplImage*/
intID;/*versindelacabeceradelaimagen*/
intnChannels;
intalphaChannel;
intdepth;/*profundadaddelaimagenenpxeles*/
charcolorModel[4];
charchannelSeq[4];
intdataOrder;
intorigin;
intalign;/*alineamientode4o8byte*/
intwidth;

intheight;
struct_IplROI*roi;/*punteroalaROIsiexiste*/
struct_IplImage*maskROI;/*punteroalamxcaraROIsiexiste*/
void*imageId;/*usodelaaplicain*/
struct_IplTileInfo*tileInfo;/*containsinformationontiling
intimageSize;/*tamaotilenbytes*/
char*imageData;/*punteroalaimagenalineada*/
intwidthStep;/*tamaodealineamientodelineaenbytes*/
intBorderMode[4];/*thetop,bottom,left,andrightbordermode
*/
intBorderConst[4];/*constantsforthetop,bottom,left,and
rightborder*/
char*imageDataOrigin;/*punteroalaimagencompleta,sinalinear
*/
}IplImage;

Vamosadescribirmsenprofundidadaquelloscamposquenosvanasertilesen
nuestraaplicacin.
Los campos width y height contienen la anchura y la altura de la imagen
expresadasenpxeles.
El campo depth contiene informacin sobre el tipo de valorde lospxeles. Los
posiblesvaloresdelcampodepthsonlossiguientes:
IPL_DEPTH_8U:Enterossinsignode8bits(unsignedchar)
IPL_DEPTH_8S:Enterosconsignode8bits(signedcharosimplementechar)
IPL_DEPTH_16S:Enterosde16bitsconsigno(shortint)
IPL_DEPTH_32S:Enterosconsignode32bits(int)
IPL_DEPTH_32F:Nmerosenpuntoflotanteconprecisinsimplede32bits(float)
El campo nChannels indica el nmero de canales de color de la imagen. Las
imgenesenescaladegrisestienenunslocanal,mientrasquelasdecolortienen3o4
canales.

El campo widthStep contiene el nmero de bytes entre puntos de la misma


columnayfilassucesivas.Paracalcularladistanciaconwidthnoessuficiente,yaque
cadacolumnapuedeestaralineadaconunciertonmerodebytesparaobtenermayores
velocidadesdeprocesamiento.
ElcampoimageDatacontieneunpunteroalaprimeracolumnadelosdatosdela
imagen.
Es posible seleccionar algunas partes rectangulares de la imagen, lo que se
conocecomoregionesdeinters(ROI).LaestructuraIplImagecontieneelcamporoi,que
sinoesnulo(NULL),apuntaalaestructuraIplROI,quecontieneparmetrosdelaregin
seleccionada.

CvMat
UnadelasestructurasmsempleadasparaoperarconlasimgenesesCvMat,
quesedefinedelsiguientemodo:
typedefstructCvMat
{
introws;//nmerodefilas
intcols;//nmerodecolumnas
CvMatTypetype;//tipodematriz
intstep;//noseutiliza
union
{
float*fl;//punteroalosdatosdetipofloat
double*db;//punteroadatosdedobleprecisin
}data;
}CvMat

Secaracterizaporqueapartedealmacenarloselementoscomocualquiermatriz,
ofrecelaposibilidaddeaccederainformacinadicionalquepuederesultardeutilidad.En
losprogramasquerealicemosestetipodedatossiempreirnasociadosconlafuncin

cvCreateMatquenospermitirconfigurarlaestructuramatricialdemaneramuysencilla.
Estafuncinseencargadecrearalencabezadodelaimagenydeubicarsusdatos.
Exponemossuestructura:
CvMat*cvCreateMat(introws,intcols,inttype);
rows:nmerodefilasdelamatriz
cols:nmerodecolumnasdelamatriz
type:tipodeloselementosdelasmatrices.Seespecificadela
forma:
CV_<bit_depth>(S|U|F)C<number_of_channels>.Siendo:
bit_depth:profundidaddebit(8,16,31...)
numberofchannels:elnmerodecanalesdelamatriz
(S|U|F):eltipodedatosdebit:
S:consigno
U:sinsigno
F:flotante

Porejemplo.:
CV_8UC1significaquesetieneunamatrizdeuncanalde8bitdetipounsigned.
CV_32SC2equivaleaunamatrizdedoscanalesde32bitsigned.

CvScalar
LaestructuraCvScalaressimplementeunvectordecuatroelementos,peroque
resultamuytilalahoradeaccederalospxelesdeunaimagen,sobretodosiesde
color.LaestructuraCvScalareslasiguiente:
CvScalar
doubleval[4];//vector4D

Para acceder al campo de esta estructura basta con adjuntar el nombre de la


mismaalapalabraval,conunpuntoentreambas,esdecir:
CvScalars;//definicindelavariablesdetipoCvScalar
s.val[0]=2;//inicializamoselprimerelementodesconelvalor
arbitrario2

Normalmente esta estructura suele ir acompaada de la funcin cvScalar, que


permitedefinirtodoslosparmetrosdeunasolavez.Analizamoslafuncin:
inlineCvScalarcvScalar(doubleval0,doubleval1,doubleval2,
doubleval3=0);
donde:val0,val1...sonlosvaloresquetomanloselementosdela
estructura.

Vemosunejemplo:
CvScalars=cvScalar(1.0,3,4.6,5);

CvPointyCvPoint2D32f
LostiposdedatosCvPointyCvPoint2D32f,definenlascoordenadasdeunpunto,
elprimerodeellosconnmerosenterosyelsegundoconnmerosenpuntoflotante.
DescribimosenprimerlugarCvPoint:
typedefstructCvPoint
{
intx;/*coordenadax*/
inty;/*coordenaday*/
}
CvPoint;

DeformaanlogatenemoslaestructuraCvPoint2D32f:
typedefstructCvPoint2D32f
{
floatx;/*coordenadax*/
floaty;/*coordenaday*/
}
CvPoint2D32f;

Estas estructuras como algunas de las anteriores suelen ir acompaadas de

funcionesquefacilitansuusoydefinicin.EnestecasotenemoslasfuncionescvPointy
cvPoint2D32f,conlossiguientesparmetros:
inlineCvPointcvPoint(intx,inty);
inlineCvPoint2D32fcvPoint2D32f(doublex,doubley);
siendoxeylascoordenadasdelpunto.

Ejemplodeaplicacin:
CvPointpunto=cvPoint(100,200);
CvPoint2D32fpuntof=cvPoint2D32f(100.0,200.0);

CvSize
Estructurautilizadaparadefinirlasdimensionesdeunrectnguloenpxeles:
typedefstructCvSize
{
intwidth;/*anchuradelrectngulo(valorenpxeles)*/
intheight;/*alturadelrectngulo(valorenpxeles)*/
}
CvSize;

Estetiposeutilizasobretodoalahoradecrearimgenesnuevas,paradefinirsus
dimensiones.LafuncinasociadaaestetipoescvSize:

inlineCvSizecvSize(intwidth,intheight);//siendowidthyheight
lasdimensiones

Vemosunejemplodeaplicacin:
CvSizetamano=cvSize(100,200);

Funcionesinteresantes
Antesdeabordarloscasosdeintersseraconvenienteintroduciralgunasdelas
funcionesquemsseutilizarnenlosprogramassiguientes,yquesepuedenconsiderar
comunesatodoslostemasquetrataremos.

voidcvNamedWindow(charname,inttype);
Estafuncincreaunaventanagrfica.Analizamossusparmetros:
name:cadenadecaracteresquesirvecomonombredelaventana
type:formatodetamaodelaventana:
UtilizaremosCV_WINDOW_AUTOSIZE,osimplementepondremosun
1paraseleccionarestaopcin.
voidcvShowImage(charname,CvArr*img)
Estafuncindibujalaimagenindicadaenlaventanacorrespondiente.
Tienecomoparmetros:
name:nombredelaventanadondesedibujarlafuncin
img:imagenquedeseamosdibujar
voidcvDestroyAllWindows();
Estafuncineliminatodaslasventanasgrficasquehayansidocreadas
previamente.
voidcvReleaseImage(&CvArr*img);
Estafuncinseencargadeliberarelespaciodememoriaquehasido
asignadoaunaestructuraCvArr*.Poseeunnicoparmetro:
img:eselnombredelaimagenquesedesealiberar
voidcvmSet(CvMat*mat,introw,intcol,doublevalue)
Estafuncinguardaunelementoenunamatrizdeunsolocanalenpunto
flotante:
mat:Lamatrizdeentrada
row:Elndicedelafila
col:Elndicedelacolumna
value:Elnuevovalordelelementodelamatriz

voidcvmGet(constCvMat*mat,introw,intcol);
Retornaelvalorquetomaunelementodelamatrizindicada.
mat:matrizdeentrada,delacualseextraerelvalordeunode
suselementos
row:valordelndicedeseadoenlasfilas(ejevertical)
col:valordelndiceenlascolumnas(ejehorizontal).Juntocon
lafiladefinela

posicindelelementodentrodelamatriz.

FuncionesarealizarconOpencv
Abririmgenes
ParaimplementarlaaccindeabririmgenesutilizandoOpencv,sehaceusodela
funcincvLoadImage.
Pasamos a describir los parmetros necesarios para poder trabajar con esta
funcin:
img=cvLoadImage(fileName,flag);
Siendo:

fileName:Nombredelficheroquesequierecargar

flag:Caractersticasdecargaenelfichero:

flag:>0:seobligaquelaimagencargadaseaunaimagendecolor
de3canales

flag=0:seobligaquelaimagencargadaseaunaimagenintensidad
de1canal

flag<0:laimagensecargatalcuales,conelnmerodecanales
queposeasufichero

Cabedestacarqueestafuncinpuederecibirlasimgenesencualquiertipode
formato: BMP, DIB, JPEG, JPG, JPE, PNG, PBM, PGM, PPM, SR, RAS, TIFF, TIF.
Siempreycuandolosparmetrosdelamismaseadecenalaimagenencuestin.
CuandodejemosdeutilizarunaimagenIplImagedebemosliberarlamemoriacon:
voidcvReleaseImage(IplImage**image);

deformasimilarafree().

Guardarimgenes
Se utiliza la funcin cvSaveImage para salvar las imgenes. Los parmetros
requeridos para su uso son muy parecidos a los empleados en la funcin anterior.
Pasamosadescribirloscamposdelafuncin:
cvSaveImage(outFileName,img)
Siendo:

outFileName:Nombredelficherodesalidaquedebercontenerala
imagenaguardar.

img:Imagenquesevaaguardar

Comoparticularidadcabedestacarquelaimagenquesesalvaescreadaporel
propioprogramayalmacenadaeneldirectoriodondeseencuentreelprograma.Porlo
tanto,noesnecesariodefinirningntipodeficherodealmacenamientoconantelacin.

ProgramadepruebadelasfuncionescvLoadImage

y
cvSaveImage

Para concretar los conceptos anteriormente expuestos vamos a mostrar dos


ejemplosclarosysencillosdelasfuncionescvLoadImageycvSaveImage.
Elprimerejemploeselsiguiente:

#include"cv.h"
#include"highgui.h"
#include<stdio.h>
charname0[]="out10000.jpg";//sedefineelficheroacargar
intmain()
{
IplImage*imagen=NULL;//inicializoimagen
imagen=cvLoadImage(name0,1);//cargamoslaimagen,
//secargaentrescolores
cvNamedWindow("test",1);//creamoslaventanadenombre
//"test"indicndoleconel1queajuste
//sutamaoaldelaimagen
cvShowImage("test",imagen);//representamoslaimagenenlaventana

cvSaveImage("saliendo.jpg",imagen);//guardamoslaimagen
cvWaitKey(0);//sepulsateclaparaterminar
cvDestroyAllWindows();//destruimostodaslasventanas
cvReleaseImage(&imagen);
return0;
}

Alejecutarelprograma,semuestraenpantallaunaimagencomoladelafigura1
(laquesedeseacargar),quepermaneceenelmonitorhastaquesedetectalapulsacin
deunateclacualquiera.
Ademssegenerarunficheroenlarutaindicadaenlainstruccindeguardar
imagen,quecontendrestamismaimagen.

Figura1
Enelprogramaanterior,elficheroimagensedefinedirectamenteenelcdigodel
mismo,asignandosunombreaunavariabledetipo char,queposteriormentesepasa
comoparmetroalafuncincvLoadImage,donderealmentesecargalaimagen.
Elsegundoejemplosediferencialigeramentedelanterior:

#include"cv.h"
#include"highgui.h"
#defineventana"Ventana1"
#defineventana1"Ventana2"
intmain(intargc,char*argv[])
{
//Comprobamossihanpasadounaimagencomoparmetro,
//sinopasamosunapordefecto
char*filename=argc>=2?argv[1]:(char*)"lena.jpg";

IplImage*imagen=NULL,*imagen1=NULL;
imagen=cvLoadImage(filename,1);//cargamoslaimagenenRGB
imagen1=cvLoadImage(filename,0);//Cargamoslaimagen
//enEscaladegrises
cvNamedWindow(ventana,0);//Mostramoslaimagenenlaventana
cvNamedWindow(ventana1,0);
cvShowImage(ventana,imagen);
cvShowImage(ventana1,imagen1);
cvWaitKey(0);
cvDestroyAllWindows();//destruimostodaslasventanas
cvReleaseImage(&imagen);
cvReleaseImage(&imagen1);
return0;
}

Enestecdigoelnombredelficherosedebecargarporconsola,porlotantoesel
propiousuarioelquedecidequeimagencargarsinnecesidaddemodificaryrecompilarel
programa.Encasodequestenointroduzcaelnombredeningnficheroenlaconsola,
secargarelqueelpropioprogramaposeepordefecto:lena.jpg.

Figura2

Figura3

Portanto,sidesesemosabrirlaimagenout4553.jpg,alahoradeejecutarel
programa,porconsoladeberamosescribir:./nombre_programarutadondeseubicala
imagenacargar.
Porejemplo,sielprogramasellamaloadsave.cypretendemoscargarlaimagenconruta
/home/raul/tpm2/out4553.jpg,escribimos:./loadsave/home/raul/tpm2/out4553.jpg.
Lasfigurassiguientesmuestranlamismaimagencargadaendosmodosdistintos:
encolor(figura4),yenescaladegrises(figura5).

Figura4

Figura5

Accederaunpixel
Comoessabido,elelementobsicodeunaimageneselpxel,portantoresulta
primordialsaberaccederaellos.
Opencvproporcionauna granvariedadde mtodosparaaccedera lospxeles,
aquvamosadescribiralgunosdelosmsusados.

Mtodo1:Accesoindirectoalospxeles.
SebasaenlautilizacindelasfuncionescvGet2DycvSet2Dqueseencargande
encontrarelementosdeunarrayyconfigurarelementosdeunarrayrespectivamente.Las
describimosacontinuacin:
CvScalarcvGet2D(constCvArr*arr,intidx0,intidx1);
Siendo:

arr:arrayenelcualvamosabuscarelvalordelelementodeseado

idx0:ndicedefilasdelelemento

idy1:ndicedecolumnasdelelemento

LasalidadelafuncineselvalordelelementoyesdetipoCvScalar(unescalar).

voidcvSet2D(CvArr*arr,intidx0,intidx1,CvScalarvalue);
Siendo:

arr:arraydeentradaenelquevamosadefinirunodesuselementos

idx0:ndicedefilasdelelemento

idx1:ndicedecolumnasdelelemento

value:valorquedeseamosasignaralelemento(idx0,idx1)

Laestructuradedatosimplicadaenelaccesoalospxeleses CvScalar yest


definidaenlaslibrerasdeOpencv.
Pasamos a mostrar el acceso a un pxel en un sistema monocanal (imgenes
binariasoenescaladegrises):
IplImage*img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);

//Obtenemoselvalordeintensidadenunpxel

CvScalars;//definimoslaestructuradondealmacenaremoslosdatos
s=cvGet2D(img,i,j);//seobtieneelvalor(i,j)delpxel,que

quedaalmacenadoens.val[0]

printf("intensity=%f\n",s.val[0]);//imprimimosesevalor

//Fijamosunpxelaundeterminadoniveldeintensidad
s.val[0]=111;//asignamoselvalordeintensidaddeseado

cvSet2D(img,i,j,s);//configuramoselpxel(i,j)conesevalor

Enelcdigoanteriorsloseutilizaelcampos.val[0]delaestructuraCvScalar,ya
quealtenerunsoloniveldecolor,nicamenteesnecesariounindicador.
Enelcasodetenerunsistemamulticanal(trescoloresparadefinirunpxel)el
accesoalospxelesserealizaconelsiguientecdigo:

IplImage*img=cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3);

//Obtenemoselvalordelpxel(i,j)deunaimagen

CvScalars;

s=cvGet2D(img,i,j);//obtenemoselvalorenelpxel(i,j)

printf("B=%f,G=%f,R=%f\n",s.val[0],s.val[1],s.val[2]);//
imprimimosesevalor

//Fijamosunpxelaunniveldecolordeterminado

s.val[0]=111;//Niveldeazul

s.val[1]=111;//Niveldeverde

s.val[2]=111;//Nivelderojo

cvSet2D(img,i,j,s);//asignamoslosnivelesanterioresalpxel
(i,j)

CabedestacarqueaquseutilizantrescamposdelaestructuraCvScalar,unopara
cadaniveldecolor(rojo,verdeyazul).
Podemosenunciaralgunadelascaractersticasdeestemtododeaccesoalos
pxeles.Comoaspectopositivocontienelaventajadequeeslaformamssencillade
accederaunpxel.Cmoinconvenientepodemoscitarqueespocoeficiente,ocomo
mnimo,menoseficientequelosotrosmtodos.

Mtodo2:Utilizandopunterosalosdatosdelaimagen.

Para ello es necesario acceder a los siguientes campos de la estructura


IplImage*:height,width,widthstep,imageData.
Al ser una estructura puntero el acceso como sigue: nombre_variable >
nombre_del_campo
Paraunaimagenmonocanalcodificadaenbytes,utilizamoselsiguientecdigo:
IplImage*img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);

intheight=img>height;//obtenemoslaalturadelaimagenen
pxeles

intwidth=img>width;//anchuradelaimagenenpxeles

intstep=img>widthStep/sizeof(uchar);//calculamoselvalordel
paso
uchar*data=(uchar*)img>imageData;//cargamoslosdatosdela
imagenendata

data[i*step+j]=111;//fijamoselpixel(i,j)aundeterminado
valor

Paraunaimagenmulticanalcodificadaenbytes,deberemosescribir:
IplImage*img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3);

intheight=img>height;//obtenemoslaalturadelaimagenen
pxeles

intwidth=img>width;//anchuradelaimagenenpxeles

intstep=img>widthStep/sizeof(uchar);//calculamoselvalordel
paso
intchannels=img>nChannels;//obtenemoselnmerodecanalesde
laimagen

uchar*data=(uchar*)img>imageData;//cargamoslosdatosdela
imagenendata

data[i*step+j*channels+k]=111;//fijamoselvalordeunodelos
canalesdelpixel(i,j)aun
determinadonivel,siendo:
//

k=0paraelazul

//

k=1paraelverde

//

k=2paraelrojo

Comoventajasprincipalesdelaccesoalospxelesconpunterospodemoscitarque
esunsistemarelativamentesencillo(aunquemenosqueelanterior),ysobretodoesun
accesocontasasdeeficienciamuyelevadas.

Mtodo3:Accesodirecto
Esta es una de lasmejoresformasde accedera lospxeles,aunque su
sintaxisesunpocomenosevidentequelasanteriores.
Para imgenes de un solo canal definimos el valor de un pxel a una cuanta
arbitraria,porejemplo111.
IplImage*img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);//imagen
de1canal
((uchar*)(img>imageData+i*img>widthStep))[j]=111;//accesoal
elementoi,j

Paraimgenesmulticanal:
IplImage*img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3);//imagen
de3canales
((uchar*)(img>imageData+i*img>widthStep))[j*img>nChannels+
0]=111;//B
((uchar*)(img>imageData+i*img>widthStep))[j*img>nChannels+
1]=112;//G
((uchar*)(img>imageData+i*img>widthStep))[j*img>nChannels+
2]=113;//R

Seaccedeenelprimercasoalcolorazul,enelsegundoalverdeyenelterceroal
rojo.Lafilosofadelmtodoeslamismaqueenelmtodo2,peroenestaocasinde
formamscomprimidayeficiente.

Mtodo4:Utilizandolainformacindelasfilas
Sehaceusodeunafuncinauxiliarcomoenelcasoinicialparaelaccesoalos
datos,yunavezestncargadosseoperaconelloscomosidematricessetrataran.En
estaocasinutilizamoslafuncincvGetRawData:

uchar*data;
cvGetRawData(img,(uchar**)&data);
data[x*img>Width+y]=111;

Ejemplosdeaccesoapxeles
EnprimerlugarutilizamoselMtodo1(cvGet2D,cvSet2D)paraelaccesoalos
pxeles:

#include"cv.h"
#include"highgui.h"
#include<stdio.h>
charname0[]="lena.jpg";
inti=2,j=2;
intmain()
{
IplImage*imagen=NULL;//seinicializaimagen
imagen=cvLoadImage(name0,1);//secargalaimagen
CvScalars;//definimoselescalardondesealmacenar
//elvalordelpxel
s=cvGet2D(imagen,i,j);//seobtieneelvalordelpxel(i,j)
printf("B=%f,G=%f,R=%f\n",s.val[0],s.val[1],s.val[2]);
//ens.val[0]quedaalmacenadoelprimer
//color,ens.val[1]elsegundo...
cvReleaseImage(&imagen);
return0;
}

Ahora vamos a utilizar un acceso ms eficiente mediante punteros. Para ello


aplicamoselmtodo3:

#include"cv.h"
#include"highgui.h"
#include<stdio.h>
charname0[]="lena.jpg";
inti=2,j=2;//elementoalqueacceder
intmain()
{
IplImage*imagen=NULL;//inicializoimagen
ints;
imagen=cvLoadImage(name0,1);//cargamoslaimagen
((uchar *)(imagen>imageData+i*imagen>widthStep))[j*imagen>nChannels
+0]=111;//B
((uchar *)(imagen>imageData+i*imagen>widthStep))[j*imagen>nChannels
+1]=112;//G
((uchar *)(imagen>imageData+i*imagen>widthStep))[j*imagen>nChannels

+2]=113;//R
//paracomprobarsiefectivamenteelvalorhasidotomado,
//leemoselcanalazuldelpxel
s = ((uchar *)(imagen>imageData + i*imagen>widthStep))[j*imagen
>nChannels+0];
printf("B=%d\n",s);//imprimimoselresultado
//(debeser111sifuncionacorrectamente);
cvReleaseImage(&imagen);
return0;
}

Gestionardistintostiposdeimgenes
Una imagen no es ms que una matriz o un array bidemensional de nmeros,
siendocadaceldaelequivalenteaunpxel.Lasimgenesposeendimensionesdeancho
xalto(widthxheight),siendoelancholascolumnasyelaltolasfilas.

Formatosdeficheros

FormatoBMP
EsteformatofuedesarrolladoporMicrosoftparapermitirunarpidaentrada/salida
pordisco/pantalla.
Entrelascaractersticasdeestetipodealmacenamientodestacalagrancantidadde
nivelesdeprofundidadqueoferta:1bitporpxel(imagende2coloresobinaria),4bits
porpxel(imagende16colores),y24bitsporpxeloloqueeslomismo3bytes
(imagendecolor).
Este formato utiliza compresin sin prdida: RLE o sin comprimir. Adems, el
almacenamientoesbottomleft(seempiezaporlaparteinferiorizquierda),yentrelaza
loscanales.
Lasventajasdeesteformatosonlassiguientes:

Nohayprdidadecalidadenlasimgenes

Lalecturayescriturasonmuyrpidas

Elformatoesmuysencillo:cabecera+datos

Encuantoalosinconvenientespodemoscitar:

El tamao de las imgenes es excesivamente grande, sobre todo en

imgenesfotogrficas.

Tamao_imagen=(aprox)ancho*alto*bits_por_pxel

Noesadecuadoparalatransmisinporred.

EspocopopularfueradelosentornosdeMSWindows(aunqueestlibrede

patentes)
Algunasdelasaplicacionesdeesteformatoson:

Aplicacionesquerequieranunarpidasalidaporpantalla.

Aplicaciones donde no deba haber prdida de calidad, aun a costa del

tamao

FormatoTIFF
Fue creado por Aldus (ahora Adobe) pensado en trabajos de impresin de alta
resolucinycalidad.
Esteesunformatomuyflexible,basadoentags(etiquetas)quesonbloquesdedatos
(de formato predefinido) que contienen cierto tipo de informacin sobre la imagen.
Existenmuchostiposdetags(ysepuedencrearnuevos).Unficheropuedecontener
muchostags,unodetrsdeotro.
steesunodelosformatosmsabiertosqueexiste:admitehasta64000canales,un
nmero arbitrario de bits por pxel (hasta enteros o reales de 64 bits), distintos
espacios de color, mltiples imgenes por fichero, cualquier tipo de compresin
existente...

Caberesearqueunaimagensepuedealmacenarportiras(cadauna1tag).
Comoventajasdeesteformatotenemos:

Esindependientedelaplataforma,flexibleyampliable.

Puedeadaptarseamuchostiposdenecesidades.

Puedecontener(encapsular)ficherosconotrosformatos.

Losinconvenientesdelformatoson:

Esdemasiadoflexible,porloqueesdifcilcrearunprogramaquesoporte

todaslasopcionesytiposdetags.

Elalmacenamientoentirasesinadecuadoparaciertosusos.

Algunasdelasaplicaciones:

Edicindefotografadealtacalidad,comoimpresindecarteles

Aplicacionesconnecesidadesespeciales,comoimgenesmultiespectrales,

conaltaresolucindecolor...

FormatoJPEG
Esunformatobastantereciente,estmselaboradoyorientadoalalmacenamiento
deimgenesfotogrficas.
Admitetantoimgenesenescaladegrises(1byteporpxel)comoimgenesencolor
RGB(3bytesporpxel).Adems,incluyemecanismosavanzadosdecompresin,que
puedenajustarseadistintosratiosdecompresin.
Unadesusprincipalescaractersticaseslacompresinconprdida,medianteDCT.
Elficheropuedeincluirunaversinreducidaparaprevisualizarlaimagenantesde
leerla.
Otroaspectoatenerencuentaesqueseencuentralibredepatentes.

Ventajas:
Enlamayoradeloscasosconsigueunratiocompresin/calidadmuchomejorque
losotrosformatos.Adems,suniveldecompresinesajustable,tpicamenteentre
1:10y1:100
Esunformatomuypopularycasiexclusivoenmuchosmbitos.
Inconvenientes:
Poseecompresiones/descompresionescomplejasycostosas
Noincluyetransparenciasnianimaciones
Lainformacinperdidanoserecupera.SitrabajamosconunJPEGguardandoen
discotrascadaoperacin,laimagensevadegradando.
Aplicaciones:
Se utiliza prcticamente en todas las aplicaciones de fotografa digital: captura,
almacenamiento,transmisin,impresin...
Noesconvenienteutilizarlosinosepermiteprdidadecalidadosisetrabajacon
dibujos.

Tiposdeimgenes
Las imgenes que vamos a tratar son bsicamente de tres tipos: imgenes de
intensidad,binariasodecolor.

Imagenbinaria
Laprincipalcaractersticadelasimgenesbinariasesquesoloutilizandosnivelesde
intensidadparasucodificacin:elblancoyelnegro,olosbits1y0.
Enestetipodeimgenes1pxelcorrespondecon1bit,luegoeseltipomssencillo
quenosvamosaencontrar.

Imagendeintensidad
Las imgenes de intensidad tambin son conocidas como imgenes en escala de
grises,ysuprincipalcaractersticaesquepermitencodificarunpxelcon255niveles
degrisdistintos:siendoel0=negroyel255=blanco.
Enestetipodeimgenes1pxelsecorrespondecon1byte,deahlos255niveles
permitidos.

Imgenesdecolor
Enlaimgenesdecolorcadapxelsecodificacontrescoloresdistintos(rojo,verdey
azul),teniendocadacolorlaprofundidadde1byte.
Por tanto, cada pxel se codificar con 3 bytes, siendo el nmero total de colores
posiblesdelordende16,7millones.Estoesloquesellamaunaimagenmulticanal,en
estecasode3canales.AunquetambinexistenimgenesRGBAdecuatrocanales
dondeelcuartocanalindicaelniveldetransparenciadeunpxel,conaplicacionesen
visinnocturnaoimgenesporsatlite.Estetipodeimgenesnolasvamosatratar.
ExistendosformasbsicasdealmacenamientodeunaimagenRGB,comosonel
entrelazado(dondesealmacenasiguiendoR0 G0 B0,R1G1 B1, R2G2 B 2 ...)oelno
entrelazado(dondesealmacenasiguiendoR0R1R2...,G0G1G2...,B0B1B2...).
Perotodoestonoestlimitadoaunosparmetrossinoqueexisteninfinitostipos

posibles,yaqueunniveldegrisouncolorsepuedenrepresentarconmsomenosbits,
loquesellamaprofundidaddecolor(depth).Astambinexistenlasimgenesenpunto
flotantequesontilesparaprocesosintermediosdonde1pxel=1floatodouble.

Tiposdedatosdeunpxel
Unpxelpuedetomarunagrancantidaddetiposdedatosposible,parasaberel
tipodedatodeunpxelbastarconaccederalcampodepthdelaimagen,noobstante
existeunciertonmerodetiposdedatospermitidos,queyaexpusimosenladescripcin
delaestructuraIplImage,peroquevolvemosahaceraquparamayorclaridad:

IPL_DEPTH_8U:Enterossinsignode8bits(unsignedchar)

IPL_DEPTH_8S:Enterosconsignode8bits(signedcharosimplementechar)

IPL_DEPTH_16S:Enterosde16bitsconsigno(shortint)

IPL_DEPTH_32S:Enterosconsignode32bits(int)

IPL_DEPTH_32F:Nmerosenpuntoflotanteconprecisinsimplede32bits(float)

Transformacionesafines
Seentiendeportransformacinafncualquiertipoderotacinescaladootraslacin
queseproduzcaenlasdosdireccionesespacialesdelplano.Comotransformaciones
afinesprincipalespodemoscitar:elescalado,larotacinylatraslacin.
Elelementobsicodetodatransformacinafneslamatrizdetransformacin,que
serlaencargadadedefinirlaclaseylosparmetrosdelatransformacinarealizar.As,
tendremossiempreunamatrizasociadatantoparaelescalado,comoparalarotacin,
comoparalatraslacin.

Traslacin
Latraslacintambinesconocidacomodesplazamiento,ysebasaenelcambio
deposicindeunobjetodeacuerdoconunafrmula.
Por lo tanto, la imagen de salida obtenida se relaciona con la entrada de la
siguientemanera:
Img_resultado(x,y)=Img_origen(x+dx,y+dy)
Siendo,dx=desplazamientoenelejehorizontal
dy=desplazamientoenelejevertical

De forma grfica, podemos ejemplificar lo anterior con las siguientes figuras


(suponiendoquecadacuadradoequivaleaunpxel):

Situacin
Aplicamostraslacin(1,1)
Aplicamostraslacin(1,1)
inicialImg_result(x,y)=Img_org(x+1,y+1)Img_rs(x,y)=Img_or(x1,y1)

Altrasladarlaimagenaparecenpxelesquenoquedandefinidos.Alahorade
programar tomaremos estos pxeles como 0, es decir color negro. Las funciones que
utilizaOpencvparalatraslacin,noasignanningnvaloraestosrecuadros,conloque
tenemoslibertadparaasignarleselvalormsconveniente.
El parmetro que nos definelas caractersticasde la traslacin esla matriz de
transformacin,queenestecasoesdeltipo:
Matrizdetransformacin=
1

dx

dy

En Opencv toda transformacin afn se puede implementar con la funcin


cvWarpAffine quegeneraunaimagendesalidaalaqueselaaplicalatransformacin
correspondiente.Losparmetrosdeestafuncinsonlossiguientes:
voidcvWarpAffine(constCvArr*src,CvArr*dst,constCvMat*map_matrix,
intflags=CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS,
CvScalarfillval=cvScalarAll(0));
Siendocadaunodeellos:

src:Imagenfuente,alacualseleaplicalatransformacin.

dst:Imagendestino,dondeseobtienelatransformacinrealizada.

map_matrix:Matrizdetransformacin,dedimensiones2x3.

flags:

Lostiposdeinterpolacinpuedenser:

CV_INTER_NN:Interpolacintipovecinomsprximo

CV_INTER_LINEAR:Interpolacinbilineal(eslaqueseutiliza
pordefecto)

CV_INTER_AREA:Seutilizalarelacindepxelyreaparaasignarvalores.Enel
casodeampliarlaimagenactaanlogamenteaelmtodoCV_INTER_NN.

CV_INTER_CUBIC:Interpolacinbicbica.

Loqueacontececonlospxelessobrantes,seconfiguraconlas
siguientesopciones:

CV_WARP_FILL_OUTLIERS:Rellenatodoslospxelesdelaimagen

destino.Sialgunosdeelloscorrespondenconpartesquequedan
fueradelaimagenorigen,sonrellenadosaunvalorfijo.

CV_WARP_INVERSE_MAP:Indicaquelamatrizrepresentalarelacin
detransformacininversa,esdecir,delaimagendestinoala
fuente,porloquepuedeserutilizadaparalainterpolacinde
pxeles.

fillval:Eselvalorderellenoqueseusaparadefinirlostrozosque
quedanfueradelaimagen.

Porlotantoesnecesariodefinirpreviamentealaaplicacindeestafuncin,su
matrizdetransformacin.

Ejemplodetraslacin
El siguiente programa implementa una traslacin haciendo uso de los
recursosqueproporcionaOpencv.

#include"cv.h"
#include"highgui.h"
#include"math.h"
#include<stdio.h>
intmain(intargc,char**argv)
{
IplImage*src;
/*elprimerparmetroquesepaseporconsoladebeser
elnombredelfichero*/
if(argc==2&&(src=cvLoadImage(argv[1],1))!=0)
{
IplImage*dst=cvCloneImage(src);//clonamoslaimagen
//fuente,paraquelaimagendestino
//tengalosmismosparmetrosespacialesquelafuente
intdx=40;//desplazamientoenpxelesenelejex;
intdy=40;//desplazamientoenpxelesenelejey;
CvMat*M=cvCreateMat(2,3,CV_32FC1);
//staserlamatrizdetransformacin
cvmSet(M,0,0,1);//asignamosvalor1alelemento(0,0)
cvmSet(M,0,1,0);//asignamosvalor0alelemento(0,1)
cvmSet(M,1,0,0);//asignamosvalor0alelemento(1,0)
cvmSet(M,1,1,1);//asignamosvalor1alelemento(1,1)
cvmSet(M,0,2,dx);//elcuartonmeroindicalospxeles
//queserecorrenenelejex
//Paraelloasignamosesenmeroalelemento(0,2)
//delamatrizdetransformacin
cvmSet(M,1,2,dy);//idemejey

cvWarpAffine(src,dst,M,CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS,
cvScalarAll(0));
//aplicamoslatransformacin,asignandoalospxelesno
//definidoselvalor0(colornegro)
cvNamedWindow("origen",1);//dibujamoslaimagendeentrada
cvNamedWindow("resultado",1);//dibujamoslaimagenresultante
cvShowImage("origen",src);
cvShowImage("resultado",dst);
cvWaitKey(0);//paraterminarelprogramapulsartecla
cvDestroyAllWindows();//destruimostodaslasventanas

cvReleaseImage(&src);
cvReleaseImage(&dst);
cvReleaseMat(&M);
}
elseexit(0);
cvReleaseImage(&src);
return0;
}

Comocomentarioadicional,enesteprogramahemoscomprobadoquelaimagen
src ha sido cargada correctamente (src no es un puntero nulo). Esto es bastante
conveniente.
Comosalidadeesteprogramasemuestrandosimgenes,laprimeradeellasesla
imagen origen, sobre la que vamos a realizar la traslacin. En la segunda figura se
muestralaimagenresultadodeaplicarlatraslacinalaimagenorigen.
Ambasfiguras(6y7),semuestranacontinuacin:

Figura6

Figura7

Escalado
Elescaladoesunatransformacinafnquepuedeaumentarodisminuirunobjeto
porundeterminadofactor.
La imagen que se obtiene a la salida se relaciona con la entrada siguiendo la
siguienteregla:

Imag_destino(x,y)=Imag_origen(ex*x,ey*y)
siendo:
ex:escalaenelejex
ey:escalaenelejey

Dentro del escalado existen dos supuestos bsicos: que la imagen de salida
aumente con respecto a la imagen de entrada (aumento), o que la imagen de salida
disminuyaconrespectoalaimagendeentrada(reduccin).Laaplicacindeunauotra
dependerdelfactordeescalaqueintroduzcamos.

Siexoeysonmayoresque1,seproduceunaumentoozoomdelaimagen.

Siexoeysonmenoresque1,seproduceunadisminucindelaimagen.

Siexoeysoniguala1,laimagenquedainvariante.

As,enfuncindelaumentoodeladisminucinquerealicemoslaimagendesalida
quedarcodificadaconundeterminadonmerodepxeles:

Silaimagendeentradaesdetamaopx*py,laimagendesalidaserde

tamaopx/ex*py/ey.

ConlalibreraOpencvexistendosmodosbsicosderealizarestasoperaciones:
podemos utilizar la funcin genrica de transformaciones afines cvWarpAffine, o una
funcinespecficadeescaladocvResizequenosaportaungradomayordeversatilidad.
Tambinresultaimprescindibledefinirlamatrizdetransformacinquenosdictar

losparmetrosdelamisma:

Matrizdetransformacin=

ex

ey

Ejemplosdeescalado
En primer lugar vamos a mostrar un programa que escala una imagen con la
funcingenricacvWarpAffine.

#include"cv.h"
#include"highgui.h"
#include"math.h"
#include<stdio.h>
intmain(intargc,char**argv)
{
IplImage*src;
/*elprimerparmetroquesepaseporconsola
debeserelnombredelfichero*/
if(argc==2&&(src=cvLoadImage(argv[1],1))!=0)
{
IplImage*dst=cvCloneImage(src);
//clonamoslaimagenfuente,paraquelaimagendestino
//tengalosmismosparmetrosespacialesquelafuente
floatex=1;//factordeescalaenelejex;
floatey=0.5;//factordeescalaenelejey;
CvMat*M=cvCreateMat(2,3,CV_32FC1);
//matrizdetransformacin(2x3)
cvmSet(M,0,0,ex);//factordeescalaejex
cvmSet(M,0,1,0);//asignamosvalor0alelemento(0,1)
cvmSet(M,1,0,0);//asignamosvalor0alelemento(1,0)
cvmSet(M,1,1,ey);//factordeescalaejey
cvmSet(M,0,2,0);//asignamosvalor0alelemento(0,2)
cvmSet(M,1,2,0);//asignamosvalor0alelemento(1,2)
cvWarpAffine(src,dst,M,CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS,
cvScalarAll(255));
//aplicamoslatransformacin,asignandoalospxelesno
//definidoselvalor0(colornegro)

cvNamedWindow("origen",1);//dibujamoslaimagenresultante
cvShowImage("origen",src);
cvNamedWindow("resultado",1);//dibujamoslaimagenresultante
cvShowImage("resultado",dst);
cvWaitKey(0);//Esperaapulsarunatecla
cvDestroyAllWindows();//destruimostodaslasventanas
cvReleaseImage(&src);

cvReleaseImage(&dst);
cvReleaseMat(&M);
}
elseexit(0);
cvReleaseImage(&src);
return0;
}

Enlafigura9seapreciaelresultadodeaplicarunescaladoalaimagenoriginal
(figura8).Enestecasonicamentesehaescaladosobreelejevertical(ejey),aplicando
unfactordeescalade0,5,esdecir,reducindolaalamitad.Elejehorizontal(ejex),
permaneceintacto(factordeescala1).

Figura8

Figura9

Pasamos a mostrar un segundo programa de escalado utilizando la funcin


cvResize.Enprimerlugaresnecesariocomprenderestafuncinysusparmetros:
voidcvResize(constCvArr*src,CvArr*dst,
intinterpolation=CV_INTER_LINEAR);
Siendo:

src:Imagenfuente.

dst:Imagendestino.

interpolation:Tipodeinterpolacin.Lainterpolacinpuedeserde
lossiguientesmodos:

CV_INTER_NN:Interpolacintipovecinomsprximo

CV_INTER_LINEAR:Interpolacinbilineal(eslaqueseutiliza
pordefecto)

CV_INTER_AREA:Seutilizalarelacindepxelyreapara
asignarvalores.Enelcasodeampliarlaimagenacta
anlogamenteaelmtodoCV_INTER_NN.

CV_INTER_CUBIC:Interpolacinbicbica.

Elusodeestafuncinamplialasposibilidadesdeinterpolacin.Porejemplo,si
ampliamos una imagen la opcin ms adecuada sera la utilizacin de interpolacin
bilinealobicbica.
Tambinesimportanteremarcar,queenestecasoelfactordeescalasedefineen
pxeles, es decir, el propio usuario decide las dimensiones tanto horizontales como
verticalesdelaimagendesalida.
Pasamosamostrarunprograma,queescalaunaimagenconestafuncin:
#include"cv.h"
#include"highgui.h"
#include<stdio.h>
charname0[]="lena.jpg";//enestaocasincargamos
//elficheroenelpropioprograma
intmain()
{
IplImage*imagen=NULL;//inicializoimagen
imagen=cvLoadImage(name0,1);//cargamoslaimagen
intpx=200;//pxelesenelejexdelaimagenescalada,
//esdecir,estamosdefiniendolaescalaX
intpy=400;//pxelesenelejexdelaimagenescalada,
//esdecir,estamosdefiniendolaescalaY
IplImage*resized=cvCreateImage(cvSize(px,py),IPL_DEPTH_8U,3);
//creamoslaestructura
//dondeubicaremoslaimagenescalada,
//siendopxypylospxelesdelaimagen
//destino,esdecir,elpropiofactordeescala
cvResize(imagen,resized,CV_INTER_LINEAR);//escaladodelaimagen
cvNamedWindow("test",1);//representamoslaimagenescalada
//(conel1indicamosquela
//ventanaseajustealosparmetrosdelaimagen)
cvShowImage("test",resized);
cvWaitKey(0);//pulsamoscualquierteclaparaterminarelprograma
cvDestroyAllWindows();//destruimostodaslasventanas
cvReleaseImage(&imagen);
cvRelase(Image(&resized);
return0;
}

Enestecasoladefinicindelescaladoesunpocodistinta,yaqueseindicaal
programaelnmerodepxeles,tantoverticalescomohorizontales,queconstituirnla
imagenresultado.

Enlafigura10semuestralaimagendeentrada,yenlafigura11obtenemosla
imagenescalada,asignandoalejeverticaldelaimagenescalada400pxelesdelongitud
yasuejehorizontal200pxeles.Elresultadosemuestraacontinuacin:

Figura10
Figura11

Rotacin
Larotacinesunatransformacinenlaquelosejesdecoordenadassonrotados
undeterminadongulorespectoalorigen.
Lasoperacionesenlascoordenadasquesellevanacaboenlarotacinsepueden
sintetizarenlasiguienterelacin:
Imagen_resultado(x,y)=Imagen_inicial(xcos+ysen,
xsen+ycos)
siendo=nguloderotacin

Esdecir,siReslamatrizderotacin:

cos()

sen()

sen()

cos()

yresunvectorcolumna:
x
y
EntoncesImagen_destino(x,y)=Imagen_origen(Rr)

Conlamatrizdefinidaanteriormentelarotacinserealizarespectoalpunto(0,0)
pero si queremos definir un centro de rotacin en el punto (cx, cy), la matriz de
transformacincambia,siendodelsiguientemodo:

cos()

sen()

cxcxcos()cysen()

sen()

cos()

cy+cxsen()cycos()

Puesahorasolorestaaplicarestosconceptosparaimplementarlaoperacinde
rotacin.Opencvofrecedosposibilidadesdistintaspararealizarestaoperacin.Porun
lado est el uso de la funcin genrica para transformaciones afines cvWarpAffine
acompaada de la funcin cv2DRotationMatrix que calcula la matriz de rotacin
necesaria.PorotroladodisponemosdelafuncincvGetQuadrangleSubPixquerealizala
mismafuncinquelaanteriorconalgunamatizacin:

La funcin cvWarpAffine exigeque tanto imagen de entradacomo de salida

tengan el mismo tipo de datos, mientras que cvGetQuadrangleSubPix permite


compaginartiposdedatosdistintos.

LafuncincvWarpAffinepuededejarpartedelaimagendesalidasinrellenaro

sin modificar su valor anterior, mientras que en cvGerQuadrangleSubPix todos los


puntos de la imagen de salida toman un valor, incluso aquellos que no estn
directamentedefinidossonasignadosalvalordelpxelmsprximo.

Ejemplosderotacin
Comenzamosestudiandoelcasoderotarunaimagenutilizandolafuncingenrica
cvWarpAffine,

ya estudiada. Sin embargo, debemos introducir la funcin

cv2DRotationMatrixparaelclculodelamatrizdetransformacin:
CvMat*cv2DRotationMatrix(CvPoint2D32fcenter,doubleangle,double
scale,CvMat*map_matrix);
Siendo:

center:Centroderotacindelaimagen(unacoordenadaen2D)

angle:Elnguloderotacinengrados.Valorespositivosdeeste
ngulorotanlaimagenenelsentidocontrarioalasagujasdelreloj.
Elorigendecoordenadassesuponequeseencuentraenlaesquina
superiorizquierdadelaimagen.ElngulosedaenGRADOS.

map_matrix:Punteroalaubicacindelamatrizdedimensiones2x3.
Eslasalidadelafuncin,esdecir,lamatrizderotacindeseada.

Pasamos a mostrar un programa que utiliza estas estructuras para rotar una
imagen:
#include"cv.h"
#include"highgui.h"
#include<stdio.h>
charname0[]="pasillo1.jpg";
intmain()
{
IplImage*imagen=NULL;//inicializoimagen
imagen=cvLoadImage(name0,1);//cargamoslaimagenarotar
//definimoslaimagendesalidadonde
//serepresentaraalaimagenrotada
IplImage *rotated=cvCreateImage(cvGetSize(imagen),IPL_DEPTH_8U, imagen
>nChannels);
CvPoint2D32fcenter;//definimoselelcentrodelarotacin
intangle=30;//definimoselnguloderotacinengrados
CvMat*mapMatrix=cvCreateMat(2,3,CV_32FC1);
//definimoslasdimensionesdelamatrizdetransformacin
center.x=160;//asignamoslacoordenadaxdelarotacinquedeseemos
center.y=120;//asignamoslacoordenadaydelarotacinquedeseemos
cv2DRotationMatrix(center,angle,1.0,mapMatrix);
//calculalosvaloresdemapMatrix
cvWarpAffine(imagen,rotated,mapMatrix,CV_INTER_LINEAR
+CV_WARP_FILL_OUTLIERS,
cvScalarAll(0));
//realizalatransformacinderotacin

cvNamedWindow("origen",1);//representalaimagenrotada
cvShowImage("origen",imagen);
cvNamedWindow("resultado",1);//representalaimagenrotada
cvShowImage("resultado",rotated);
cvWaitKey(0);//esperaapulsarteclaparafinalizar
cvDestroyAllWindows();//destruimostodaslasventanas
cvReleaseImage(&imagen);
cvReleaseImage(&rotated);
cvReleaseMat(&mapMatrix);
return0;
}

Alaplicarunarotacinsobreunaimagencualquiera(figura12),conuntamaode
320x240pxeles.Obtenemoslaimagenrotadaqueseobservaenlafigura13.Elcentro
de la rotacin coincide en este caso con el centro de la imagen (160 x 120). Se ha
definidounnguloarbitrarioderotacinde30grados.Lapartedelaimagenrotadaque
quedasindefinir,sehafijadoacolorblanco.

Figura12

Figura13

El segundo caso de rotacin bajo anlisis utiliza la funcin


cvGetQuadrangleSubPix, enestecasodefinimoslamatrizdetransformacindeforma
artesanal.Vamosaestudiarlosparmetrosdelafuncin:
voidcvGetQuadrangleSubPix(constCvArr*src,CvArr*dst,constCvMat*
map_matrix);
Siendo:

src:Imagenquequeremosrotar.

dst:Trozodelaimagensrcquetomamos.Ennuestrocasotomaremosla
imagenentera(dimensionesdesrcigualesalasdedst).

map_matrix:Lamatrizdetransformacin(3x2).

Loqueenrealidadhaceestafuncinestomarpxelesdelaimagenoriginalcon
unaprecisin mayor,ylosrepresenta en la imagen destino con esa mayorprecisin,
aplicandolarelacindetransformacindefinidaporlamatriz.
Elsiguienteprogramamuestracomorotarunaimagenconesafuncin:
#include"cv.h"
#include"highgui.h"
#include"math.h"
intmain(intargc,char**argv)
{
IplImage*src;
if(argc==2&&(src=cvLoadImage(argv[1],1))!=0)
//cargamoslaimagenensrc
{
IplImage*dst=cvCloneImage(src);
//hacemosunacopiadelaimagenendst,paraque
//laimagendestinoposealosmismosparmetrosquelaorigen
intangle=25;//definimoselnguloderotacin
floatm[6];//componentesdelamatrizM
CvMatM=cvMat(2,3,CV_32F,m);//matrizdetransformacin
intw=src>width;//anchuraenpxelesdelaimagen
inth=src>height;//alturaenpxelesdelaimagen
m[0]=(float)(cos(angle*2*CV_PI/180.));//elementosdelamatriz
m[1]=(float)(sin(angle*2*CV_PI/180.));
m[2]=w*0.5f;
m[3]=m[1];
m[4]=m[0];
m[5]=h*0.5f;
cvGetQuadrangleSubPix(src,dst,&M);//aplicamoslarotacin
cvNamedWindow("origen",1);//representamoslarotacin
cvShowImage("origen",src);
cvNamedWindow("resultado",1);//representamoslarotacin
cvShowImage("resultado",dst);
cvWaitKey(0);//pulsarteclaparaterminar
cvDestroyAllWindows();
cvReleaseImage(&dst);
}
elseexit(0);
cvReleaseImage(&src);
return0;
}

Alaplicarlarotacinsobrelafigura14obtenemoslaimagenrepresentadaenla
figura15.Elcentrodelarotacineselcentrodelaimagenyesngulodegiroseha
fijadoa25grados.Comonovedaddestacaelrellenodelapartedelaimagenrotadaque
quedasindefinir,conlosvaloresquestaposeeenelcontornodelamisma.

Figura14

Figura15

Binarizacindeimgenes
Enestaseccinsepretendedaraentenderlasarmasconlasquenosprovee
Opencv para el cambio de codificacin entre imgenes. As, el principal objetivo es
encontrarunafuncinoconjuntodefuncionesquerealicenlamismaoperacinquelas
estructurasgraythreshyim2bwrealizanenMatlab.
Portanto,debemossercapacesdetomarunaimagenenescaladegrises(imagen
deintensidad)yconvertirlaenimagenbinaria,mediantelaaplicacindeunumbral.Todos
losvaloressuperioresalvalorumbralsernbinarizadosa1ylosquenosuperenese
valorloserna0.
OpencvproporcionalafuncincvThresholdparaelprocesodebinarizacin.Vamos
aanalizarlamsenprofundidad:

voidcvThreshold(constCvArr*src,CvArr*dst,doublethreshold,double
max_value,
intthreshold_type);
Siendo:

src:Imagenorigen.Podrtenercodificacinde8bitsode32bits
enpuntoflotante.

dst:Imagendesalida.Deberserde8bitsodeigualtipoquela
sealdeentrada.

threshold:Elvalorumbraldelabinarizacin.

max_value:Valormximoautilizarparalosdostiposdebinarizacinmsfrecuentes

(CV_THRESH_BINARYyCV_THRESH_BINARY_INV).

threshold_type:Eltipodebinarizacinarealizar.Exponemoslos
tiposexistentes:

threshold_type=CV_THRESH_BINARY:dst(x,y)=max_value,si
src(x,y)>threshold
0encasocontrario.

threshold_type=CV_THRESH_BINARY_INV:dst(x,y)=0,si
src(x,y)>thresholdmax_valueencasocontrario.

threshold_type=CV_THRESH_TRUNC:dst(x,y)=threshold,si
src(x,y)>threshold
src(x,y)encasocontrario.

threshold_type=CV_THRESH_TOZERO:dst(x,y)=src(x,y),si
(x,y)>threshold
0encasocontrario.

threshold_type=CV_THRESH_TOZERO_INV:dst(x,y)=0,si
src(x,y)>threshold
src(x,y)encasocontrario.

ApartedeestatransformacinOpencvtambinnosdalaposibilidaddetransformar
unaimagenRGBenotraenescaladegrises,utilizandolafuncincvCvtColor:
voidcvCvtColor(constCvArr*src,CvArr*dst,intcode);
Siendo:

src:Laimagenorigencodificadaen8bitsoenpuntoflotante

dst:Laimagendestinocodificadaen8bitsoenpuntoflotante

code:Definelaoperacindeconversinallevaracabo.Esta
operacinsedefineutilizandolasconstantes
CV_<espacio_de_color_origen>2<espacio_de_color_destino>.
Caberemarcarqueexistengrancantidaddecombinacionesquesepueden
llevaracabo.Nosotrosestamosinteresadosenlatransformacin
BGR2GRAY.Todaslascombinacionesposiblessepuedenconsultarenel
manualdelafuncin.

Ejemplodebinarizacin
Pasamosaenunciarunejemplodeestafuncin:
#include"cv.h"
#include"highgui.h"
#include"math.h"
intmain()
{
IplImage*src;//imagendecolorbase
IplImage*colorThresh;//contendrlaimagendecolorbinarizada
IplImage*gray;//contendrlaimagenconvertidaenescaladegrises
IplImage*grayThresh;//imagenbinariaconseguida
//apartirdelaimagenenescaladegrises
intthreshold=120;//definimoselvalorumbral
intmaxValue=255;//definimoselvalormximo
intthresholdType=CV_THRESH_BINARY;//definimosel
//tipodebinarizacin
src=cvLoadImage("out4553.pgm",1);//cargamosimagendecolor
colorThresh=cvCloneImage(src);//copiamosesaimagendecolor
gray=cvCreateImage(cvSize(src>width,src>height),IPL_DEPTH_8U,1);
//laimagendeintensidadtendrlamismaconfiguracin
//quelafuenteperoconunsolocanal
cvCvtColor(src,gray,CV_BGR2GRAY);//pasamoslaimagendecolor
//aescaladegrises
grayThresh=cvCloneImage(gray);//copiamoslaimagenenescala
//degrises(trucoanterior)
cvNamedWindow("src",1);//representamoslaimagendecolor
cvShowImage("src",src);
cvNamedWindow("gray",1);//representamoslaimagendeintensidad
cvShowImage("gray",gray);
cvThreshold(src,colorThresh,threshold,maxValue,thresholdType);
//binarizamoslaimagendecolor
cvThreshold(gray,grayThresh,threshold,maxValue,thresholdType);
//binarizamoslaimagendeintensidad
cvNamedWindow("colorThresh",1);//representamoslaimagen
//decolorbinarizada
cvShowImage("colorThresh",colorThresh);
cvNamedWindow("grayThresh",1);//representamoslaimagen
//deintensidadbinarizada
cvShowImage("grayThresh",grayThresh);
cvWaitKey(0);//pulsamosteclaparaterminar
cvDestroyWindow("src");//destruimostodaslasventanas

cvDestroyWindow("colorThresh");
cvDestroyWindow("gray");
cvDestroyWindow("grayThresh");
cvReleaseImage(&src);//eliminamostodaslasimgenes
cvReleaseImage(&colorThresh);
cvReleaseImage(&gray);
cvReleaseImage(&grayThresh);
return0;
}

Lafigura16representaunaimagendecolor.Enlafigura17seharepresentadola
imagenanteriorperoconvertidaaescaladegrises.Sobreesaimagenenescaladegrises
se ha realizado la binarizacin, con umbral en nivel de intensidad 120, obteniendo la
instantneadelafigura18.

Figura16

Figura17

Figura18

Operacionesconmatrices
Opencvofertavariasfuncionesdetratamientodematrices,lamayoradeellasse
basan enla realizacin de operacioneselemento porelemento.Sinembargo,nuestro
estudiosebasaenclculomatricialenconjuntoynoelementoporelemento,conloque
noscentraremosenlamultiplicacindematricestradicionalyenelclculodelainversa.

Inversindematrices
Alahoradeinvertirmatricesdeformamanualsebarajandosotresmtodosms
populares.Opencvtambinpermitedefinirelmtodoqueseconsideremsconveniente,
oferta tres caminos distintos por los que invertir una matriz, todos ellos dentro de la
funcincvInvert.Lafuncineslasiguiente:

doublecvInvert(constCvArr*src,CvArr*dst,intmethod=CV_LU);
Ladescripcindelosparmetroseslasiguiente:

src:Lamatrizquesedeseainvertir

dst:Matrizdesalida,contienelainversadelamatrizdeentrada

method:Mtododeinversin.Exponemoslosmtodosadjuntandosu
descripcineningls,paranodistorsionarsusignificado:

CV_LUGaussianeliminationwithoptimalpivotelementchose

CV_SVDSingularvaluedecomposition(SVD)method

CV_SVD_SYMSVDmethodforasymmetricpositivelydefinedmatrix

Ejemplodeinvertirmatrices
Exponemos un ejemplo sencillo para concretar el funcionamiento de la funcin
anterior:
#include"cv.h"
#include"highgui.h"
#include"math.h"
#include<stdio.h>

intmain()
{
CvMat*M=cvCreateMat(2,2,CV_64FC1);//matrizainvertir
CvMat*P=cvCreateMat(2,2,CV_64FC1);//contendrlamatrizinversa
cvmSet(M,0,0,1.0);//definimoslamatrizainvertir
cvmSet(M,0,1,2.0);
cvmSet(M,1,0,3.0);
cvmSet(M,1,1,7.0);
cvInvert(M,P,CV_LU);//invertimoslamatriz
cvReleaseMat(&M);
cvReleaseMat(&P);
return0;
}

Sisedesearavisualizarelresultadodeestainversindematricesporpantalla,la
expresinqueseobtendraseralasiguiente:


1 2
3 7

7 2
3 1

Multiplicacindematrices
La funcin de multiplicar dos matrices no est directamente implementada en
Opencv,perosexistenfuncionesquerealizanlamultiplicacinconalgnmatizaadido.
Estamos hablando de la funcin cvMulMatAdd que aparte de multiplicar dos matrices
tambin suma una tercera al producto, para utilizar esta funcin debemos definir
convenientementelasmatricesutilizandocvInitHeader.Pasamosadarunadescripcinde
estasdosestructuras:

CvMat*cvInitMatHeader(CvMat*mat,introws,intcols,inttype,void*
data=NULL,

intstep=CV_AUTOSTEP

);
Siendo:

mat:Punteroalacabeceradelamatrizquesevaainicializar

rows:Nmerodefilasenlamatriz

cols:Nmerodecolumnasenlamatriz

type:Tipodeloselementosdelamatriz

data:Punteroalacabeceradelamatrizparalaasignacindedatos

step:tamaocompletoenbytesdeunafiladedatos,pordefectose
tomaelmnimopasoposible(CV_AUTOSTEP),esdecir,sesuponequeno
quedanhuecosentredosfilasconsecutivasdelamatriz

LafuncincvMatMulAddevalaelproductodedosmatricesyaadelaterceraal
mismo:
cvMatMulAdd(srcasrcbsrccdst)
siendo:

srca:Primeramatrizamultiplicar

srcb:Segundamatrizamultiplicar

src:Matrizasumaralproductoanterior

dst:Matrizqueguardaelresultadofinaldelasoperaciones

Ejemplodemultiplicacin
ElsiguienteprogramarealizaelproductoMc=Ma*Mb,delsiguientemodo:

#include"cv.h"
#include"highgui.h"
#include"math.h"
#include<stdio.h>
intmain()
{
//Elindicedecolumnaeselquecorreprimero
doublea[]={1,2,3,4,5,6,7,8,9,10,11,12};
//definimosloselementosdelamatriza
doubleb[]={1,5,9,2,6,10,3,7,11,4,8,12};
//definimosloselementosdelamatrizb
doublec[9];//declaramosloselementosdelamatrizc
CvMatMa,Mb,Mc;//declaramoslasmatrices
cvInitMatHeader(&Ma,3,4,CV_64FC1,a,CV_AUTOSTEP);
//Rellenamoslasmatrices
cvInitMatHeader(&Mb,4,3,CV_64FC1,b,CV_AUTOSTEP);
cvInitMatHeader(&Mc,3,3,CV_64FC1,c,CV_AUTOSTEP);
cvMatMulAdd(&Ma,&Mb,0,&Mc);
//realizamoselproductodelasmatrices(3x4)y(4x3)

printf("multiplicacion%f%f%f%f%f%f",c[0],c[1],c[2],c[3],
c[4],c[5]);
return0;

Portantoesteprogramaejecutalaoperacinsiguiente,conelresultadoquese

muestraenlaecuacinsiguiente.

1
1 2
3
4
2
5 6
7
8
3
9 10 11 12
4

5 9
30
70 110
6 10
= 70 174 278
7 11
110 278 446
8 12

BIBLIOGRAFA
Pasamosacitar,lamayorpartedelabibliografautilizadaenlaconfeccindel
manual:

LeedsGuidetoOpencv.CxCoreReferenceManual

Autor:DrewMorgan
ltimaactualizacin:3Noviembrede2006
http://www.comp.leeds.ac.uk/vision/opencv/opencvref_cxcore.htm

CvReferenceManual

Autor:DrewMorgan
ltimaactualizacin:3deNoviembrede2006
http://www.comp.leeds.ac.uk/vision/opencv/opencvref_cv.html

HighGUIReferenceManual

Autor:EdLawson
http://cs.gmu.edu/~vislab/opencvdocs/ref/opencvref_highgui.htm

OpenSourceComputingVisionLibrary.ReferenceManual.Intel

http://www.intel.com/technology/computing/opencv/

ImageProcessingandAnalysisReference

Autor:FranciscoBlanesGmez/LuisM.Jimnez
ltimaactualizacin:17deMayode2006
http://isa.umh.es/pfc/rmvision/opencvdocs/ref/OpenCVRef_ImageProcessing.htm

BasicStructuresandOperationsReference

Autor:FranciscoBlanesGmez/LuisM.Jimnez

ltimaactualizacin:17deMayode2006
http://isa.umh.es/pfc/rmvision/opencvdocs/ref/OpenCVRef_BasicFuncs.htm

ProcesamientoAudiovisual.

Autor:GinsGarcaMateos

IntroductiontoprogrammingwithOpenCV

Autor:GadyAgam
ltimaactualizacin:27deEnerode2006
http://www.cs.iit.edu/~agam/cs512/lectnotes/opencvintro/opencvintro.html

ExperimentalandObsoleteFunctionalityReference

Autor:MauricioFerreira/AurelioMoraes
ltimaactualizacin:8deagostode2007
http://www.tecgraf.pucrio.br/~malf/opencv/ref/opencvref_cvaux.htm

ObjectRecognitionReference

http://isa.umh.es/pfc/rmvision/opencvdocs/ref/OpenCVRef_ObjectRecognition.htm

OpenCvIHighGui

Autor:DavidMilln
ltimaactualizacin:20deMarzode2005
http://www.artresnet.com/david/tutorial.jsp?id=4

Pxelprocessing

Autor:BerndJhne/SpringerVerlag
http://mmc36.informatik.uniaugsburg.de/mediawiki/data/3/37/VSP0607
Lecture2new.pdf

IntroductiontoOpencv

Autor:VadimPisarevsky
ltimaactualizacin:9deJuniode2007
http://fsa.ia.ac.cn/files/OpenCV_China_2007June9.pdf

OpenSourceComputerVisionLibrary

ltimaactualizacin:14deSeptiembrede2006
http://wwwrobotics.cs.umass.edu/Documentation/OpenCV

LushManual

Autor:YannLeCun/LeonBottou
ltimaactualizacin:24deNoviembrede2002
http://lush.sourceforge.net/lushmanual/8193ae9d.html

ForodeOpencvenYahooGroups:ForooficialdelosusuariosdeOpencv

http://tech.dir.groups.yahoo.com/dir/Computers___Internet/Software/Open_Source

GNUFreeDocumentationLicense
GNUFreeDocumentationLicense
Version1.2,November2002

Copyright(C)2000,2001,2002FreeSoftwareFoundation,Inc.
51FranklinSt,FifthFloor,Boston,MA021101301USA
Everyoneispermittedtocopyanddistributeverbatimcopies
ofthislicensedocument,butchangingitisnotallowed.

0.PREAMBLE
ThepurposeofthisLicenseistomakeamanual,textbook,orotherfunctionalandusefuldocument
"free"inthesenseoffreedom:toassureeveryonetheeffectivefreedomtocopyandredistributeit,
withorwithoutmodifyingit,eithercommerciallyornoncommercially.
Secondarily,thisLicensepreservesfortheauthorandpublisherawaytogetcreditfortheirwork,
whilenotbeingconsideredresponsibleformodificationsmadebyothers.
ThisLicenseisakindof"copyleft",whichmeansthatderivativeworksofthedocumentmust
themselvesbefreeinthesamesense.ItcomplementstheGNUGeneralPublicLicense,whichisa
copyleftlicensedesignedforfreesoftware.
We have designed this License in order to use it for manuals for free software, because free
softwareneedsfreedocumentation:afreeprogramshouldcomewithmanualsprovidingthesame
freedomsthatthesoftwaredoes.ButthisLicenseisnotlimitedtosoftwaremanuals;itcanbeused
foranytextualwork,regardlessofsubjectmatterorwhetheritispublishedasaprintedbook.We
recommendthisLicenseprincipallyforworkswhosepurposeisinstructionorreference.
1.APPLICABILITYANDDEFINITIONS
ThisLicenseappliestoanymanualorotherwork,inanymedium,thatcontainsanoticeplacedby
thecopyrightholdersayingitcanbedistributedunderthetermsofthisLicense. Suchanotice
grants a worldwide, royaltyfree license, unlimited in duration, to use that work under the
conditionsstatedherein.The"Document",below,referstoanysuchmanualorwork.Anymember
ofthepublicisalicensee,andisaddressedas"you".Youacceptthelicenseifyoucopy,modifyor
distributetheworkinawayrequiringpermissionundercopyrightlaw.

A"ModifiedVersion"oftheDocumentmeansanyworkcontainingtheDocumentoraportionofit,
eithercopiedverbatim,orwithmodificationsand/ortranslatedintoanotherlanguage.
A"SecondarySection"isanamedappendixorafrontmattersectionoftheDocumentthatdeals
exclusivelywiththerelationshipofthepublishersorauthorsoftheDocumenttotheDocument's
overallsubject(ortorelatedmatters)andcontainsnothingthatcouldfalldirectlywithinthatoverall
subject.(Thus,iftheDocumentisinpartatextbookofmathematics,aSecondarySectionmaynot
explainanymathematics.) Therelationshipcouldbeamatterofhistoricalconnectionwiththe
subjectorwithrelatedmatters,oroflegal,commercial,philosophical,ethicalorpoliticalposition
regardingthem.
The"InvariantSections"arecertainSecondarySectionswhosetitlesaredesignated,asbeingthose
ofInvariantSections,inthenoticethatsaysthattheDocumentisreleasedunderthisLicense.Ifa
sectiondoesnotfittheabovedefinitionofSecondarythenitisnotallowedtobedesignatedas
Invariant.TheDocumentmaycontainzeroInvariantSections.IftheDocumentdoesnotidentify
anyInvariantSectionsthentherearenone.
The"CoverTexts"arecertainshortpassagesoftextthatarelisted,asFrontCoverTextsorBack
CoverTexts,inthenoticethatsaysthattheDocumentisreleasedunderthisLicense. AFront
CoverTextmaybeatmost5words,andaBackCoverTextmaybeatmost25words.
A"Transparent"copyoftheDocumentmeansamachinereadablecopy,representedinaformat
whosespecificationisavailabletothegeneralpublic,thatissuitableforrevisingthedocument
straightforwardly with generic text editors or (for images composed of pixels) generic paint
programsor(fordrawings)somewidelyavailabledrawingeditor,andthatissuitableforinputto
text formatters or for automatic translation to a variety of formats suitable for input to text
formatters. AcopymadeinanotherwiseTransparentfileformatwhosemarkup,orabsenceof
markup, has been arranged to thwart or discourage subsequent modification by readers is not
Transparent.AnimageformatisnotTransparentifusedforanysubstantialamountoftext.Acopy
thatisnot"Transparent"iscalled"Opaque".
ExamplesofsuitableformatsforTransparentcopiesincludeplainASCIIwithoutmarkup,Texinfo
inputformat,LaTeXinputformat,SGMLorXMLusingapubliclyavailableDTD,andstandard
conforming simpleHTML,PostScript orPDF designedforhumanmodification. Examples of
transparent image formats include PNG, XCF and JPG. Opaque formats include proprietary
formatsthatcanbereadandeditedonlybyproprietarywordprocessors,SGMLorXMLforwhich
theDTDand/orprocessingtoolsarenotgenerallyavailable,andthemachinegeneratedHTML,
PostScriptorPDFproducedbysomewordprocessorsforoutputpurposesonly.

The"TitlePage"means,foraprintedbook,thetitlepageitself,plussuchfollowingpagesasare
neededtohold,legibly,thematerialthisLicenserequirestoappearinthetitlepage.Forworksin
formats which do not have any title page as such, "Title Page" means the text near the most
prominentappearanceofthework'stitle,precedingthebeginningofthebodyofthetext.
Asection"EntitledXYZ"meansanamedsubunitoftheDocumentwhosetitleeitherisprecisely
XYZorcontainsXYZinparenthesesfollowingtextthattranslatesXYZinanotherlanguage.(Here
XYZ stands for a specific section name mentioned below, such as "Acknowledgements",
"Dedications","Endorsements",or"History".)To"PreservetheTitle"ofsuchasectionwhenyou
modifytheDocumentmeansthatitremainsasection"EntitledXYZ"accordingtothisdefinition.
TheDocumentmayincludeWarrantyDisclaimersnexttothenoticewhichstatesthatthisLicense
appliestotheDocument.TheseWarrantyDisclaimersareconsideredtobeincludedbyreferencein
thisLicense,butonlyasregardsdisclaimingwarranties:anyotherimplicationthattheseWarranty
DisclaimersmayhaveisvoidandhasnoeffectonthemeaningofthisLicense.
2.VERBATIMCOPYING
You may copy and distribute the Document in any medium, either commercially or
noncommercially,providedthatthisLicense,thecopyrightnotices,andthelicensenoticesaying
this License applies to the Document are reproduced in all copies, and that you add no other
conditionswhatsoevertothoseofthisLicense.Youmaynotusetechnicalmeasurestoobstructor
controlthereadingorfurthercopyingofthecopiesyoumakeordistribute. However,youmay
acceptcompensationinexchangeforcopies.Ifyoudistributealargeenoughnumberofcopiesyou
mustalsofollowtheconditionsinsection3.
Youmayalsolendcopies,underthesameconditionsstatedabove,andyoumaypubliclydisplay
copies.
3.COPYINGINQUANTITY
If you publish printed copies (or copies in media that commonly have printed covers) of the
Document,numberingmorethan100,andtheDocument'slicensenoticerequiresCoverTexts,you
mustenclosethecopiesincoversthatcarry,clearlyandlegibly,alltheseCoverTexts:FrontCover
Textsonthefrontcover,andBackCoverTextsonthebackcover.Bothcoversmustalsoclearly
andlegiblyidentifyyouasthepublisherofthesecopies.Thefrontcovermustpresentthefulltitle
withallwordsofthetitleequallyprominentandvisible.Youmayaddothermaterialonthecovers
inaddition.Copyingwithchangeslimitedtothecovers,aslongastheypreservethetitleofthe
Documentandsatisfytheseconditions,canbetreatedasverbatimcopyinginotherrespects.

Iftherequiredtextsforeithercoveraretoovoluminoustofitlegibly,youshouldputthefirstones
listed(asmanyasfitreasonably)ontheactualcover,andcontinuetherestontoadjacentpages.
IfyoupublishordistributeOpaquecopiesoftheDocumentnumberingmorethan100,youmust
eitherincludeamachinereadableTransparentcopyalongwitheachOpaquecopy,orstateinor
witheachOpaquecopyacomputernetworklocationfromwhichthegeneralnetworkusingpublic
hasaccesstodownloadusingpublicstandardnetworkprotocolsacompleteTransparentcopyofthe
Document,freeofaddedmaterial.Ifyouusethelatteroption,youmusttakereasonablyprudent
steps,whenyoubegindistributionofOpaquecopiesinquantity,toensurethatthisTransparent
copywillremainthusaccessibleatthestatedlocationuntilatleastoneyearafterthelasttimeyou
distributeanOpaquecopy(directlyorthroughyouragentsorretailers)ofthateditiontothepublic.
It is requested, but not required, that you contact the authors of the Document well before
redistributinganylargenumberofcopies,togivethemachancetoprovideyouwithanupdated
versionoftheDocument.
4.MODIFICATIONS
YoumaycopyanddistributeaModifiedVersionoftheDocumentundertheconditionsofsections
2and3above,providedthatyoureleasetheModifiedVersionunderpreciselythisLicense,with
theModifiedVersionfillingtheroleoftheDocument,thuslicensingdistributionandmodification
oftheModifiedVersiontowhoeverpossessesacopyofit.Inaddition,youmustdothesethingsin
theModifiedVersion:
A.UseintheTitlePage(andonthecovers,ifany)atitledistinctfromthatoftheDocument,and
fromthoseofpreviousversions(whichshould,iftherewereany,belistedintheHistorysection
oftheDocument).Youmayusethesametitleasapreviousversioniftheoriginalpublisherofthat
versiongivespermission.
B.ListontheTitlePage,asauthors,oneormorepersonsorentitiesresponsibleforauthorshipof
themodificationsintheModifiedVersion,togetherwithatleastfiveoftheprincipalauthorsofthe
Document(allofitsprincipalauthors,ifithasfewerthanfive),unlesstheyreleaseyoufromthis
requirement.
C.StateontheTitlepagethenameofthepublisheroftheModifiedVersion,asthepublisher.
D.PreserveallthecopyrightnoticesoftheDocument.
E. Add an appropriate copyright notice for your modifications adjacent to the other copyright
notices.
F.Include,immediatelyafterthecopyrightnotices,alicensenoticegivingthepublicpermissionto
usetheModifiedVersionunderthetermsofthisLicense,intheformshownintheAddendum

below.
G.PreserveinthatlicensenoticethefulllistsofInvariantSectionsandrequiredCoverTextsgiven
intheDocument'slicensenotice.
H.IncludeanunalteredcopyofthisLicense.
I.PreservethesectionEntitled"History",PreserveitsTitle,andaddtoitanitemstatingatleastthe
title,year,newauthors,andpublisheroftheModifiedVersionasgivenontheTitlePage.Ifthere
isnosectionEntitled"History"intheDocument,createonestatingthetitle,year,authors,and
publisheroftheDocumentasgivenonitsTitlePage,thenaddanitemdescribingtheModified
Versionasstatedintheprevioussentence.
J.Preservethenetworklocation,ifany,givenintheDocumentforpublicaccesstoaTransparent
copyoftheDocument,andlikewisethenetworklocationsgivenintheDocumentforprevious
versionsitwasbasedon.Thesemaybeplacedinthe"History"section.Youmayomitanetwork
location foraworkthatwaspublishedatleastfouryearsbeforetheDocumentitself,orifthe
originalpublisheroftheversionitreferstogivespermission.
K. For any section Entitled "Acknowledgements" or "Dedications", Preserve the Title of the
section, and preserve in the section all the substance and tone of each of the contributor
acknowledgementsand/ordedicationsgiventherein.
L.PreservealltheInvariantSectionsoftheDocument,unalteredintheirtextandintheirtitles.
Sectionnumbersortheequivalentarenotconsideredpartofthesectiontitles.
M. Delete any section Entitled "Endorsements". Such a section may not be included in the
ModifiedVersion.
N.DonotretitleanyexistingsectiontobeEntitled"Endorsements"ortoconflictintitlewithany
InvariantSection.
O.PreserveanyWarrantyDisclaimers.
IftheModifiedVersionincludesnewfrontmattersectionsorappendicesthatqualifyasSecondary
SectionsandcontainnomaterialcopiedfromtheDocument,youmayatyouroptiondesignate
someorallofthesesectionsasinvariant.Todothis,addtheirtitlestothelistofInvariantSections
intheModifiedVersion'slicensenotice.Thesetitlesmustbedistinctfromanyothersectiontitles.
YoumayaddasectionEntitled"Endorsements",provideditcontainsnothingbutendorsementsof
yourModifiedVersionbyvariouspartiesforexample,statementsofpeerrevieworthatthetext
has
beenapprovedbyanorganizationastheauthoritativedefinitionofastandard.
YoumayaddapassageofuptofivewordsasaFrontCoverText,andapassageofupto25words
asaBackCoverText,totheendofthelistofCoverTextsintheModifiedVersion. Onlyone
passage of FrontCover Text and one of BackCover Text may be added by (or through

arrangementsmadeby)anyoneentity.IftheDocumentalreadyincludesacovertextforthesame
cover,previouslyaddedbyyouorbyarrangementmadebythesameentityyouareactingonbehalf
of,youmaynotaddanother;butyoumayreplacetheoldone,onexplicitpermissionfromthe
previouspublisherthataddedtheoldone.
Theauthor(s)andpublisher(s)oftheDocumentdonotbythisLicensegivepermissiontousetheir
namesforpublicityforortoassertorimplyendorsementofanyModifiedVersion.
5.COMBININGDOCUMENTS
YoumaycombinetheDocumentwithotherdocumentsreleasedunderthisLicense,undertheterms
definedinsection4aboveformodifiedversions,providedthatyouincludeinthecombinationall
oftheInvariantSectionsofalloftheoriginaldocuments,unmodified,andlistthemallasInvariant
Sectionsofyourcombinedworkinitslicensenotice,andthatyoupreservealltheirWarranty
Disclaimers.
ThecombinedworkneedonlycontainonecopyofthisLicense,andmultipleidenticalInvariant
Sectionsmaybereplacedwithasinglecopy.IftherearemultipleInvariantSectionswiththesame
namebutdifferentcontents,makethetitleofeachsuchsectionuniquebyaddingattheendofit,in
parentheses,thenameoftheoriginalauthororpublisherofthatsectionifknown,orelseaunique
number.MakethesameadjustmenttothesectiontitlesinthelistofInvariantSectionsinthelicense
noticeofthecombinedwork.
In the combination, you must combine any sections Entitled "History" in the various original
documents, forming one section Entitled "History"; likewise combine any sections Entitled
"Acknowledgements", and any sections Entitled "Dedications". You must delete all sections
Entitled"Endorsements".

6.COLLECTIONSOFDOCUMENTS
YoumaymakeacollectionconsistingoftheDocumentandotherdocumentsreleasedunderthis
License,andreplacetheindividualcopiesofthisLicenseinthevariousdocumentswithasingle
copy that is included in the collection, provided that you follow the rules of this License for
verbatimcopyingofeachofthedocumentsinallotherrespects.
Youmayextractasingledocumentfromsuchacollection,anddistributeitindividuallyunderthis
License,providedyouinsertacopyofthisLicenseintotheextracteddocument,andfollowthis
Licenseinallotherrespectsregardingverbatimcopyingofthatdocument.

7.AGGREGATIONWITHINDEPENDENTWORKS
AcompilationoftheDocumentoritsderivativeswithotherseparateandindependentdocumentsor
works, in or on a volume of astorage or distribution medium, is called an "aggregate" if the
copyrightresultingfromthecompilationisnotusedtolimitthelegalrightsofthecompilation's
usersbeyondwhattheindividualworkspermit.WhentheDocumentisincludedinanaggregate,
thisLicensedoesnotapplytotheotherworksintheaggregatewhicharenotthemselvesderivative
worksoftheDocument.
IftheCoverTextrequirementofsection3isapplicabletothesecopiesoftheDocument,thenifthe
Documentislessthanonehalfoftheentireaggregate,theDocument'sCoverTextsmaybeplaced
oncoversthatbrackettheDocumentwithintheaggregate,ortheelectronicequivalentofcoversif
theDocumentisinelectronicform.Otherwisetheymustappearonprintedcoversthatbracketthe
wholeaggregate.
8.TRANSLATION
Translation is considered a kind of modification, so you may distribute translations of the
Documentundertheterms ofsection4.ReplacingInvariantSections withtranslations requires
specialpermissionfromtheircopyrightholders,butyoumayincludetranslationsofsomeorall
InvariantSectionsinadditiontotheoriginalversionsoftheseInvariantSections.Youmayinclude
a translation of this License, and all the license notices in the Document, and any Warranty
Disclaimers,providedthatyoualsoincludetheoriginalEnglishversionofthisLicenseandthe
originalversionsofthosenoticesanddisclaimers.Incaseofadisagreementbetweenthetranslation
andtheoriginalversionofthisLicenseoranoticeordisclaimer,theoriginalversionwillprevail.
Ifasection intheDocumentisEntitled"Acknowledgements","Dedications",or"History",the
requirement(section4)toPreserveitsTitle(section1)willtypicallyrequirechangingtheactual
title.
9.TERMINATION
Youmaynotcopy,modify,sublicense,ordistributetheDocumentexceptasexpresslyprovidedfor
underthisLicense.Anyotherattempttocopy,modify,sublicenseordistributetheDocumentis
void,andwillautomaticallyterminateyourrightsunderthisLicense.However,partieswhohave
receivedcopies,orrights,fromyouunderthisLicensewillnothavetheirlicensesterminatedso
longassuchpartiesremaininfullcompliance.
10.FUTUREREVISIONSOFTHISLICENSE
TheFreeSoftwareFoundationmaypublishnew,revisedversionsoftheGNUFreeDocumentation
Licensefromtimetotime.Suchnewversionswillbesimilarinspirittothepresentversion,but

maydifferindetailtoaddressnewproblemsorconcerns.Seehttp://www.gnu.org/copyleft/.
EachversionoftheLicenseisgivenadistinguishingversionnumber.IftheDocumentspecifies
thataparticularnumberedversionofthisLicense"oranylaterversion"appliestoit,youhavethe
optionoffollowingthetermsandconditionseitherofthatspecifiedversionorofanylaterversion
thathasbeenpublished(notasadraft)bytheFreeSoftwareFoundation.IftheDocumentdoesnot
specifyaversionnumberofthisLicense,youmaychooseanyversioneverpublished(notasa
draft)bytheFreeSoftwareFoundation.

También podría gustarte