Descargar

Transformaciones geométricas en OpenCV (página 2)

Enviado por Pablo Turmero


Partes: 1, 2
edu.red Ejemplo. Aplicar una transformación afín a una imagen img, suponiendo que tenemos 3 puntos en img y los 3 puntos correspondientes en destino.

CvMat *mat= cvCreateMat(2, 3, CV_64FC1); CvPoint2D32f src[3]; CvPoint2D32f dst[3]; src[0]= cvPoint2D32f(x, y); … cvGetAffineTransform(src, dst, mat); cvWarpAffine(img, destino, mat, CV_INTER_CUBIC); cvReleaseMat(&mat); Transformaciones geométricas OpenCV.

edu.red Transformaciones perspectivas Para las transformaciones perspectivas, las operaciones disponibles en OpenCV son similares a las afines. Aplicar una transformación: cvWarpAffine ? cvWarpPerspective Calcular los coeficientes: cvGetAffineTransform ? cvGetPerspectiveTransform En este caso la matriz que define la transformación es un CvMat de 3×3 de tipo CV_64FC1 o CV_32FC1. OpenCV no tiene las transformaciones bilineales. Transformaciones geométricas OpenCV.

edu.red Aplicar una transformación perspectiva: void cvWarpPerspective (const CvArr* src, CvArr* dst, const CvMat* c, int flags= …, CvScalar fillval= cvScalarAll(0)) Aplica una transf. perspectiva de la imagen src en dst. La matriz de coeficientes c es de 3×3. Transformaciones geométricas OpenCV. flags indica el tipo de interpolación (por defecto bilineal). Y si vale CV_WARP_INVERSE_MAP, se usa la inversa de la matriz c. Si flags vale CV_WARP_FILL_OUTLIERS significa que lo que caiga fuera en dst, se rellene de color fillval. · =

edu.red Calcular los coeficientes de una transformación afín: CvMat* cvGetPerspectiveTransform (const CvPoint2D32f* src, const CvPoint2D32f* dst, CvMat* mat); src es un array de 4 puntos, en la imagen de origen. dst es un array de 4 puntos, en la imagen de destino. Significado: calcular la transformación perspectiva necesaria para mapear los puntos src en los puntos dst, almacenando en resultado en la matriz mat (matriz de 3×3), que es la misma que se devuelve. Esta operación resuelve el sistema de ecuaciones de la página 59, para mapear un cuadrilátero dado en otro. Los cuadriláteros deben ser conexos (no cóncavos). También se podrían resolver con cvSolve. Transformaciones geométricas OpenCV.

edu.red Algunas propiedades interesantes de la matriz c: Si ambos cuadriláteros son rombos, la transformación anterior será afín, por lo que c[2][0]= 0, c[2][1]= 0, c[2][2]= 1. La inversa de una transformación perspectiva asociada a c, se obtiene usando la matriz inversa de c, es decir, c-1. Ver cvInvert para invertir matrices. El modo CV_WARP_INVERSE_MAP consiste simplemente en usar la matriz c-1. La aplicación sucesiva de dos transformaciones perspectivas c1 y luego c2, equivale a la transf. asociada al producto matricial de c2 por c1. Ver cvMatMulAdd. Transformaciones geométricas OpenCV.

edu.red Ejemplo. Transformación perspectiva de una imagen, img, para producir un efecto similar al de la página 56.

IplImage *sal= cvCloneImage(img); cvSet(sal, cvScalarAll(255)); CvMat *c= cvCreateMat(3, 3, CV_32FC1); int w= img->width-1; int h= img->height-1; CvPoint2D32f src[4]= // Cuatro puntos en el origen {{0,0}, {w,0}, {w,h}, {0,h}}; CvPoint2D32f dst[4]= // Cuatro puntos en el destino {{w*0.4,0}, {w*0.55,0}, {w,h}, {0,h}}; cvGetPerspectiveTransform(src, dst, c); cvWarpPerspective(img, sal, c, CV_INTER_CUBIC); cvReleaseMat(&c); Transformaciones geométricas OpenCV.

edu.red Transformaciones de mapeo arbitrario: Consisten en definir el par de funciones f1(x,y) y f2(x,y) de la transformación geométrica genérica: R(x,y):= A(f1(x,y), f2(x,y)) f1 y f2 indican para cada píxel de salida, cuál es el píxel correspondiente de entrada. Recordar que f1 y f2 se pueden ver, a su vez, como imágenes, que tendrán un solo canal. Cuando el valor de las funciones no sea entero, se aplicará algún método de interpolación. Si el valor asociado a un píxel cae fuera de la imagen origen, el contenido de la imagen no se modifica o se pone a un valor constante. La única función necesaria es cvRemap. Transformaciones geométricas OpenCV.

edu.red Aplicar un mapeo arbitrario: void cvRemap (const CvArr* src, CvArr* dst, const CvArr* xMap, const CvArr* yMap, int interpol, CvScalar fillval)

Aplica la transformación de mapeo: dst(x,y):= src(xMap(x,y), yMap(x,y)) Es decir, f1 está dada en xMap, y f2 en yMap. xMap e yMap deben ser imágenes 1 solo canal, de profundidad float (IPL_DEPTH_32F) y del mismo tamaño que dst. La profundidad de las imágenes src y dst debe ser la misma. Recordar: cvRemap admite modo in-place. Lo realmente importante de esta función es cómo calcular las imágenes xMap e yMap para conseguir el efecto deseado. Transformaciones geométricas OpenCV.

edu.red Ejemplo 1. Transf. aleatoria de una imagen img, con un radio m:

IplImage* imgx= cvCreateImage(cvGetSize(img), IPL_DEPTH_32F, 1); IplImage* imgy= cvCreateImage(cvGetSize(img), IPL_DEPTH_32F, 1); CvScalar sx, sy; for (int y= 0; yheight; y++) for (int x= 0; xwidth; x++) { sx.val[0]= x + rand()%(2*m+1) – m; // m indica el radio de la sy.val[0]= y + rand()%(2*m+1) – m; // transformación aleatoria cvSet2D(imgx, y, x, sx); cvSet2D(imgy, y, x, sy); } cvRemap(img, res, imgx, imgy, CV_INTER_CUBIC); cvReleaseImage(&imgx); cvReleaseImage(&imgy);

Ejemplo 2. Tr. de acristalado. Sustituir las líneas comentadas por: sx.val[0]= x – x%m + y%m; sy.val[0]= y – y%m + x%m; Transformaciones geométricas OpenCV.

edu.red Ejemplo 3. Aplicación de varias transformaciones cilíndricas a la imagen img, con distintos grados de transformación. IplImage* res= cvCloneImage(img); IplImage* imgx= cvCreateImage(cvGetSize(img), IPL_DEPTH_32F, 1); IplImage* imgy= cvCreateImage(cvGetSize(img), IPL_DEPTH_32F, 1); for (int yy= 0; yyheight; yy++) for (int xx= 0; xxwidth; xx++) cvSetReal2D(imgy, yy, xx, yy); double x2, vx, a; for (int kk= 0; kk<200; kk++) { // OJO: esto es para hacer una animación a= 1.0/(5.05-kk/40.0); // a es el segundo radio de la elipse for (int yy= 0; yyheight; yy++) for (int xx= 0; xxwidth; xx++) { x2= 1.0-2.0*xx/img->width; vx= x2?atan2(a*sqrt(1-x2*x2),x2)*img->width/M_PI:img->width/2.0; cvSetReal2D(imgx, yy, xx, vx); } cvRemap(img, res, imgx, imgy, CV_INTER_CUBIC); cvNamedWindow("Remap", 0); cvShowImage("Remap", res); cvWaitKey(20); } cvReleaseImage(&imgx); cvReleaseImage(&imgy); Transformaciones geométricas OpenCV.

Partes: 1, 2
 Página anterior Volver al principio del trabajoPágina siguiente