Tôi đang tìm kiếm một phương pháp để khớp mẫu bất biến tỷ lệ và xoay. Tôi đã thử một số, nhưng chúng không hoạt động tốt cho các ví dụ của tôi hoặc đã từng thực hiện. Phát hiện tính năng SIFT và SURF hoàn toàn thất bại. Tôi cũng đã cố gắng thực hiện chức năng Kết hợp mẫu Log-Polar, nhưng tôi chưa bao giờ hoàn thành (không biết chính xác làm thế nào).
Trong các bài viết này (đầu tiên là tiếng Đức)
http://cvpr.uni-muenster.de/teaching/ss08/seminarSS08/doads/Wentker-Vortrag.pdf
http://www.jprr.org/index.php/jprr/article/viewFile/355/148
Tôi đọc về phương pháp đó. Ánh xạ tọa độ cực hoạt động, nhưng tôi không biết liệu nó có đúng không. Các hình ảnh trông như thế này.
Và sau khi kết hợp 2 hình ảnh này với chức năng Ghép mẫu của OpenCV, tôi đã nhận được kết quả đó
Bây giờ tôi không làm thế nào để tiếp tục.
Các mẫu của tôi luôn là các biểu tượng đơn giản trong việc xây dựng các bản thiết kế và bản thiết kế. Các biểu tượng có thể khác nhau về kích thước và định hướng.
Ví dụ bản thiết kế đơn giản của tôi:
Và mẫu của tôi
Trong ví dụ này chỉ có một mẫu, nhưng trong bản thiết kế, nó sẽ tìm thấy tất cả các lần xuất hiện, ngay cả những mẫu có kích thước và / hoặc định hướng.
Có ai có một cách tiếp cận làm thế nào tôi có thể giải quyết điều này?
Biên tập:
Một bổ sung cho cách tiếp cận của Andrey. Thuật toán chụp khoảng cách cho một hồ sơ xuyên tâm. (Sử dụng 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;
}