Podemos clasificar las operaciones de transformación geométrica en los siguientes tipos: 1) Transformaciones afines predefinidas. 2) Transformaciones afines genéricas. 3) Transformaciones perspectivas. 4) Transformaciones de mapeo arbitrario. Un parámetro de las operaciones es el tipo de interpolación a aplicar. Se definen las constantes: Transformaciones geométricas OpenCV.
Comportamiento de las operaciones de transformación geométrica en OpenCV: Las operaciones permiten usar ROI. No se pueden usar máscaras (mask). Se permite el modo in-place, es decir, la salida se almacena en la misma imagen de entrada. Por defecto, los píxeles de salida no afectados se ponen a negro (ver flag CV_WARP_FILL_OUTLIERS). Pero se puede indicar que se rellenen con otro valor constante (parámetro fillval) o dejarlos sin modificar (si no se activa ese flag). La principal carencia de OpenCV son las transformaciones bilineales. No se pueden hacer… hay que programárselas uno mismo. Transformaciones geométricas OpenCV.
Transformaciones afines predefinidas: cvResize, cvFlip (cvMirror), cv2DRotationMatrix Transformaciones afines genéricas: cvWarpAffine, cvGetAffineTransform Transformaciones perspectivas: cvWarpPerspective, cvGetPerspectiveTransform Transformaciones de mapeo arbitrario: cvRemap Transformaciones geométricas OpenCV.
Redimensionar una imagen: void cvResize (CvArr* src, CvArr* dst, int inter=CV_INTER_LINEAR) Redimensionar la imagen src al tamaño de la imagen dst. Puede ser aumento o reducción. El método de interpolación va en inter. Las dos imágenes deben ser de la misma profundidad y el mismo número de canales. Recordar: se permite ROI, tanto en src como en dst; y si dst tiene ROI, no se modifican los valores exteriores (esta función no admite FILL_OUTLIERS). Ejemplo. Zoom 2x de una imagen img: IplImage *res= cvCreateImage(cvSize(img->width*2,img->height*2), img->depth, img->nChannels); cvResize(img, res, CV_INTER_CUBIC); cvShowImage("Zoom", res); Transformaciones geométricas OpenCV.
Espejo de una imagen: void cvFlip (const CvArr* src, CvArr* dst=NULL, int flip_mode=0)(cvMirror es sinónimo de cvFlip) Calcula el espejo de la imagen src. Según flip_mode:1 ? espejo horizontal; 0 ? espejo vertical; -1 ? ambos. Permite modo in-place (que, además, es el modo por defecto, cuando dst==NULL).
Nota: estas operaciones son importantes si el origen de las imágenes (origin) es bottom-left, ya que OpenCV trabaja siempre con top-left. Al obtener las imágenes habrá que hacer: if (img->origin==1) { cvFlip(img); img->origin= 0; } Transformaciones geométricas OpenCV. Ojo: esto puede ser necesario cuando trabajamos con vídeo en Windows
Si hay que usar otro desplazamiento, se deben modificar las posiciones (0,2) y (1,2) de mafin:cvRealSet2D(mafin, 0, 2, dx); cvRealSet2D(mafin, 1, 2, dy); Rotar una imagen. No existe una función única para rotar una imagen, sino que hay que: Calcular una matriz de rotación (cv2DRotationMatrix). Aplicar dicha transformación afín (cvWarpAffine). Las matrices de transformación afín son matrices CvMat de tamaño 2×3 y tipo CV_64FC1 o CV_32FC1. CvMat *mafin= cvCreateMat(2, 3, CV_64FC1); Ejemplo. Rotar una imagen respecto al centro de la misma en un ángulo angulo. CvMat *mafin= cvCreateMat(2, 3, CV_64FC1); CvPoint2D32f centro= cvPoint2D32f(img->width/2.0, img->height/2.0); cv2DRotationMatrix(centro, angulo, 1.0, mafin); cvWarpAffine(img, res, mafin); Transformaciones geométricas OpenCV.
Transformaciones afines genéricas Aplicar una transformación afín arbitraria en OpenCV: void cvWarpAffine (const CvArr* src, CvArr* dst, const CvMat* c, int flags= …, CvScalar fillval= cvScalarAll(0)) Aplicar una transformación afín genérica, dada por la fórmula: Transformaciones geométricas OpenCV. dst(x,y):= src( · ) La matriz c, de tipo CV_64FC1 o CV_32FC1, indica los coeficientes de la transformación. La matriz c se puede rellenar usando cvSetReal2D. flags indica el tipo de interpolación (bilineal por defecto) y además…
Si flags = CV_WARP_INVERSE_MAP, la transformación es inversa, es decir, se aplica: Transformaciones geométricas OpenCV. dst( · ) Ejemplo. Inclinar (shear) la imagen img en X en angulo grados y desplazar en X para que se quede centrada.
sal= cvCreateImage(cvGetSize(img), img->depth, img->nChannels); cvZero(sal); double inc= tan(angulo*M_PI/180.0); CvMat *c= cvCreateMat(2, 3, CV_32FC1); cvSetReal2D(c, 0, 0, 1.0); cvSetReal2D(c, 0, 1, inc); cvSetReal2D(c, 0, 2, -inc*img->height/2.0); cvSetReal2D(c, 1, 0, 0.0); cvSetReal2D(c, 1, 1, 1.0); cvSetReal2D(c, 1, 2, 0.0); cvWarpAffine(img, sal, c, CV_INTER_LINEAR); cvReleaseMat(&c); := src(x,y)
Calcular los coeficientes de una transformación afín: CvMat* cvGetAffineTransform (const CvPoint2D32f* src, const CvPoint2D32f* dst, CvMat* mat); src es un array de 3 puntos, en la imagen de origen. dst es un array de 3 puntos, en la imagen de destino. Significado: calcular la transformación afín necesaria para mapear src en los puntos dst, almacenando en resultado en la matriz mat (matriz de 2×3), que es la misma que se devuelve. Esta operación resuelve el sistema de ecuaciones de las páginas 44-45, para mapear un rombo dado en otro rombo. También se podrían resolver de forma explícita usando la función cvSolve para resolver sistemas de ecuaciones en general. Transformaciones geométricas OpenCV.
Página siguiente |