Я ищу метод для масштабирования и вращения Инвариант соответствия шаблона. Я уже попробовал некоторые, но они не работали так хорошо для моих примеров или потребовались навсегда, чтобы выполнить. Обнаружение SIFT и SURF полностью не удалось. Я также пытался реализовать функцию согласования логарифмических шаблонов, но я так и не закончил (точно не знал, как это сделать).
В этих статьях (первая на немецком языке)
http://cvpr.uni-muenster.de/teaching/ss08/seminarSS08/downloads/Wentker-Vortrag.pdf
http://www.jprr.org/index.php/jprr/article/viewFile/355/148
Я читал об этом методе. Отображение полярных координат сработало, но я не знаю, правильно ли это. Изображения выглядят так.
И после сопоставления этих двух изображений с функцией сопоставления шаблонов OpenCV я получил этот результат
Теперь я не знаю, как идти дальше.
Мои шаблоны всегда являются простыми символами в построении чертежей и самих чертежей. Символы могут отличаться по размеру и ориентации.
Например, мой простой план:
И мой шаблон
В этом примере есть только один шаблон, но в чертежах он должен найти все вхождения, даже те, которые имеют размеры и / или ориентации.
У кого-нибудь есть подход, как я мог это решить?
Редактировать:
Дополнение к подходу Андрея. Алгоритм захвата расстояния для радиального профиля. (Используя 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;
}
источник
Ответы:
Я думаю, что вы можете решить свою проблему гораздо проще. Учитывая, что вы имеете дело с чертежами, вам не нужно беспокоиться о пограничном соединении, шуме и многих других вещах, для которых были созданы SIFT и SURF. Ваш шаблон представляет собой полую форму с определенными краями.
Таким образом, моя рекомендация:
Вот некоторый код Matlab, с которого вы можете начать - я написал часть, которая находит профиль расстояния для определенного большого двоичного объекта и вычисляет его для шаблона:
источник
Вот основная идея того, что, как я знаю, может быть сделано, основано на выступлении профессора Анурага Миттала из ИИТ Мадрас.
Идея заключается в обнаружении объекта на основе формы, но, очевидно, может быть распространена и в других местах.
Его статья об этом доступна по адресу: Многоэтапное обнаружение деформируемых объектов на основе контура.
С другой стороны, я думаю, что SIFT должен работать, так как алгоритмы обнаружения углов будут работать на основе имеющейся у вас функции шаблона.
Примечание: SIFT не является полностью инвариантным к вращению. Это не в состоянии справиться с вращениями> 60 градусов или около того. Поэтому формирование нескольких шаблонов - хорошая идея.
Как на лог-полярных преобразованиях Фурье-Меллина: они вызывают потерю информации из-за того, как осуществляется выборка для преобразований.
источник
Я не задумывался об этом, но я уверен, что можно найти надежное решение без особых проблем, используя классические дескрипторы Фурье (FD). Я думаю, что ваша проблема может быть очень хорошим кандидатом для этого. Не думайте, что вам нужно определять края, потому что у вас есть черные линии. Просто начните растровое сканирование, пока не дойдете до пикселей, а затем выполните следующее:
Просто обработайте периметры вашей комнаты так, как если бы они были одномерным сигналом, где амплитуда сигнала - это нормальное расстояние от центра тяжести объекта, отобранного с некоторой постоянной частотой. Итак, сделайте простую модель FD для двери. Затем отсканируйте параметр каждой комнаты с помощью своего рода выпуклого фильтра в поисках нарастающего фронта, пика и спада, который устанавливает окно запуска / остановки «сигнала» для захвата. Сделайте FFT или аналогичный алгоритм FD для этого захваченного «сигнала» и сравните с шаблоном FD. Может быть, шаг сравнения шаблонов может быть простой корреляцией с пороговым значением для запуска совпадения. Так как только у ваших дверей есть закругленные края, это должно быть довольно легкой проблемой соответствия FD.
Думайте об этом как об использовании FD для поиска изображений или музыки из базы данных. Много белой книги по этому вопросу.
Это хороший учебник по использованию FD для аппроксимации форм: я сомневаюсь, что он вам понадобится, но вы также можете сначала преобразовать ваши изображения в полярную систему координат, чтобы справиться с поворотами, как предложено в этой статье: поиск изображений на основе формы с использованием универсальный дескриптор Фурье
Посмотрите, как они FD параметризуют обнаружение периметра яблока? Та же идея, что и твоя дверь.
Кстати, я почти уверен, что отображение всей схемы в полярные координаты не поможет вращательной инвариантности - вам нужно будет сделать это относительно центроида каждой двери, что и является вашей главной задачей. Вот почему я думаю, что вы хотите просто захватить кандидатов на двери и, возможно, сопоставить их с полярными координатами, чтобы они соответствовали шаблону двери FD, как это было сделано в статье, приведенной выше.
дайте мне знать, как это происходит, если вы попробуете этот подход.
источник
Возможно, вы найдете этот код Matlab, который я написал, полезным: Fractal Mosaics
В ней реализована статья «Надежная регистрация изображений с использованием логополярного преобразования» ( pdf ) в художественном приложении, которое требовало большей надежности, чем традиционные методы, которые я обнаружил.
источник