Estoy buscando un método para la coincidencia de plantillas invariantes de escala y rotación. Ya probé algunos, pero no funcionaron tan bien para mis ejemplos o tardaron en ejecutarse. La detección de funciones SIFT y SURF falló totalmente. También intenté implementar una función Log-Polar Template Matching, pero nunca terminé (no sabía exactamente cómo hacerlo).
En estos artículos (el primero está en alemán)
http://cvpr.uni-muenster.de/teaching/ss08/seminarSS08/downloads/Wentker-Vortrag.pdf
http://www.jprr.org/index.php/jprr/article/viewFile/355/148
Leí sobre ese método. El mapeo de las coordenadas polares funcionó, pero no sé si es correcto. Las imágenes se ven así.
Y después de hacer coincidir estas 2 imágenes con la función de coincidencia de plantillas de OpenCV obtuve ese resultado
Ahora no sé cómo seguir.
Mis plantillas son siempre símbolos simples en la construcción de planos y los planos en sí. Los símbolos pueden diferir en tamaño y orientación.
Por ejemplo, mi plan simple:
Y mi plantilla
En este ejemplo, solo hay una plantilla, pero en los planos debe encontrar todas las ocurrencias, incluso las que tienen tamaños y / u orientaciones.
¿Alguien tiene un enfoque de cómo podría resolver esto?
Editar:
Una adición al enfoque de Andrey. El algoritmo de captura de distancia para un perfil radial. (Usando EmguCV)
private float[] getRadialProfile( Image<Gray, byte> image, Point center, int resolution )
{
var roi = image.ROI;
if ( !roi.Contains( center ) )
{
return null;
}
var steps = resolution;
var degreeSteps = 360 / (double)resolution;
var data = image.Data;
var peak = 0.0f;
var bottom = double.MaxValue;
var bottomIndex = 0;
var width = roi.Width;
var height = roi.Height;
var minX = roi.X;
var minY = roi.Y;
float[] distances = new float[resolution];
for ( var i = 0; i < steps; i++ )
{
var degree = i * degreeSteps;
var radial = degree * Math.PI / 180.0;
var dy = Math.Sin( radial );
var dx = Math.Cos( radial );
var x = (double)center.X;
var y = (double)center.Y;
while ( true )
{
x += dx;
y += dy;
if ( x >= minX + width || y >= minY + height || x <= minX || y <= minY )
{
x = -1;
y = -1;
break;
}
var pixel = data[(int)y, (int)x, 0];
if ( pixel == 0 )
{
break;
}
}
float distance = 0.0f;
if ( x != -1 && y != -1 )
{
distance = (float)Math.Sqrt( Math.Pow( (center.X - x), 2 ) + Math.Pow( (center.Y - y), 2 ) );
}
distances[i] = distance;
if ( distance > peak )
{
peak = distance;
}
if ( distance < bottom )
{
bottom = distance;
bottomIndex = i;
}
}
// Scale invariance. Divide by peak
for ( var i = 0; i < distances.Length; i++ )
{
distances[i] /= peak;
}
// rotation invariance, shift to lowest value
for ( var i = 0; i < bottomIndex; i++ )
{
distances.ShiftLeft(); // Just rotates the array nothing special
}
return distances;
}
fuente
Respuestas:
Creo que puedes resolver tu problema de una manera mucho más fácil. Teniendo en cuenta que se trata de planos, no debe preocuparse por la conectividad de borde, el ruido y muchas otras cosas para las que SIFT y SURF se construyeron para adaptarse. Su plantilla es una forma hueca con formas de borde específicas.
Por lo tanto, mi recomendación es:
Aquí hay un código de Matlab para que comience: escribí la parte que encuentra el perfil de distancia para un blob específico y lo calculé para la plantilla:
fuente
Aquí está la idea básica de lo que sé que se puede hacer, basado en una charla del profesor Anurag Mittal de IIT Madras.
La idea es la detección de objetos basada en la forma, pero obviamente también se puede extender a otros lugares.
Su artículo sobre el mismo está disponible en: Detección de objetos deformables basada en contornos de múltiples etapas.
Por otro lado, creo que SIFT debería funcionar como los algoritmos de detección de esquinas funcionarían en la función de plantilla que tiene allí.
Nota: SIFT no es completamente invariante en rotación. No puede hacer frente a rotaciones> 60 grados más o menos. Entonces, formar múltiples plantillas es una buena idea.
Al igual que en los Transfrom de Fourier-Mellin basados en log-polar: Causan pérdida de información debido a cómo se realiza el muestreo de las transformadas.
fuente
No lo he pensado mucho, pero estoy bastante seguro de que se puede tener una solución robusta sin muchos problemas usando los descriptores clásicos de Fourier (FD). Creo que su problema podría ser un muy buen candidato para eso. No piense que necesita hacer detección de bordes porque tiene dibujos de líneas negras. Simplemente comience el escaneo de ráster hasta que toque cualquier píxel, luego haga lo siguiente:
Simplemente trate los perímetros de su habitación como si fueran una señal 1D, donde la amplitud de la señal es la distancia normal desde el centroide del objeto, muestreada a una velocidad constante. Entonces, haga un modelo FD simple para la puerta. Luego, escanee los parámetros de cada habitación con una especie de filtro convexo buscando un borde ascendente, un pico y una caída, que establece una ventana de inicio / parada de "señal" para capturar. Haga un FFT o algo similar de FD en esa "señal" capturada y compárela con la plantilla de FD. Quizás el paso de comparación de plantilla puede ser una simple correlación con un umbral para desencadenar una coincidencia. Dado que solo sus puertas tienen bordes redondos, debería ser un problema de coincidencia FD bastante fácil.
Piense en ello como usar la recuperación de imágenes o música de FD desde una base de datos. Un montón de libros blancos sobre eso.
Este es un buen tutorial sobre el uso de FD para aproximar formas: dudo que lo necesite, pero también puede transformar primero sus imágenes en un marco de coordenadas polares para lidiar con las rotaciones, como se propone en este documento: Recuperación de imágenes basadas en formas usando descriptor genérico de Fourier
¿Ves cómo FD parametriza la detección del perímetro de la manzana? La misma idea que tu puerta.
Por cierto, estoy bastante seguro de que mapear todo el esquema a coordenadas polares no ayudará a la invariancia rotacional; necesitaría hacer eso con respecto al centroide de cada puerta, que es exactamente con lo que es su problema para comenzar. Es por eso que creo que solo desea capturar candidatos para puertas, y tal vez asignarlos a coordenadas polares para que coincidan con la plantilla de puerta FD, como se hizo en ese documento vinculado anteriormente.
déjame saber cómo te va si intentas este enfoque.
fuente
Quizás encuentre útil este código de Matlab que escribí: Fractal Mosaics
Implementa el documento "Registro robusto de imágenes usando la transformación Log-Polar" ( pdf ) en una aplicación artística que requería más solidez que los métodos tradicionales que encontré.
fuente