2012-01-18 20 views
5

¿Cuál es la mejor manera en OpenCV para aplicar la corrección en una imagen proyectada a una superficie 3D como en mis ejemplos o mostrada en Projection on 3D surface?Corrección de imagen para proyección en superficie con OpenCV

Mis primeras pruebas con la detección de esquina de damero OpenCV no parecían muy prometedoras. Si el ángulo de la cámara era demasiado alto, la imagen estaba demasiado distorsionada o demasiado pequeña (demasiado lejos), no se detectó ninguna esquina. También si el tablero de ajedrez tenía demasiados campos.

Mi idea era utilizar un algoritmo como el que se usa en los escáneres 3D para detectar superficies (objetos), pero no tengo idea de si esto es posible con OpenCV. Incluso si no fuera posible con OpenCV, ¿cuáles son los algoritmos utilizados para el escaneo de objetos?

Estas imágenes muestran cómo se ve sin ninguna corrección. Uncorrected projection on surface

Los rectángulos verdes son las proyecciones corregidas. Corrected projection (green)

+0

¿Qué tipo de detalles estás buscando? –

+0

Primero gracias por su respuesta. ¿Puede explicar algunos conceptos básicos sobre cómo detectar la distorsión (algoritmo)? Entonces, si los datos de corrección se encuentran de alguna manera, ¿qué métodos de OpenCV son los mejores para ser utilizados para la corrección? Lamentablemente, la documentación de OpenCV es muy pobre. – bkausbk

+0

Ok, aclararé algo primero. Los rectángulos verdes que muestra como "corregidos", ¿cómo se corrigen exactamente? No parecen encajar bien con nada de lo que puedo ver en la captura de pantalla ... Por cierto, hay muchos detalles sobre tales cosas en este sitio http://www.vision.caltech.edu/bouguetj/calib_doc/ y en este libro "Geometría de visión múltiple en visión artificial" http://www.robots.ox.ac.uk/~vgg/hzbook/, esas son buenas referencias. En cualquier caso, hágamelo saber cómo califica esos rectángulos verdes como "corregidos", gracias –

Respuesta

2

Los marcadores, como los que utilicé para ProCamCalib, se deben detectar de manera más robusta que el patrón de tablero de ajedrez. Puede usar ARToolkitPlus como con ProCamCalib, pero hay otras alternativas, o puede hacer su propio pequeño detector. :) Luego, con las coordenadas de esquina detectadas de los marcadores, podemos calibrar de la misma manera, usando el resto de las funciones de calibración de OpenCV.

Y también puedo hacer cosas geniales con él, como se muestra en la página de ProCamTracker.

EDIT: Ahora que entiendo la pregunta mejor, podemos lograr esto para escenas estáticas con bastante facilidad, aunque OpenCV no nos ayudará mucho. Primero, colocamos la cámara en la posición desde la que deseamos que un espectador vea una proyección corregida. Luego, proyectamos patrones binarios (que se parecen a los puntos que parpadean localmente) y capturamos imágenes de esos patrones de puntos. (Podemos hacerlos más densos, hasta que se conviertan en barras, una técnica conocida como luz estructurada.) Después de detectar imágenes de la cámara y decodificar esos puntos en códigos binarios, obtenemos la cámara < -> correspondencias de píxel del proyector, bien cierta cantidad de vértices de todos modos, y a partir de ahí es 100% gráficos. Aquí es un papel que cubre estos pasos en algunos detalles más:

Zollmann, S., Langlotz, T. y Bimber, O.
calibración geométrica pasiva-activa para proyecciones dependiente de la vista sobre superficies arbitrarias
http://140.78.90.140/medien/ar/Pub/PAGC_final.pdf
Demostración video: http://140.78.90.140/medien/ar/Pub/PAGC.avi

EDIT2: Proyectando algún tipo de patrón, podemos descubrir las coordenadas del pixel en la imagen del proyector que corresponde a un pixel dado en la imagen de la cámara. A menudo usamos patrones de puntos temporales porque es fácil de detectar y decodificar ... Y en realidad, OpenCV puede ser útil para esto. La forma en que creo que trataría de hacerlo sería algo como esto. Tomemos solo 2 bits por simplicidad. Por lo tanto, tenemos cuatro imágenes: 00, 01, 10 y 11. Como controlamos la imagen del proyector, las conocemos, pero también debemos encontrarlas en la imagen de la cámara. Primero, tomaría la última imagen (de la cámara), 11, y la restaría de la primera imagen (de la cámara) 00, usando cvAbsDiff(), luego binarizaría el resultado con cvThreshold(), y encontraría los contornos (o blobs) en el binario imagen con cvFindContours(). Debemos asegurarnos de que cada contorno tenga un área apropiada con cvContourArea(), mientras que podemos encontrar su centroide con cvMoments(). Entonces podemos comenzar a hacer cosas con las otras imágenes. Para cada contorno, trataría de tomar los píxeles cvBoundingRect() a cvCountNonZero() en las otras imágenes (también binarizadas con cvThreshold()), dentro de estos rectángulos delimitadores, que podemos establecer a través de cvSetImageROI().Si el recuento distinto de cero es grande, debe registrarse como un 1, si no, un 0.

Una vez que tenga todos los bits, tendrá el código y listo.

+0

Gracias, eso era exactamente lo que estaba buscando. No entiendo por qué usar patrones de puntos y cómo crear el mapa de desplazamiento a partir de él, pero esto debería quedar claro después de estudiar el documento. – bkausbk

+0

Suena como lo que necesitas, ¡genial! Añadiré un poco más detalles para completar ... –

Cuestiones relacionadas