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.

Programadepruebadelasfunciones cvLoadImage cvSaveImage y


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 0 0 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: CV_INTER_NN:Interpolacintipovecinomsprximo CV_INTER_LINEAR:Interpolacinbilineal(eslaqueseutiliza pordefecto)

Lostiposdeinterpolacinpuedenser:

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 0

0 ey

0 0

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()

sen() cos()

cxcxcos()cysen() 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, ); Siendo:


intstep=CV_AUTOSTEP

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