2012-08-27 2 views
1

저는 여가 시간에 컴퓨터 비전 기술을 통해 다양한 게임을 시도하고 자동화하려고합니다. 일반적으로 필터 및 픽셀 감지와 일치하는 템플릿은 저와 잘 맞습니다. 그러나 최근에 필자는 기능 일치를 사용하여 레벨 탐색에 손을 대지 않기로 결정했습니다. 내가 의도 한 것은 탐색 된 전체지도의 필터링 된 이미지를 저장하는 것이 었습니다. FullMapEMGU 2.4의 서핑 기능 감지/매칭 문제

그런 다음 Minimap을 화면에서 몇 초마다 복사 한 다음 동일한 방식으로 필터링하고 Surf를 사용하여 내 전체지도에 일치시킵니다. 플레이어에게 현재 위치를 알려 주어야합니다 (경기의 중심은 플레이어가지도 위에있는 곳). 이 작업의 좋은 예는 다음과 같습니다 (왼쪽에서 일치하는 전체지도가있는 미니 맵 이미지입니다.) GoodMatch

EMGU 라이브러리의 서핑 일치가 잘못된 일치를 찾은 것 같습니다. 많은 경우에 때때로 BadMatch BadMatch2

는 완전히 나쁜 아래와 같이 :. 일어나고있는 것은 그것의 다른 위치에있는 키포인트 더 나은 경기를 찾는 것입니다 무슨 나는 가지 볼 수 있습니다 WonkyMatch

s는 서핑이 스케일 불변 적이기 때문에지도 상에 있습니다. EMGU 라이브러리 나 Surf에 대해 충분히 알지 못하기 때문에 초기 좋은 하나만 받아 들여서 나쁜 매치를 버리거나 튜닝을하면 좋지 않은 매치가 좋은 것입니다.

새 2.4 EMGU 코드베이스를 사용하고 SURF 일치를위한 코드가 아래와 같습니다. 난 정말 그 지점에 그것을 얻을 수 있도록 그것은 단지 같은 크기 (전체 맵에있을 것이라고 정상 minimap 크기의 비율을 비례) 일치하는 결과를 반환합니다 그래서 일부 미친 모양의 일치를 얻을하지 마십시오 .

public Point MinimapMatch(Bitmap Minimap, Bitmap FullMap) 
    { 
     Image<Gray, Byte> modelImage = new Image<Gray, byte>(Minimap); 
     Image<Gray, Byte> observedImage = new Image<Gray, byte>(FullMap);  
     HomographyMatrix homography = null; 

     SURFDetector surfCPU = new SURFDetector(100, false); 
     VectorOfKeyPoint modelKeyPoints; 
     VectorOfKeyPoint observedKeyPoints; 
     Matrix<int> indices; 

     Matrix<byte> mask; 
     int k = 6; 
     double uniquenessThreshold = 0.9; 
     try 
     { 
      //extract features from the object image 
      modelKeyPoints = surfCPU.DetectKeyPointsRaw(modelImage, null); 
      Matrix<float> modelDescriptors = surfCPU.ComputeDescriptorsRaw(modelImage, null, modelKeyPoints); 

      // extract features from the observed image 
      observedKeyPoints = surfCPU.DetectKeyPointsRaw(observedImage, null); 
      Matrix<float> observedDescriptors = surfCPU.ComputeDescriptorsRaw(observedImage, null, observedKeyPoints); 
      BruteForceMatcher<float> matcher = new BruteForceMatcher<float>(DistanceType.L2); 
      matcher.Add(modelDescriptors); 

      indices = new Matrix<int>(observedDescriptors.Rows, k); 
      using (Matrix<float> dist = new Matrix<float>(observedDescriptors.Rows, k)) 
      { 
       matcher.KnnMatch(observedDescriptors, indices, dist, k, null); 
       mask = new Matrix<byte>(dist.Rows, 1); 
       mask.SetValue(255); 
       Features2DToolbox.VoteForUniqueness(dist, uniquenessThreshold, mask); 
      } 

      int nonZeroCount = CvInvoke.cvCountNonZero(mask); 
      if (nonZeroCount >= 4) 
      { 
       nonZeroCount = Features2DToolbox.VoteForSizeAndOrientation(modelKeyPoints, observedKeyPoints, indices, mask, 1.5, 20); 
       if (nonZeroCount >= 4) 
        homography = Features2DToolbox.GetHomographyMatrixFromMatchedFeatures(modelKeyPoints, observedKeyPoints, indices, mask, 2); 
      } 

      if (homography != null) 
      { //draw a rectangle along the projected model 
       Rectangle rect = modelImage.ROI; 
       PointF[] pts = new PointF[] { 
       new PointF(rect.Left, rect.Bottom), 
       new PointF(rect.Right, rect.Bottom), 
       new PointF(rect.Right, rect.Top), 
       new PointF(rect.Left, rect.Top)}; 
       homography.ProjectPoints(pts); 
       Array.ConvertAll<PointF, Point>(pts, Point.Round); 

       Image<Bgr, Byte> result = Features2DToolbox.DrawMatches(modelImage, modelKeyPoints, observedImage, observedKeyPoints, indices, new Bgr(255, 255, 255), new Bgr(255, 255, 255), mask, Features2DToolbox.KeypointDrawType.DEFAULT); 
       result.DrawPolyline(Array.ConvertAll<PointF, Point>(pts, Point.Round), true, new Bgr(Color.Red), 5);     

       return new Point(Convert.ToInt32((pts[0].X + pts[1].X)/2), Convert.ToInt32((pts[0].Y + pts[3].Y)/2)); 
      } 


     } 
     catch (Exception e) 
     { 
      return new Point(0, 0); 
     } 


    return new Point(0,0); 
    } 

답변

1

추출 된 키포인트 주변에 검은 색 영역이있는 경우가 있습니다. 추출 된 키포인트에 해당하는 설명자 사이에서 발생하는 것을 기억하는 기능이 제공됩니다.

SURF 기술자는 일치하는 성능이 좋지 않은 원인 일 수있는 단일 키포인트 및 패치를 설명하지 않습니다.

[EDIT]

시나리오 가능한 후보 분석 방법은 윤곽 부분의 일치를 구성이다. openCv에서 이미 구현 된 것을 찾을 수있을 것 같지 않으므로 Donoser의 좋은 서적 " 효율적인 외곽선 모양 일치"를 제안 할 수 있으며 citeseerx에서 가져 와서 쉽게 구현할 수 있습니다.

+1

달성하려는 목표에 어떤 방법을 사용 하시겠습니까? – OPcorki

+0

감사합니다. 할 일이 있습니다. – OPcorki

+0

반갑습니다. 스미스 워터 만 (Smith Waterman)이라고 불리는 로컬 정렬 알고리즘을 기반으로하는 또 다른 비슷한 접근 방식을 제안 할 수 있습니다. (필자는 제 대학에서 이것을 서열 단백질 정렬에 적용했습니다.) 다음은이 논문의 링크입니다 : http://rogerioferis.com/publications/FerisNordia08.pdf –