가변 템플릿 일치 스케일 및 회전


12

배율 및 회전 불변 템플릿 일치 방법을 찾고 있습니다. 나는 이미 몇 가지를 시도했지만 내 예제에서 잘 작동하지 않았거나 실행하는 데 시간이 오래 걸렸습니다. SIFT 및 SURF 기능 감지가 완전히 실패했습니다. 또한 Log-Polar Template Matching 기능을 구현하려고 시도했지만 완료하지 못했습니다 (정확히 방법을 몰랐습니다).

이 기사에서 (첫 번째는 독일어)

http://cvpr.uni-muenster.de/teaching/ss08/seminarSS08/downloads/Wentker-Vortrag.pdf

http://www.jprr.org/index.php/jprr/article/viewFile/355/148

그 방법에 대해 읽었습니다. 극좌표를 매핑하는 것이 효과가 있었지만 그것이 맞는지 모르겠습니다. 이미지는 다음과 같습니다.

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

template_log_polar.png

그리고이 두 이미지를 OpenCV의 템플릿 매칭 기능과 일치시킨 후에 그 결과를 얻었습니다.

match_log_polar.png

이제 나는 계속하지 않습니다.

내 템플릿은 항상 청사진과 청사진 자체를 빌드 할 때 간단한 기호입니다. 기호의 크기와 방향이 다를 수 있습니다.

예를 들어 간단한 청사진 :

여기에 이미지 설명을 입력하십시오

그리고 내 템플릿

여기에 이미지 설명을 입력하십시오

이 예제에는 템플릿이 하나만 있지만 청사진에는 크기 및 / 또는 방향이있는 템플릿도 포함됩니다.

누구든지 내가 이것을 해결할 수있는 접근법을 가지고 있습니까?

편집하다:

Andrey의 접근 방식에 추가되었습니다. 방사형 프로파일에 대한 거리 캡처 알고리즘. (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;
}

dsp.SE에 오신 것을 환영합니다. 도와 드리겠습니다.보다 정확한 정보를 제공하는 것이 좋습니다. SIFT와 SURF가 "완전히 실패했다"는 것은 무엇을 의미합니까? 그들은 무엇을 감지 / 일치 했습니까? 또한 개인적으로 Log-Polar Template Matching에 대해 잘 모르지만 시도한 경우 정확히 어디에 문제가 있었습니까?
penelope

SIFT 및 SURF 기능 감지가 템플리트 이미지에서 기능을 찾지 못했습니다. 템플릿에 정보가 너무 적은 것 같습니다 (그 작은 활과 선). Log-Polar 일치의 경우 설명이 나와있는 논문을 찾았지만 정확한 수학은 아닙니다. 검색해서 추가하겠습니다.
Arndt Bieberstein


이봐, 여기에 많은 사람들이 독일어를 이해할 수 없다고 생각합니다. D : 그러나, 다른 모든 것들은 : 주석 대신에 올바른 장소에 새로운 정보를 추가하기 위해 자신의 게시물을 편집 할 수 있습니다. 또한, 여전히 정확히 무슨 문제가 있는지 말하지 않았습니다.
penelope

3
"german Article"의 저자는 영어로 된 기사를 가지고 있습니다 -www-cs.engr.ccny.cuny.edu/~wolberg/pub/icip00.pdf (Google 덕분에)
SergV

답변:


6

훨씬 더 쉬운 방법으로 문제를 해결할 수 있다고 생각합니다. 블루 프린트를 다루는 것을 고려할 때, 에지 연결, 노이즈 및 SIFT 및 SURF가 수용 할 수있는 많은 것들에 대해 걱정하지 않아도됩니다. 템플릿은 특정 모서리 모양을 가진 속이 빈 모양입니다.

따라서 내 추천은 다음과 같습니다.

  • 주변을 걸어 템플릿 중앙 주위의 가장자리 거리 프로파일을 찾습니다. 이것은 템플릿의 방사형 프로파일입니다. 가장 큰 거리로 나누면 크기가 변하지 않습니다. 가장 작은 거리가 가장 먼저 회전 불변이되도록 벡터를 회전시킵니다. (템플릿에 주된 거리가 없으면 나중에 2 단계를 변경할 수 있습니다)

여기에 이미지 설명을 입력하십시오

  • 이미지에서 얼룩을 찾습니다. 파트 (1)에 설명 된 방사형 프로파일을 계산하고 정규화 된 상관 관계로 두 벡터를 비교합니다. 템플릿에 주된 거리가없는 경우 상관 관계는 정규화 된 상호 상관이되고 최대 값을 선택합니다. 임계 값을 초과 한 사람은 일치하는 것으로 간주됩니다.

다음은 시작할 Matlab 코드입니다. 특정 블롭에 대한 거리 프로파일을 찾아서 템플릿에 대해 계산 한 부분을 작성했습니다.

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

닫히지 않은 모양에서는 작동하지 않는 것 같습니다. 아니면 모양의 "구멍"을 건너 뛰나요?
Arndt Bieberstein

@ArndtBieberstein, 그렇습니다. 닫힌 모양에만 작동합니다. 확장 할 수있는 방법이 있어야한다고 생각합니다.
Andrey Rubshtein

OpenCV에는 bwtraceboundary 함수가 포함되어 있지 않기 때문에 필자가 직접 작성하고 홀을 "스킵"하여 0으로 채웠습니다. 다음은 결과가 어떻게 보이는지에 대한 작은 예입니다. 각 템플릿에 대해 5 플롯. 빨간 점은 시작점입니다. 샘플 플롯
안트 Bieberstein

@ArndtBieberstein, 아주 좋은! 어쩌면 당신이 끝나면 결과를 우리와 공유 할 수 있습니다.
Andrey Rubshtein

물론, 강령은 그렇게 훌륭하거나 성능이 좋지는 않지만 작동합니다. 내 질문 아래에 첨부하겠습니다. 그것은 (내가 EmguCV을 사용하고 있습니다) C #으로 작성된 것
안트 Bieberstein에게

3

다음은 IIT Madras의 Anurag Mittal 교수의 이야기를 바탕으로 내가 알 수있는 기본적인 아이디어입니다.

이 아이디어는 형태 기반 물체 감지에 관한 것이지만 다른 곳에서도 확장 될 수 있습니다.

  1. 버클리 에지 검출기를 사용하여 에지를 계산합니다.
  2. 얻은 모서리를 연결하십시오. "글로벌 객체 경계 감지".
  3. 모따기 거리 또는 Houstoff 거리를 사용하여 모양 일치.

그의 논문은 Multi-Stage Contour based 변형 가능한 물체 감지에 있습니다.

반면에 SIFT는 코너 감지 알고리즘이 템플릿 기능에서 작동하므로 작동해야한다고 생각합니다.

참고 : SIFT는 회전이 완전히 변하지 않습니다. 60도 이상의 회전에는 대처할 수 없습니다. 따라서 여러 템플릿을 형성하는 것이 좋습니다.

로그 폴라 기반 푸리에-멜린 트랜스 포스 (Pourier-Mellin Transfroms)에서와 같이 : 변환을 위해 샘플링이 이루어지는 방식으로 인해 정보가 손실됩니다.


이 방법은 정말 유망한 것 같습니다! 귀하의 링크를 열 수 없지만 귀하의 접근 방식을 봤습니다. 나는 SIFT가 완전히 변하지 않는 SIFT라는 것을 몰랐다! 아주 좋은 답변입니다! +1
Arndt Bieberstein

1
Chamfer Distance와 그 작동 방식에 대해서는 거의 찾지 못했습니다 . 링크를 검색하는 사람들을 위해 .
Arndt Bieberstein

@Naresh SIFT는 평면을 벗어난 큰 회전에 대해 회전 불변성이 아닙니다 . 같은 비행기에 없습니다.
a-Jays

1

나는 많은 생각을하지 않았지만 고전적인 푸리에 설명자 (FD)를 사용하면 많은 문제없이 강력한 솔루션을 얻을 수 있다고 확신합니다. 귀하의 문제가 그에 대한 훌륭한 후보라고 생각합니다. 검은 선 그림이있는 가장자리 감지 b / c를 수행 할 필요가 없다고 생각하십시오. 픽셀을 칠 때까지 래스터 스캔을 시작한 후 다음을 수행하십시오.

방의 둘레를 1D 신호처럼 취급하십시오. 여기서 신호 진폭은 물체의 중심으로부터의 일정한 거리이며 일정한 속도로 샘플링됩니다. 따라서 문에 대한 간단한 FD 모델을 수행하십시오. 그런 다음 상승 실, 피크 및 하강을 찾는 일종의 볼록 필터로 각 방의 매개 변수를 스캔하여 캡처 할 "신호"의 시작 / 중지 창을 설정합니다. 캡처 한 "신호"에 대해 FFT 또는 이와 유사한 FD 알고리즘을 수행하고 FD 템플릿과 비교하십시오. 템플릿 비교 단계는 임계 값과의 간단한 상관 관계 일 수 있습니다. 문에만 둥근 모서리가 있기 때문에 FD 일치 문제가 매우 쉽습니다.

데이터베이스에서 FD의 이미지 또는 음악 검색을 사용하는 것처럼 생각하십시오. 그것에 많은 백서가 있습니다.

이것은 대략적인 모양에 FDS를 사용하는 방법에 대한 좋은 튜토리얼 : 나는 당신이 필요합니다 의심,하지만 당신은 처음 본 논문에서 제안 된 것처럼, 회전 처리하는 프레임 워크를 좌표 극성으로 이미지를 변환 할 수 있습니다 : 형상 기반의 이미지 검색 사용 일반 푸리에 기술자

그들이 어떻게 사과 둘레 감지를 FD로 매개 변수화하는지 보라? 당신의 문과 같은 생각입니다.

BTW, 나는 전체 회로도를 극좌표에 매핑하는 것이 회전 불변에 도움이되지 않을 것이라고 확신합니다. 각 문의 중심에 대해 그렇게해야 할 것입니다. 이것은 정확히 문제가 시작하는 것입니다. 이것이 바로 문 후보를 포착하고 위의 링크 된 논문에서와 같이 FD 문 템플릿과 일치하도록 극좌표에 매핑하는 것입니다.

이 방법을 시도하면 어떻게되는지 알려주십시오.


0

아마도 내가 쓴 Matlab 코드가 유용하다는 것을 알 수 있습니다 : 프랙탈 모자이크

필자는 기존의 방법보다 견고성이 요구되는 예술적 응용 프로그램에서 "로그 폴라 변환을 사용한 강력한 이미지 등록"( pdf ) 종이를 구현합니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.