Как я могу найти шаблон изображения в другом изображении? Kinect и AForge предпочтительнее - PullRequest
2 голосов
/ 23 января 2012

Я скопировал образец AForge отсюда: http://www.aforgenet.com/framework/features/template_matching.html И надеялся, что он будет работать с 2 битмапами в качестве источников, как в следующем коде:

    Bitmap findTemplate (Bitmap sourceImage, Bitmap template)
    {

    // create template matching algorithm's instance
    // (set similarity threshold to x.y%, 1.0f = 100%)
    ExhaustiveTemplateMatching tm = new ExhaustiveTemplateMatching( 0.4f );
    // find all matchings with specified above similarity
    TemplateMatch[] matchings = tm.ProcessImage( sourceImage, template ); **// "Unsupported pixel format of the source or template image." as error message**
    // highlight found matchings
    BitmapData data = sourceImage.LockBits(
        new Rectangle( 0, 0, sourceImage.Width, sourceImage.Height ),
        ImageLockMode.ReadWrite, sourceImage.PixelFormat );
    foreach ( TemplateMatch m in matchings )
    {
        AForge.Imaging.Drawing.Rectangle( data, m.Rectangle, System.Drawing.Color.White );
        // do something else with matching
    }
    sourceImage.UnlockBits( data );
    return sourceImage;
    }

Но при вызове TemplateMatch [] matchings = tm.P .... выдает ошибку, упомянутую выше. Шаблон генерируется следующим образом:

Bitmap templatebitmap=(Bitmap)AForge.Imaging.Image.FromFile("template.jpg");

источник генерируется с помощью веб-камеры kinect, где PlanarImage отформатирован как растровое изображение (метод скопирован откуда-то, но до сих пор работал)

 Bitmap PImageToBitmap(PlanarImage PImage)
        {
            Bitmap bmap = new Bitmap(
              PImage.Width,
              PImage.Height,
              System.Drawing.Imaging.PixelFormat.Format32bppRgb);
            BitmapData bmapdata = bmap.LockBits(
              new Rectangle(0, 0, PImage.Width,
                                   PImage.Height),
              ImageLockMode.WriteOnly,
              bmap.PixelFormat);
            IntPtr ptr = bmapdata.Scan0;
            Marshal.Copy(PImage.Bits,
                         0,
                         ptr,
                         PImage.Width *
                            PImage.BytesPerPixel *
                                 PImage.Height);
            bmap.UnlockBits(bmapdata);
            return bmap;
        }

Итак, кто-нибудь может мне помочь, где моя ошибка? Или, может быть, кто-нибудь знает лучший способ сопоставить шаблон с Kinect? Общая задача состоит в том, чтобы обнаружить известный объект с помощью kinect, в моем случае - резиновой утки.

Спасибо, в сообщении.

Ответы [ 2 ]

0 голосов
/ 25 февраля 2012

вот решение, использующее AForge, но оно медленное, занимает около 5 секунд, но оно работает. Как правило, вам нужно представить загрузку и установку платформы AForge.указать с помощью пространства имен AForge

и скопировать вставить, чтобы он работал

System.Drawing.Bitmap sourceImage = (Bitmap)Bitmap.FromFile(@"C:\SavedBMPs\1.jpg");
System.Drawing.Bitmap template = (Bitmap)Bitmap.FromFile(@"C:\SavedBMPs\2.jpg");
// create template matching algorithm's instance
// (set similarity threshold to 92.5%)

ExhaustiveTemplateMatching tm = new ExhaustiveTemplateMatching(0.921f);
// find all matchings with specified above similarity

TemplateMatch[] matchings = tm.ProcessImage(sourceImage, template);
// highlight found matchings

BitmapData data = sourceImage.LockBits(
    new Rectangle(0, 0, sourceImage.Width, sourceImage.Height),
    ImageLockMode.ReadWrite, sourceImage.PixelFormat);
foreach (TemplateMatch m in matchings)
{

        Drawing.Rectangle(data, m.Rectangle, Color.White);

    MessageBox.Show(m.Rectangle.Location.ToString());
    // do something else with matching
}
sourceImage.UnlockBits(data);
0 голосов
/ 05 февраля 2012

Итак, я просто реализовал это сам.Но это так медленно - поэтому, если у кого-то есть идеи по улучшению, не стесняйтесь критиковать мой код:

    public class Position
    {
        public int bestRow { get; set; }
        public int bestCol { get; set; }
        public double bestSAD { get; set; }
        public Position(int row, int col, double sad)
        {
            bestRow = row;
            bestCol = col;
            bestSAD = sad;
        }
    }

    Position element_position = new Position(0, 0, double.PositiveInfinity);
    Position ownSearch(Bitmap search, Bitmap template) {
        Position position = new Position(0,0,double.PositiveInfinity);
        double minSAD = double.PositiveInfinity;


        // loop through the search image
        for (int x = 0; x <= search.PhysicalDimension.Width - template.PhysicalDimension.Width; x++)
        {
            for (int y = 0; y <= search.PhysicalDimension.Height - template.PhysicalDimension.Height; y++)
            {
                position_label2.Content = "Running: X=" + x + "  Y=" + y;
                double SAD = 0.0;

                // loop through the template image
                for (int i = 0; i < template.PhysicalDimension.Width; i++)
                {
                    for (int j = 0; j < template.PhysicalDimension.Height; j++)
                    {
                        int r = Math.Abs(search.GetPixel(x + i, y + j).R - template.GetPixel(i, j).R);

                        int g = Math.Abs(search.GetPixel(x + i, y + j).G - template.GetPixel(i, j).G);

                        int b = Math.Abs(search.GetPixel(x + i, y + j).B - template.GetPixel(i, j).B);

                        int a = template.GetPixel(i, j).A;

                        SAD = SAD + ((r + g + b)*a/255 );

                    }
                }
                // save the best found position 
                if (minSAD > SAD)
                {
                    minSAD = SAD;
                    // give me VALUE_MAX
                    position.bestRow = x;
                    position.bestCol = y;
                    position.bestSAD = SAD;
                }
            }
        }
        return position;
    }
...