Estou procurando um método para correspondência invariável de modelos de escala e rotação. Eu já tentei alguns, mas eles não funcionaram tão bem para os meus exemplos ou levaram para sempre a execução. A detecção de SIFT e SURF falhou totalmente. Também tentei implementar uma função de correspondência de modelo Log-Polar, mas nunca terminei (não sabia exatamente como fazê-lo).
Nestes artigos (o primeiro está em alemão)
http://cvpr.uni-muenster.de/teaching/ss08/seminarSS08/downloads/Wentker-Vortrag.pdf
http://www.jprr.org/index.php/jprr/article/viewFile/355/148
Eu li sobre esse método. O mapeamento das coordenadas polares funcionou, mas não sei se está certo. As imagens são assim.
E depois de combinar essas duas imagens com a função de correspondência de modelo do OpenCV, obtive esse resultado
Agora eu não sei como continuar.
Meus modelos são sempre símbolos simples na construção de plantas e nas próprias plantas. Os símbolos podem diferir em tamanho e orientação.
Por exemplo, meu projeto simples:
E meu modelo
Neste exemplo, existe apenas um modelo, mas nos modelos deve encontrar todas as ocorrências, mesmo as com tamanhos e / ou orientações.
Alguém tem uma abordagem de como eu poderia resolver isso?
Editar:
Uma adição à abordagem de Andrey. O algoritmo de captura de distância para um perfil radial. (Usando o 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;
}
fonte
Respostas:
Eu acho que você pode resolver seu problema de uma maneira muito mais fácil. Considerando que você está lidando com projetos, não deve se preocupar com conectividade de borda, ruído e muitas outras coisas que o SIFT e o SURF foram criados para acomodar. Seu modelo é uma forma oca com formas de aresta específicas.
Assim, minha recomendação é:
Aqui está um código do Matlab para você começar - escrevi a parte que encontra o perfil da distância para um blob específico e o calculei para o modelo:
fonte
Aqui está a idéia básica do que sei que pode ser feita, com base em uma palestra do professor Anurag Mittal, do IIT Madras.
A idéia é a detecção de objetos com base na forma, mas obviamente também pode ser estendida para outros lugares.
Seu artigo sobre o mesmo está disponível em: Detecção de Objetos Deformáveis com Base em Contorno de Vários Estágios.
Por outro lado, acho que o SIFT deve funcionar, pois os algoritmos de detecção de canto funcionariam no recurso de modelo que você tem por lá.
Nota: SIFT não é completamente invariável para rotação. Não é capaz de lidar com rotações> 60 graus ou mais. Portanto, formar vários modelos é uma boa ideia.
Como nas transferências de Fourier-Mellin baseadas em log-polar: Elas causam perda de informações devido à forma como a amostragem ocorre para as transformações.
fonte
Eu não pensei muito nisso, mas tenho certeza de que uma solução robusta pode ser encontrada sem muitos problemas usando o clássico Fourier Descriptors (FD). Acho que seu problema pode ser um bom candidato para isso. Não pense que você precisa fazer a detecção de bordas porque possui desenhos de linhas pretas. Basta iniciar a varredura de varredura até atingir os pixels e faça o seguinte:
Apenas trate os perímetros da sua sala como se fossem um sinal 1D, onde a amplitude do sinal é a distância normal do centróide do objeto, amostrada a uma taxa constante. Então, faça um modelo FD simples para a porta. Em seguida, verifique o parâmetro de cada sala com uma espécie de filtro convexo, procurando uma borda ascendente, um pico e uma queda, que define uma janela de início / parada do "sinal" para capturar. Faça um FFT ou algo similar no FD capturado no "sinal" e compare com o modelo FD. Talvez a etapa de comparação do modelo possa ser uma correlação simples com um limite para acionar uma correspondência. Como apenas suas portas têm bordas arredondadas, esse deve ser um problema de correspondência de FD bastante fácil.
Pense nisso como usar FDs para recuperar imagens ou músicas de um banco de dados. Muitos white papers sobre isso.
Este é um bom tutorial sobre o uso de FDs para aproximar formas: duvido que você precise, mas também é possível transformar suas imagens em uma estrutura de coordenadas polares para lidar com rotações, como proposto neste artigo: Recuperação de imagens com base em formas usando descritor genérico de Fourier
vê como eles parametrizam a detecção do perímetro da maçã? A mesma ideia que a sua porta.
BTW, tenho certeza de que o mapeamento de todo o esquema para coordenadas polares não ajudará a invariância rotacional - você precisaria fazer isso sobre o centróide de cada porta, que é exatamente o que seu problema deve começar. É por isso que eu acho que você deseja capturar apenas candidatos a porta e talvez mapeá-los para coordenadas polares para combinar com o modelo de porta FD, como foi feito no documento acima.
deixe-me saber como será, se você tentar essa abordagem.
fonte
Talvez você ache este código do Matlab que escrevi útil: Mosaicos Fractal
Ele implementa o artigo "Registro robusto de imagens usando a transformação log-polar" ( pdf ) em uma aplicação artística que exigia mais robustez do que os métodos tradicionais que encontrei.
fonte