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 0 dx
0 1 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 0 0
0 ey 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() 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 5 9


1 2 3 4 30 70 110
2 6 10
5 6 7 8 = 70 174 278
3 7 11
9 10 11 12 110 278 446
4 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