Kết hợp mẫu bất biến tỷ lệ và xoay


12

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.

source_log_polar.png http://www.shareimages.com/images/pics/0/0/3/62394-pZSfl5WenZysnpyVnKg-source_log_polar.png

template_log_polar.png

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ả đó

match_log_polar.png

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:

nhập mô tả hình ảnh ở đây

Và mẫu của tôi

nhập mô tả hình ảnh ở đây

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;
}

Chào mừng đến với dsp.SE. Chúng tôi sẽ cố gắng giúp bạn, nhưng cung cấp thông tin chính xác hơn sẽ rất tốt. Ý bạn là gì khi Sift và SURF "thất bại hoàn toàn"? Họ đã phát hiện / khớp gì? Ngoài ra, cá nhân tôi không biết về Kết hợp mẫu Log-Polar, nhưng, nếu bạn đã thử, vấn đề chính xác là ở đâu?
Penelope

Các phát hiện tính năng SIFT và SURF không tìm thấy bất kỳ tính năng nào trong hình ảnh mẫu. Có vẻ như mẫu có quá ít thông tin (chỉ có cái nơ nhỏ và một dòng). Đối với phép so khớp Log-Polar, tôi đã tìm thấy một bài báo được mô tả, nhưng không phải là phép toán chính xác đằng sau nó. Tôi sẽ tìm kiếm nó và thêm nó.
Arndt Bieberstein


Này, không nhiều người ở đây có thể hiểu tiếng Đức, tôi nghĩ: D Nhưng, đối với mọi thứ khác: bạn có thể chỉnh sửa bài đăng của mình để thêm bất kỳ thông tin mới nào vào đúng chỗ, thay vì trong các bình luận. Và, ngoài ra, bạn vẫn không nói chính xác những gì bạn có vấn đề với.
Penelope

3
Tác giả của "Bài báo tiếng Đức" có bài viết bằng tiếng Anh - www-cs.engr.ccny.cuny.edu/~wolberg/pub/IDIA00.pdf (cảm ơn google)
SergV

Câu trả lời:


6

Tôi nghĩ rằng bạn có thể giải quyết vấn đề của bạn một cách dễ dàng hơn nhiều. Xem xét rằng bạn đang xử lý các bản thiết kế, bạn không nên lo lắng về kết nối cạnh, tiếng ồn và nhiều thứ khác mà SIFT và SURF được xây dựng để phù hợp. Mẫu của bạn là một hình dạng rỗng với hình dạng cạnh cụ thể.

Vì vậy, khuyến nghị của tôi là:

  • Đi bộ quanh chu vi và tìm một hồ sơ về khoảng cách của các cạnh xung quanh trung tâm của mẫu. Đây là hồ sơ xuyên tâm của mẫu. Chia cho khoảng cách lớn nhất, để được bất biến quy mô. Xoay vectơ sao cho khoảng cách nhỏ nhất là đầu tiên, là bất biến xoay. (Nếu mẫu của bạn không có khoảng cách chi phối, bạn có thể thay đổi bước 2 sau)

nhập mô tả hình ảnh ở đây

  • Tìm các đốm màu trong hình ảnh. Tính toán cấu hình xuyên tâm được mô tả ở phần (1) và so sánh hai vectơ bằng tương quan chuẩn hóa. Nếu mẫu của bạn không có khoảng cách chi phối, mối tương quan sẽ trở thành tương quan chéo được chuẩn hóa và chọn tối đa). Những người vượt qua một số ngưỡng được coi là phù hợp.

Đây là một số mã Matlab để bạn bắt đầu - Tôi đã viết phần tìm hồ sơ khoảng cách cho một blob cụ thể và tính toán cho mẫu:

function Doors
    im = imread('http://i.stack.imgur.com/Tf8EV.png');
    im = im(:,:,1);
    template = imread('http://i.stack.imgur.com/PlP4i.png');
    template = template(:,:,1);

    blobs = regionprops(template>0,'Area','Image');
    largestBlob = GetLargestBlob(blobs);
    [prof,edgeImage] = GetBlobRadialProfile(largestBlob);

    figure;
    subplot(1,2,1);plot(prof); title('Radial profile')
    subplot(1,2,2);imshow(edgeImage); title('Template');

end

function [prof,edgeImage] = GetBlobRadialProfile(blob)
    paddedImage = padarray( blob.Image,[8 8]);
    erodedImage = imerode(paddedImage,strel('disk',1));
    edgeImage = xor(erodedImage,paddedImage);

    c = regionprops(paddedImage,'Centroid');
    cx  = c.Centroid(1);
    cy  = c.Centroid(2);

    [y,x] = find(edgeImage);
    rad = (x(:)-cx).^2 + (y(:)-cy).^2;
    [~,minIndex] = min(rad);
    contour = bwtraceboundary(edgeImage, [y(minIndex), x(minIndex)],'N');
    prof = (contour(:,2)-cx).^2 + (contour(:,1)-cy).^2;
    prof = prof./max(prof);
end

function largestBlob = GetLargestBlob(blobs)    
    area = [blobs.Area];
    [~,index] = max(area);
    largestBlob = blobs(index);
end

Tôi đoán nó không hoạt động với hình dạng không kín? Hoặc tôi chỉ bỏ qua những "lỗ hổng" trong hình dạng.
Arndt Bieberstein

@ArndtBieberstein, Yep nó chỉ hoạt động cho các hình dạng đóng. Tôi đoán nên có một số phương pháp để mở rộng nó.
Andrey Rubshtein

Vì OpenCV không chứa hàm bwtraceboundary, tôi đã tự viết và chỉ "bỏ qua" các lỗ hổng và chứa đầy số không. Đây là một ví dụ nhỏ về kết quả bây giờ. 5 lô cho mỗi mẫu. Các chấm đỏ là điểm bắt đầu. Lô đất mẫu
Arndt Bieberstein

@ArndtBieberstein, rất hay! Có lẽ bạn có thể chia sẻ kết quả với chúng tôi sau khi bạn hoàn thành.
Andrey Rubshtein

Chắc chắn, Mã không phải là tốt đẹp hoặc hiệu suất, nhưng nó hoạt động. Tôi sẽ đính kèm bên dưới Câu hỏi của tôi. Nó được viết bằng C # (Tôi đang sử dụng EmguCV)
Arndt Bieberstein

3

Đây là ý tưởng cơ bản về những gì tôi biết có thể được thực hiện, dựa trên bài nói chuyện của Giáo sư Anurag Mittal của IIT Madras.

Ý tưởng là phát hiện đối tượng dựa trên hình dạng, nhưng rõ ràng cũng có thể được mở rộng ở nơi khác.

  1. Tính toán edgels bằng cách sử dụng máy dò cạnh Berkeley.
  2. Kết nối các cạnh thu được. "Phát hiện ranh giới đối tượng toàn cầu".
  3. Kết hợp hình dạng bằng khoảng cách Chamfer hoặc Khoảng cách Houstoff.

Bài viết của anh ấy cũng có sẵn tại: Phát hiện các đối tượng biến dạng dựa trên nhiều giai đoạn.

Mặt khác, tôi nghĩ Sift nên hoạt động vì các thuật toán phát hiện góc sẽ hoạt động trên tính năng mẫu mà bạn có ở đó.

Lưu ý: SIFT không hoàn toàn xoay bất biến. Nó không thể đối phó với các góc quay> 60 độ hoặc hơn. Vì vậy, hình thành nhiều mẫu là một ý tưởng tốt.

Như trên Fourier-Mellin Transfroms dựa trên log-cực: Chúng gây mất thông tin do cách lấy mẫu diễn ra cho các biến đổi.


Phương pháp này nghe có vẻ rất hứa hẹn! Tôi không thể mở liên kết của bạn, nhưng tôi đã hiểu được cách tiếp cận của bạn. Tôi không biết rằng SIFT không hoàn toàn xoay vòng! Câu trả lời rất hay! +1
Arndt Bieberstein

1
Tôi hầu như không tìm thấy bất cứ điều gì về Chamfer Khoảng cách và cách thức hoạt động, đối với những người cũng đang tìm kiếm liên kết này hãy thử liên kết này .
Arndt Bieberstein

@Naresh SIFT không phải là bất biến xoay cho các phép quay lớn ra khỏi mặt phẳng. Không trong cùng một mặt phẳng.
a-Jays

1

Tôi đã không suy nghĩ nhiều, nhưng tôi khá chắc chắn rằng một giải pháp mạnh mẽ có thể có mà không gặp nhiều khó khăn khi sử dụng Fourier Descriptors (FD) cổ điển. Tôi nghĩ vấn đề của bạn có thể là một ứng cử viên rất tốt cho điều đó. Đừng nghĩ rằng bạn cần phải phát hiện cạnh b / c bạn có bản vẽ đường màu đen. Chỉ cần bắt đầu quét raster cho đến khi bạn nhấn bất kỳ pixel nào, sau đó thực hiện như sau:

Chỉ cần xử lý chu vi phòng của bạn như thể chúng là tín hiệu 1D, trong đó biên độ tín hiệu là khoảng cách bình thường từ tâm của đối tượng, được lấy mẫu ở một tốc độ ổn định. Vì vậy, làm một mô hình FD đơn giản cho cửa. Sau đó, quét tham số của mỗi phòng bằng một loại bộ lọc lồi tìm kiếm cạnh tăng, đỉnh và ngã, đặt cửa sổ bắt đầu / dừng "tín hiệu" để chụp. Thực hiện một FFT hoặc tương tự FD trên "tín hiệu" đã thu được và so sánh với mẫu FD. Có thể bước so sánh mẫu có thể là một mối tương quan đơn giản với ngưỡng để kích hoạt khớp. Vì chỉ có cửa của bạn có các cạnh tròn nên là một vấn đề khớp FD khá dễ dàng.

Hãy nghĩ về nó giống như sử dụng truy xuất hình ảnh hoặc âm nhạc của FD từ cơ sở dữ liệu. Rất nhiều giấy trắng về điều đó.

Đây là một hướng dẫn tốt về cách sử dụng FD để tạo hình gần đúng: Tôi nghi ngờ bạn sẽ cần nó, nhưng trước tiên bạn cũng có thể chuyển đổi hình ảnh của mình sang khung tọa độ cực để xử lý các phép quay, như đề xuất trong bài viết này: Sử dụng truy xuất hình ảnh dựa trên hình dạng mô tả Fourier chung

xem làm thế nào họ FD tham số hóa phát hiện chu vi táo? Cùng một ý tưởng như cánh cửa của bạn.

BTW, tôi khá chắc chắn việc ánh xạ toàn bộ sơ đồ sang tọa độ cực sẽ không giúp bất biến xoay vòng - bạn sẽ cần phải làm điều đó về tâm của mỗi cánh cửa, đó chính xác là vấn đề của bạn bắt đầu. Đó là lý do tại sao tôi nghĩ rằng bạn chỉ muốn bắt các ứng cử viên cửa và có thể ánh xạ những người đó đến tọa độ cực để phù hợp với mẫu cửa FD, giống như được thực hiện trong bài báo được liên kết ở trên.

cho tôi biết nó diễn ra như thế nào nếu bạn thử phương pháp này.


0

Có lẽ bạn sẽ thấy mã Matlab này tôi đã viết hữu ích: Fractal Mosaics

Nó thực hiện bài báo "Đăng ký hình ảnh mạnh mẽ bằng cách sử dụng biến đổi log-Polar" ( pdf ) trong một ứng dụng nghệ thuật đòi hỏi sự mạnh mẽ hơn so với các phương pháp truyền thống mà tôi tìm thấy.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.