P. 1
operaciones_basicas_imagenes

operaciones_basicas_imagenes

|Views: 3.417|Likes:
Publicado pornay_24

More info:

Published by: nay_24 on Oct 21, 2010
Copyright:Attribution Non-commercial

Availability:

Read on Scribd mobile: iPhone, iPad and Android.
download as PPT, PDF, TXT or read online from Scribd
See more
See less

08/08/2013

pdf

text

original

Procesamiento en OpenCV.

Operaciones de procesamiento global:
‡ Tipos: unarias, binarias, histogramas.
Recordar: un CvArr puede ser un IplImage

void cvUnaria (const CvArr* A, ..., CvArr* B, ...) void cvBinaria (const CvArr* A, const CvArr* B,.., CvArr* C, ...)

‡ Las funciones reciben una (unarias) o dos (binarias) imágenes de entrada, y producen una de salida. Todas ellas deben estar creadas, también la imagen de salida. ‡ La mayoría de las funciones admite modo inplace: una imagen de entrada se puede usar también para guardar el resultado. ‡ Muchas de las operaciones trabajan con ROI, COI y mask No operan sobre toda la imagen sino sólo sobre una parte concreta (rectángulo, canal o máscara de interés).

Procesamiento en OpenCV.
‡ Es importante observar las restricciones impuestas sobre las imágenes admitidas en cada función. ‡ En otro caso ocurrirá un error (se produce una excepción). ‡ Normalmente:
± Todas las imágenes deben ser del mismo tipo: profundidad y número de canales. ± Todas las imágenes deben tener el mismo tamaño. ± Algunas funciones requieren imágenes con 1 solo canal. ± Opcionalmente, algunas admiten el uso de una máscara (mask), que será otra imagen, de 8 bits y con un 1 canal. Un valor 0 significa que el píxel no se procesa, y  0 sí se procesa. ± Ver la documentación para cada función.

cvMul. cvMax. cvAbs. cvNormalizeHist. cvNot. cvOr.A. cvOrS. cvSubS. cvPow. cvAndS. cvCopy. ‡ Operaciones unarias: ± cvSet. cvMaxS. cvScale. cvSetZero. cvThreshold. cvLog ‡ Operaciones binarias: ± cvAdd. cvReleaseHist. cvConvertScaleAbs. cvAddS. cvCmpS. cvXor. cvLUT .2. cvEqualizeHist. cvConvertScale. cvXorS. cvGetMinMaxHistValue. cvSub. cvAbsDiff. cvDiv. cvSubRS. cvAdaptiveThreshold. cvMin ‡ Operaciones con histogramas: ± cvCreateHist. cvConvert. cvAbsDiffS. cvCalcHist. cvQueryHistValue. cvCmp. cvMinS. cvAddWeighted. cvAnd. Procesamiento en OpenCV. cvGetHistValue.

. img2). 100)).y):= S ‡ Ejemplo.Procesamiento en OpenCV. Copiar un trozo de imagen en otra imagen: cvSetImageROI(img. img->nChannels). cvScalar(0.y) ‡ Ejemplo. CvScalar S. Inicializar a verde: cvSet(img.y)0 entonces A(x. img2= cvCreateImage(cvSize(100. CvArr* B. cvCopy(img. 100.y):= 0 ‡ Copiar una imagen en otra: void cvCopy (const CvArr* A.y):= A(x.y)0 entonces B(x. cvRect(50.0)). cvResetImageROI(img). const CvArr* mask =0) si mask(x.50.255. ‡ Inicializar una imagen con un valor constante: void cvSet (CvArr* A. 100). ‡ Inicializar una imagen con un valor 0: void cvSetZero (CvArr* A) / void cvZero (CvArr* A) A(x. const CvArr* mask=0) si mask(x. img->depth.

const CvArr* mask=0) si mask(x. cvScalar(40.y) ± S ‡ Ejemplo. ‡ Restar a una imagen un valor constante: void cvSubS (const CvArr* A.y):= A(x. img).y):= A(x. CvArr* C. const CvArr* mask=0) si mask(x.y):= S ± A(x. CvScalar S.y)0 entonces C(x. CvScalar S. img). cvScalarAll(50).0). const CvArr* mask=0) si mask(x. img). Sumar un poco de azul: cvAddS(img.y) + S ‡ Ejemplo. Invertir una imagen (en color o B/N). CvArr* C.Procesamiento OpenCV. Disminuir el brillo: cvSubS(img. cvScalarAll(50). cvSubRS(img. .0. CvScalar S. ‡ Aumentar el brillo (inplace): cvAddS(img. img2). CvArr* C.y)0 entonces C(x. ‡ Restar a un valor constante una imagen : void cvSubRS (const CvArr* A. ‡ Sumar a una imagen un valor constante: void cvAddS (const CvArr* A. cvScalarAll(255).y) ‡ Ejemplo.y)0 entonces C(x.

y) ± S| ‡ Ejemplo. etc). Ver también cvConvertScaleAbs. cvScalar(40. CvArr* B. ‡ Valor absoluto de diferencia entre una imagen y un valor constante: void cvAbsDiffS (const CvArr* A . ‡ Valor absoluto de una imagen: void cvAbs (const CvArr* A. CvArr* C) C(x.128.y):= A(x. . -50). cvAbsDiffS(img. ‡ Ejemplo. double scale=1.y) * scale + shift (igual para todos los canales) ‡ Se puede hacer cualquier transformación lineal.y):= |A(x.150)). img2. como cvConvertScale.y):= |A(x. ‡ La función permite hacer conversiones entre imágenes con distintos valores de profundidad (de 8 bits a 16.y)| ‡ Tiene sentido cuando la profundidad son números con signo ‡ Producto/división de una imagen por una constante: void cvScale (const CvArr* A. CvScalar S) C(x. CvArr* C. ‡ Tiene sinónimos. Ajuste del contraste: cvConvertScale(img. img2.Procesamiento en OpenCV. double shift=0) B(x. 1.6. o a reales de 32 bits.

CvArr* C. A y C deben ser de 1 canal ‡ Y lógico entre una imagen y un valor constante (a nivel de bits): void cvAndS (const CvArr* A. double b.y):= A(x. Vale para invertir una imagen: cvNot(img. const CvArr* mask=0) si mask(x.y) ‡ Ejemplo. ‡ Ajuste lineal del histograma (y otros métodos de normalización): void cvNormalize(const CvArr* A.y) XOR S ‡ Negación lógica de una imagen (a nivel de bits): void cvNot (const CvArr* A. ‡ Pero.y):= NOT A(x. CvScalar S. CvScalar S.y)0 entonces C(x.y):= A(x. CvArr* C. double a.y) OR S ‡ O exclusivo entre una imagen y un valor constante (a nivel de bits): void cvXorS (const CvArr* A. ¿para qué valen las otras operaciones booleanas con constantes? .y):= A(x. const CvArr* mask=0) si mask(x. CV_MINMAX) hace que los píxeles de C vayan entre a y b.y)0 entonces C(x. img).Procesamiento en OpenCV. CvArr* C. CvScalar S.y)0 entonces C(x. CvArr* C) C(x. const CvArr* mask=0) si mask(x. CvArr* C.y) AND S ‡ O lógico entre una imagen y un valor constante (a nivel de bits): void cvOrS (const CvArr* A.

y):= si A(x. ³>=´. double maxValue. . ‡ P. ³<=´} ‡ cmp_op indica el modo de comparación: CV_CMP_EQ (igual). int thresholdType) ‡ Umbraliza la imagen según el método dado en thresholdType. ‡ El resultado es una imagen binaria. CvArr* C.y) op S. ‡ Comparación entre una imagen y un valor constante: void cvCmpS (const CvArr* A.ej. con 0 ó 255 (todos los bits a 1). y el umbral es threshold. ‡ Ver también la función cvInRangeS(img. double S. scalar2.y):= A(x. CV_THRESH_BINARY para binarizar: C(x.Procesamiento en OpenCV. etc. Para un método más avanzado ver cvAdaptiveThreshold.. usando una vecindad local (adaptativo). double threshold. ‡ Umbralización/binarización de una imagen: void cvThreshold (const CvArr* src. int cmp_op) C(x. El umbral se calcula para cada píxel. con op  {³=´. ³>´. ³<´. res). CvArr* dst. CV_CMP_GT (mayor que). CV_CMP_GE (mayor o igual). scalar1.y) > threshold entonces maxValue sino 0 ‡ La umbralización se hace con un valor constante.

CvArr* C) C(x.y)p void cvExp (const CvArr* A. 0).y).y) void cvLog (const CvArr* A.y):= A(x. 255. double scalar.. S} ‡ Las imágenes deben ser de un solo canal. imr.y):= eA(x.y)| ‡ Para evitar saturación y pérdida de información. es conveniente transformar las profundidad a reales de 32 o 64 bits. gamma). CvArr* C. double scalar. CvArr* C) C(x. // imr es de profundidad 32F cvPow(imr. 1. double p) C(x.y). cvConvertScale(imr. 0). exponencial y logaritmo de los píxeles de una imagen: void cvPow (const CvArr* A./255.y):= loge |A(x. ‡ Mínimo entre una imagen y un valor constante: void cvMinS (const CvArr* A. S} ‡ Las imágenes deben ser de un solo canal. CvArr* C) (está mal en la ayuda) C(x.y):= max {A(x. img. ‡ Potencia.y):= min {A(x.Procesamiento en OpenCV. ‡ Máximo entre una imagen y un valor constante: void cvMaxS (const CvArr* A. CvArr* C) (está mal en la ayuda) C(x. ‡ Ejemplo. . imr. Transformación de gamma: cvConvertScale(img.

0). Operaciones Binarias ‡ Sumar dos imágenes: void cvAdd (const CvArr* A.5. im1.y):= a·A(x.5. double a. 0).y) + g ‡ Las mismas restricciones que antes. double b.y):= A(x. cvScale(im2. ‡ Es mucho más adecuada para calcular la media de dos imágenes: cvAddWeighted(im1.5.y) + b·B(x. imr). im2. const CvArr* B. CvArr* C) C(x. . imr. CvArr* C. Por ejemplo. // ¿Qué pasa si hacemos primero la suma cvAdd(im1. 0. im1.y)0 entonces C(x.y) + B(x. CvArr* B. im2: cvScale(im1. im2. // y luego la división por 2? ‡ Suma ponderada de dos imágenes: void cvAddWeighted(CvArr* A.5. 0. 0. para obtener la media de dos imágenes. 0. 0. im2. double g. const CvArr* mask=0) si mask(x.y) ‡ Las imágenes deben tener el mismo tamaño (o ROI) y el mismo tipo. ‡ Ojo: recordar los problemas de saturación.Procesamiento en OpenCV. 0).

B(x. const CvArr* B.A. 16F.y)0 entonces C(x. ‡ Esta operación tiene más sentido cuando se usan tipos con signo (16S.y):= |A(x. const CvArr* B. const CvArr* mask=0) si mask(x. .y)| ‡ Más adecuada cuando tenemos imágenes sin signo y solo queremos medir diferencias absolutas entre píxeles. CvArr* C) C(x. CvArr* C. tener cuidado con los problemas de saturación. ‡ Igual que antes. Procesamiento en OpenCV.B(x. 32F). ‡ Diferencia absoluta entre dos imágenes: void cvAbsDiff (const CvArr* A.y) ‡ Las imágenes deben tener el mismo tamaño (o ROI) y el mismo tipo.y) .y) .y):= A(x.2. ‡ Restar dos imágenes: void cvSub (const CvArr* A.

‡ Ejemplo: cvDiv(im1. CvArr* C.0). imr. im2. ‡ Multiplicar dos imágenes: void cvMul (const CvArr* A. .Procesamiento en OpenCV. CvArr* C. ‡ Igual que antes. ‡ Ejemplo: multiplicar dos imágenes de 8 bits: cvMul(im1. 1. im2.y)*scale ‡ El valor scale permite evitar problemas de saturación. const CvArr* B. double scale=1) C(x. ‡ Dividir dos imágenes: void cvDiv (const CvArr* A. double scale=1) C(x.y) ‡ A puede ser nulo./255). Es más adecuado usar enteros con signo.y)*B(x.y)/B(x. const CvArr* B. 255.y):= A(x.y):= scale*A(x. imr. tener cuidado con los problemas de saturación. en cuyo caso se supone que todos los píxeles son 1.

entre dos imágenes: void cvOr (const CvArr* A. ‡ O lógico. entre dos imágenes: void cvAnd (const CvArr* A. a nivel de bits.y):= A(x.y) . CvArr* C.y)0 entonces C(x.y) AND B(x.y):= A(x. const CvArr* B.y):= A(x.y) ‡ O exclusivo.Procesamiento en OpenCV. pero ¿para qué puede valer? ‡ Para que tenga sentido.y) OR B(x. const CvArr* B. CvArr* C. ‡ Y lógico. al menos alguna de las dos imágenes debería ser binaria (0/255). a nivel de bits.y)0 entonces C(x.y) XOR B(x.y) ‡ También funciona con números reales. CvArr* C. a nivel de bits.y)0 entonces C(x. const CvArr* B. const CvArr* mask=0) si mask(x. entre dos imágenes: void cvXor (const CvArr* A. const CvArr* mask=0) si mask(x. const CvArr* mask=0) si mask(x.

imRes).y):= max {A(x. ‡ Comparación de dos imágenes: void cvCmp (const CvArr* A.y). con op  {³=´. const CvArr* B.Procesamiento en OpenCV.y):= A(x. CvArr* C) C(x.y) op B(x. ‡ Ver también la función cvInRange(img.y)} ‡ Las imágenes deben tener 1 solo canal. int cmp_op) C(x. B(x. B(x. ³>´. ³<=´} ‡ Los mismos modos de comparación que cvCmpS. imMin. ‡ La imagen de salida es binaria 0/255. imMax. const CvArr* B.y). . ³>=´.y). CvArr* C) C(x. CvArr* C. Las imágenes deben tener 1 canal. ‡ Mínimo de dos imágenes: void cvMin (const CvArr* A. ³<´. const CvArr* B.y):= min {A(x. ‡ Máximo de dos imágenes: void cvMax (const CvArr* A.y)} ‡ Las imágenes deben tener 1 solo canal.

B./255)./255). cvNot(N. cvMul(A. #define CM(a.pB.val[0].. ‡ Implementación 2.val[0]= CM(pA. porque las operaciones están optimizadas Aunque no del todo correcto. pB= cvGet2D(B. y.val[1]. pB.y))/255 + B(x. x).val[2].. y. ‡ Observar el estilo de programación usando estas funciones. B y N. const CvArr* B.pN. ‡ Implementación 1. x). R).0 CvScalar pA. cvMul(B. pN. Esto es más sencillo y eficiente. pN= cvGet2D(N.n) (a*(255-n)+b*n)/255. B. x. cvAdd(A. CvArr* R).val[0].y):= A(x.y)·(255-N(x.y)/255 void Combina (const CvArr* A. pR. queremos implementar la operación: R(x. y<A->height. 1. pR. más lento) y menos recomendable } . const CvArr* N. N). modifica sus parámetros de entrada A.val[1]. N.pN. y++) for (int x= 0.val[2]. 1. x++) { pA= cvGet2D(A. ‡ Por ejemplo. x).pB.val[2]).b. pR. (~5 veces cvSet2D(R. y. pR). y. A.val[1]= CM(pA. for (int y=0.val[2]= Esto es menos eficiente CM(pA.val[0]).val[1]). x<A->width.pB.pN.Procesamiento en OpenCV. N.y)·N(x. pR.

scale Optional scale factor A ( x . const(CvArr* src2. cvMul(A. R void cvMul( const CvArr* src1. N)./255). y src2 ) The second source array. double scale=1 ). The first source array. 1. B. cvAdd(A. B. x src1 .y):= A(x. A. R). CvArr* dst. 1. cvNot(N.Procesamiento en OpenCV.y)·N(x. N. : dst = The destination array. N.y))/255 + B(x./255).y)/255 cvMul(B. R(x.y)·(255-N(x.

Procesamiento en OpenCV. ‡ Tenemos también una operación de ecualización del histograma: cvEqualizeHist. cvQueryHistValue. ‡ Utilizaremos los histogramas de OpenCV. cvReleaseHist. cvNormalizeHist. cvGetHistValue. cvCalcHist. Operaciones con histogramas ‡ Los histogramas se manejan de formas diferentes en IPL y en OpenCV. o LUT). ‡ Otra cuestión relacionada son las tablas de transformación (look-up table. cvThreshHist. cvGetMinMaxHistValue. . ‡ En OpenCV se define el tipo CvHistogram y las operaciones para manejarlo: cvCreateHist.

Procesamiento en OpenCV. 2 dimensiones (histogramas conjuntos de dos canales) o como mucho 3. ± Rango de valores correspondientes a cada celda.. Histograma de 1 dimensión y 4 celdas Bin 0 (0-63) Histograma de 2 dimensiones Bin 0 (0-127) Bin 1 (128-255) Bin 1 Bin 2 Bin 3 Bin 0 (0-85) Bin 1 (86-170) Bin 2 (171-255) (64-127) (128-191) (192-255) . 64. ‡ Propiedades de un histograma: ± Número de dimensiones. será uniforme). ± Para cada dimensión. 32. ‡ Ejemplos. Normalmente será una potencia de 2. número de celdas (bins). Normalmente tendremos 1 dimensión (escala de grises). como 256. en el caso de haber menos celdas que valores (normalmt..

float** ranges=0. hist= cvCreateHist(1. Para histogramas uniformes. rmax) y las celdas se reparten uniformemente este rango. ‡ Ejemplo. ± ranges: rango asociado a cada celda de cada dimensión. int uniform=1) dims: número de dimensiones del histograma. Si la imagen es de 8 bits y el rango es (0. es un array de pares (rmin.. usar siempre CV_HIST_ARRAY.Procesamiento en OpenCV. 255). se puede poner simplemente ranges=NULL. ‡ Crear un histograma: CvHistogram* cvCreateHist (int dims. int* sizes. sizes: número de celdas en cada dimensión. &celdas.. ± ± ± ± . CV_HIST_ARRAY). Crear un histograma con 1 dimensión y 256 celdas: CvHistogram* hist1.. uniform: poner a 1 para que el rango de valores en cada celda sea uniforme. . type: tipo. int type. int celdas= 256.

. no borra el contenido anterior de las celdas. int celdas[2]= {32. 32}. Deben haber tantas como número de dimensiones del histograma. const CvArr* mask=0) ± img: array de imágenes de 1 canal. ± acumulate: si se pone a TRUE. ‡ Liberar la memoria ocupada por un histograma: void cvReleaseHist (CvHistogram** hist) ‡ Calcular el histograma de una imagen: void cvCalcHist (IplImage** img. int acumulate=0. CvHistogram* hist. celdas.Procesamiento en OpenCV. hist2= cvCreateHist(2. Crear un histograma con 2 dimensiones y 32 celdas en cada dimensión: CvHistogram* hist2. CV_HIST_ARRAY). Esto permite obtener histogramas acumulados de varias imágenes. ± mask: máscara sobre la que se calculará el histograma. ‡ Ejemplo.

// Ver abajo cvCvtColor(img. cvSplit(src. CV_RGB2GRAY). planos[2]= cvCreateImage(cvGetSize(img). ‡ Ojo.Procesamiento en OpenCV. 1). planos[1]= cvCreateImage(cvGetSize(img). 0). gris. planos[0]= cvCreateImage(cvGetSize(img). planos+1. 8. 1). 8. 0). porque la original no funciona bien si no hay un ROI establecido. ‡ Ejemplo 2. planos+2. hace que sea necesario separar los canales de una imagen. 1). la función cvGetSize está redefinida en HighGUI2. 8. hist2. . 1). Calcular el histograma bidimensional de los canales R y G: IplImage *planos[3]. hist1. Calcular el histograma unidimensional del nivel de gris: IplImage *gris= cvCreateImage(cvGetSize(img). ‡ Ejemplo 1. ‡ Esta forma tan particular de calcular el histograma. cvCalcHist(planos. planos+0. 8. cvCalcHist(&gris. 0).

int idx1) ± Para el caso de histogramas bidimensionales. float cvQueryHistValue_2D (CvHistogram*hist.. ± De forma similar para histogramas 3D y ND. int idx0. int idx0. ± Devuelve un puntero. ± De forma similar para histogramas 3D y ND. Esta función será útil si lo que queremos es poder modificar a mano el valor de las celdas.. ± Realmente no es una función sino un macro.Procesamiento global en OpenCV. ‡ Una vez calculado. float * cvGetHistValue_2D (CvHistogram*hist. . int idx0) ± Para el caso de histogramas unidimensionales. int idx1) ± Para el caso de histogramas bidimensionales. consultar las celdas del histograma: float cvQueryHistValue_1D (CvHistogram*hist. ‡ Obtener un puntero a una celda del histograma: float * cvGetHistValue_1D (CvHistogram*hist. int idx0) ± Para el caso de histogramas unidimensionales.

el máximo (maxVal). No se puede usar para hacer una ecualización conjunta de RGB. CvArr* dst) ± Ojo: la imagen debe ser de 1 solo canal y 8U. para escalar todas las celdas entre 0 y 1. . el índice de la celda mínima (minIdx) y máxima (maxIdx).Procesamiento en OpenCV. float* minVal. ‡ Existen otras operaciones interesantes de consulta y manipulación de histogramas. ‡ Ecualizar el histograma de una imagen: void cvEqualizeHist (const CvArr* src.ej. ‡ Obtener máximo y mínimo de un histograma: void cvGetMinMaxHistValue (const CvHistogram* hist. double factor) ± Hace que la suma de todas las celdas del histograma sea factor. ‡ Normalizar un histograma: void cvNormalizeHist (CvHistogram* hist. p.. int* maxIdx =0) ± Dado el histograma. ± Puede ser interesante para visualizar o comparar histogramas. float* maxVal. ± Interesante. calcula el mínimo (minVal). int* minIdx =0.

multiplicación de imágenes. resta. ‡ Suma. ‡ Operaciones Booleanas AND.Primer Previo ‡ Proyecto realizado utilizando las librerías de OpenCV que implemente las siguientes funciones: ‡ Histograma de una imagen. ‡ Umbralización. Deben . OR. NOT ‡ Calculo de Fondo de una imagen por combinación utilizando media.

Calcular la diferencia: D = abs(M-A). R:= (F AND NOT U) OR (A AND U) M A D U F R ¿Cómo arreglar eso? . 1. 4. Umbralizar la imagen con un valor adecuado. U = umbralizar(D. ‡ Proceso. 2. 6. 5. Obtener el modelo de fondo M.4. Para cada imagen A del vídeo. Sea F el nuevo fondo. Combinación de imágenes. x).2. 3.

Media de 2 imágenes: R(x. Combinación de imágenes.y)+B(x.y))/2 A R B ‡ Significado: las imágenes son semitransparentes (al 50%).2. . y):= (A(x. ‡ Para evitar la saturación se puede usar la media.4.

Una alternativa para crear modelos de fondo es usar máximos y mínimos. tenemos máximo y mínimo del fondo en cada píxel. En lugar de tener media y varianza. Fondo mínimo Fondo máximo ‡ Dada una imagen nueva. para cada píxel.4. si no lo está: objeto. .2. Si lo está: fondo. comprobar si su valor está entre el máximo y el mínimo. Combinación de imágenes. ‡ Ejemplo.

You're Reading a Free Preview

Descarga
scribd
/*********** DO NOT ALTER ANYTHING BELOW THIS LINE ! ************/ var s_code=s.t();if(s_code)document.write(s_code)//-->