2015-06-04 4 views
0

ОБНОВЛЕНО - решаемые LOCKING BITC# шаблон родной Image матч (FIXED)

ЗДЕСЬ НОВЫЙ КОД

public Task<Point[]> MatchImage(Bitmap orig, Bitmap template, int limit = 30) 
    { 
     Task<Point[]> tsk = 
     new Task<Point[]>(() => 
     { 
      BitmapData lockedOrig = orig.LockBits(
       new Rectangle(0, 0, orig.Width, orig.Height), 
       ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); 

      //bloqueando a leitura da memoria em que a imagem nova sera colocada 
      BitmapData lockedTemplate = template.LockBits(
       new Rectangle(0, 0, template.Width, template.Height), 
       ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); 


      Point p; 
      List<Point> l = new List<Point>(); 
      int oh = orig.Height, ow = orig.Width; 
      int th = template.Height, tw = template.Width; 

      for (int y = 0; y < oh - th; y++) 
      { 
       for (int x = 0; x < ow - tw; x++) 
       { 
        p = new Point(x, y); 
        if (sumBitArea(lockedOrig, lockedTemplate, p) <= limit) 
         l.Add(p); 

       } 
      } 

      orig.UnlockBits(lockedOrig); 
      template.UnlockBits(lockedTemplate); 
      return l.ToArray(); 


     }); 

     tsk.Start(); 
     return tsk; 
    } 

    unsafe private int sumBitArea(BitmapData image, BitmapData template, Point p) 
    { 

     int value = 0; 
     int pixelSize = 3; 

     int height = p.Y + template.Height; 
     int width = p.X + template.Width; 
     int x = p.X, xt = 0; 
     int y = p.Y, yt = 0; 
     byte* tRow; 
     byte* oRow; 

     for (yt = 0 ; y < height; y++, yt++) 
     { 
      //criando um ponteiro para a imagem original 
      oRow = (byte*)image.Scan0 + (y * image.Stride); 

      //criando um ponteiro para a nova imagem 
      tRow = (byte*)template.Scan0 + (yt * template.Stride); 

      for (xt = 0; x < width; x++, xt++) 
      { 
       int tmp = Math.Abs((byte)oRow[x * pixelSize + 2] - (byte)tRow[xt * pixelSize + 2]); 
       value += tmp; 
      } 
     } 

     return value; 
    } 

У меня небольшие проблемы производительности здесь ... Мой профессор обработки изображений попросил меня создать шаблонный матч без какой-либо библиотеки, поэтому я сделал это в C# ... он делает работу отлично, но очень очень, очень медленно , чтобы найти шаблон 80x80 на картинке 500x500, это занимает несколько минут, а не используя более 20% моего процессора

Я что-то не так?

вот мой код, все изображения серые.

СТАРЫЙ КОД!

public Task<Point[]> MatchImage(Bitmap orig, Bitmap template, int limit = 30) 
    { 
     Task<Point[]> tsk = 
     new Task<Point[]>(() => 
     { 
      Point p; 
      List<Point> l = new List<Point>(); 
      int oh = orig.Height, ow = orig.Width; 
      int th = template.Height, tw = template.Width; 

      for (int x = 0; x < oh - th; x++) 
       for (int y = 0; y < ow - tw; y++) 
       { 
        p = new Point(x, y); 
        if (sumBitArea(orig, template, p) <= limit) 
         l.Add(p);      

       } 
       return l.ToArray(); 


     }); 

     tsk.Start(); 
     return tsk; 

    } 


    /// <summary> 
    /// Soma os pixels de uma determinada imagem 
    /// PS PARA USAR MANDE A IMAGEM RECORTADA ! 
    /// SE MANDAR INTEIRA VAI RETORNAR O VALOR TOTAL. 
    /// USEM A GRAPHCS E UM RECTANGLE ! 
    /// </summary> 
    /// <param name="image">treixo da imagem original</param> 
    /// <param name="template">imagem template</param> 
    /// <param name="p">ponto inicial de referencia</param> 
    /// <returns>o valor da soma</returns> 
    private int sumBitArea(Bitmap image, Bitmap template, Point p) 
    { 
     int value = 0; 

     int height = p.X + template.Height; 
     int width = p.Y + template.Width; 

     for (int x = p.X, xt = 0; x < height; x++, xt++) 
      for (int y = p.Y, yt = 0; y < width; y++,yt++) 
      { 
       int tmp = Math.Abs(image.GetPixel(y, x).R - template.GetPixel(yt, xt).R); 
       value += tmp; 
      } 

     return value; 
    } 

PS: извините, мой английский Я не так хорошо писать. исправления очень приветствуются

+0

Вы пытались заблокировать биты или использовать [FastBitmap] (https://github.com/LuizZak/FastBitmap) реализацию? Вы должны найти множество реализаций, подобных этому. Это должно ускорить получение пикселей несколько раз. Вам просто нужно позаботиться о том, чтобы правильно распорядиться им. –

+0

WOW IT сделал мгновенно! TX @NikolaDavidovic Я обновлю ответ –

ответ

0

Вы пытались заблокировать биты или использовать реализацию FastBitmap? Вы должны найти множество реализаций, подобных этому. Это должно ускорить получение пикселей несколько раз. Вам просто нужно позаботиться о том, чтобы правильно распорядиться им.