C# C图像识别性能-将图像列表与图像字典进行比较

C# C图像识别性能-将图像列表与图像字典进行比较,c#,image,dictionary,comparison,C#,Image,Dictionary,Comparison,我成功地从图像中识别出了字符。因此: 我将所有识别的水滴图像保存在列表中 Bitmap bpt1 = new Bitmap(@"C:\2\torec1.png", true); Bitmap bpt2 = new Bitmap(@"C:\2\torec2.png", true); List<Bitmap> toRecognize = new List<Bitmap>(); toRecognize.Add(bp

我成功地从图像中识别出了字符。因此:

我将所有识别的水滴图像保存在列表中

        Bitmap bpt1 = new Bitmap(@"C:\2\torec1.png", true);
        Bitmap bpt2 = new Bitmap(@"C:\2\torec2.png", true);
        List<Bitmap> toRecognize = new List<Bitmap>();
        toRecognize.Add(bpt1);
        toRecognize.Add(bpt2);
并对图像进行比较:target[index].Key,target[index].Value

for (int i = 0; i < x; i++)
{
   for (int j = 0; j < y; j++)
   {
       if (CompareMemCmp(toRecognize[i], target[j].Value) == true)
       {
       textBox3.AppendText("Found!" + Environment.NewLine);
       textBox2.AppendText(target[j].Key); //Letter is found - save it!
       }
       else {textBox3.AppendText("Don't match!" + Environment.NewLine); }
   }
}
一,。[删除]

二,。从性能的角度来看,我使用的方法是可以容忍的吗?我计划在同一时间对10-20幅图像进行重绘,每个图像的平均字母数为8,字母库将由英文字母26大写+26小写、特殊字母~10和数字10组成

所以我有80多个字母需要识别,模式库由70多个字符组成。演出水平会好吗

建设性的批评欣然接受

问题1:

[删除]

问题2:

视情况而定。 首先,如果性能不够,瓶颈是什么? 我怀疑这是比较MCMP函数。。。你能加快速度吗

如果不是,那么考虑到循环的每个迭代似乎都独立于之前的迭代,您可以尝试并行运行它。 为此,请查看Framework4.0中的任务并行库方法,特别是到

编辑:

如果我们谈论的是图像之间的完美匹配,您可以尝试使用字典查找来加快速度

首先,您可以为位图构建一个包装类,该类可以有效地用作字典键,如下所示:

class BitmapWrapper
{
    private readonly int hash;
    public Bitmap Image { get; private set; }
    public BitmapWrapper(Bitmap img)
    {
        this.Image = img;
        this.hash = this.ComputeHash();
    }

    private int ComputeHash()
    {
        // you could turn this code into something unsafe to speed-up GetPixel
        // e.g. using lockbits etc...
        unchecked // Overflow is fine, just wrap
        {
            int h = 17;
            for (int x = 0; x < this.Image.Size.Width; x++)
                for (int y = 0; y < this.Image.Size.Height; y++)
                    h = h * 23 + this.Image.GetPixel(x, y).GetHashCode();
            return h;
        }
    }

    public override int GetHashCode()
    {
        return this.hash;
    }
    public override bool Equals(object obj)
    {
        var objBitmap = obj as Bitmap;
        if (obj == null)
            return false;
        // use CompareMemCmp in case of hash collisions 
        return Utils.CompareMemCmp(this.Image, objBitmap); 
    }
}
Bitmap le = new Bitmap(@"C:\2\e.png", true);
Bitmap lg = new Bitmap(@"C:\2\g.png", true);
...
var lookup = new Dictionary<string, Bitmap>();
lookup.Add(new BitmapWrapper(le), "e");
lookup.Add(new BitmapWrapper(lg), "g");
...
然后搜索将是:

foreach(var imgToRecognize in toRecognize)
{
   string letterFound;
   if(lookup.TryGetValue(new BitmapWrapper(imgToRecognize), out letterFound))
   {
      textBox3.AppendText("Found!" + Environment.NewLine);
      textBox2.AppendText(letterFound); //Letter is found - save it!
   }
   else
      textBox3.AppendText("Don't match!" + Environment.NewLine);
}
此方法的性能肯定取决于哈希计算,但肯定可以节省大量CompareMECMP调用。

问题1:

[删除]

问题2:

视情况而定。 首先,如果性能不够,瓶颈是什么? 我怀疑这是比较MCMP函数。。。你能加快速度吗

如果不是,那么考虑到循环的每个迭代似乎都独立于之前的迭代,您可以尝试并行运行它。 为此,请查看Framework4.0中的任务并行库方法,特别是到

编辑:

如果我们谈论的是图像之间的完美匹配,您可以尝试使用字典查找来加快速度

首先,您可以为位图构建一个包装类,该类可以有效地用作字典键,如下所示:

class BitmapWrapper
{
    private readonly int hash;
    public Bitmap Image { get; private set; }
    public BitmapWrapper(Bitmap img)
    {
        this.Image = img;
        this.hash = this.ComputeHash();
    }

    private int ComputeHash()
    {
        // you could turn this code into something unsafe to speed-up GetPixel
        // e.g. using lockbits etc...
        unchecked // Overflow is fine, just wrap
        {
            int h = 17;
            for (int x = 0; x < this.Image.Size.Width; x++)
                for (int y = 0; y < this.Image.Size.Height; y++)
                    h = h * 23 + this.Image.GetPixel(x, y).GetHashCode();
            return h;
        }
    }

    public override int GetHashCode()
    {
        return this.hash;
    }
    public override bool Equals(object obj)
    {
        var objBitmap = obj as Bitmap;
        if (obj == null)
            return false;
        // use CompareMemCmp in case of hash collisions 
        return Utils.CompareMemCmp(this.Image, objBitmap); 
    }
}
Bitmap le = new Bitmap(@"C:\2\e.png", true);
Bitmap lg = new Bitmap(@"C:\2\g.png", true);
...
var lookup = new Dictionary<string, Bitmap>();
lookup.Add(new BitmapWrapper(le), "e");
lookup.Add(new BitmapWrapper(lg), "g");
...
然后搜索将是:

foreach(var imgToRecognize in toRecognize)
{
   string letterFound;
   if(lookup.TryGetValue(new BitmapWrapper(imgToRecognize), out letterFound))
   {
      textBox3.AppendText("Found!" + Environment.NewLine);
      textBox2.AppendText(letterFound); //Letter is found - save it!
   }
   else
      textBox3.AppendText("Don't match!" + Environment.NewLine);
}

此方法的性能肯定取决于哈希计算,但肯定可以节省大量CompareMECMP调用。

如果C是适合此作业的工具,则取决于图像的大小。哈希表是一种很好的方法,但您需要比较整个图像,然后才能检查是否有匹配项。对图像进行异或运算非常快,但需要对所有图像进行异或运算,直到找到匹配的图像,这是非常低效的


一个更好的方法是选择一个指纹,它的设计方式是您只需要读取最少的数据量。例如,如果您的图像为每个图像生成不同的值,则可以在中间生成垂直线的哈希代码。如果您不采用这种方法,则在找到一种算法之前,您不需要读取整个图像,而只需要读取几个字节,直到您可以将图像分配到正确的存储桶为止。这仅在输入数据仅包含字典中的图像时有效。否则,这将只是一种概率方法

C是否适合这项工作取决于图像的大小。哈希表是一种很好的方法,但您需要比较整个图像,然后才能检查是否有匹配项。对图像进行异或运算非常快,但需要对所有图像进行异或运算,直到找到匹配的图像,这是非常低效的


一个更好的方法是选择一个指纹,它的设计方式是您只需要读取最少的数据量。例如,如果您的图像为每个图像生成不同的值,则可以在中间生成垂直线的哈希代码。如果您不采用这种方法,则在找到一种算法之前,您不需要读取整个图像,而只需要读取几个字节,直到您可以将图像分配到正确的存储桶为止。这仅在输入数据仅包含字典中的图像时有效。否则,这将只是一种概率方法

中断-打破了这个循环,所以第二个问题是快速进行图像识别需要大量并行计算硬件,就像你耳朵之间的那种。OpenCV是一个库,通常用于此类任务,高度优化SIMD代码以获得类似于此类硬件的外观。Emgu是它的.NET包装器。C不会成为性能瓶颈的根源。您可以在单个CPU上执行此操作,但将其移动到GPU实现将使其速度大大加快,达到数量级。看看Cloo OpenCL library.break-打破了循环,所以第二个问题是做图像识别
n很快就需要大规模并行计算硬件,就像你耳朵里的那种。OpenCV是一个库,通常用于此类任务,高度优化SIMD代码以获得类似于此类硬件的外观。Emgu是它的.NET包装器。C不会成为性能瓶颈的根源。您可以在单个CPU上执行此操作,但将其移动到GPU实现将使其速度大大加快,达到数量级。请看一下CLOOOpenCL库。CompareMememcMP是我见过的最快的位图比较方法之一。它也是不安全的。谢谢,我将在Parallel.For上挖掘更多信息。也许这就是我要找的。首先,如果性能不够,您的瓶颈是什么我希望在半小时内完成15幅图像的识别second@Alex:抱歉,我不知道CompareMemCmp,因为它不在基本库中。我怀疑这就是报道的那个,不是吗?如果是这样的话,是的,我怀疑这很难改进。也就是说,我看不出代码中存在性能问题,通过利用并行性,当n是代码的处理器/内核数时,可能会快n倍pc@Alex:可以肯定的是,你说的是完美的图像匹配,即两个比较的位图完全相等,对吗?如果是这样,您可以计算图像的哈希代码,例如,提取字节,然后利用字典查找。我不知道它是否会更快,因为散列计算可能会很长,但它可能值得一试…虽然我不确定现在我是否会看到任何不同,但当我的字典完成后-我会尝试使用你的方法!看来离开是个好主意。。顺便说一句,在字典里这样保存所有图像可以吗?也许我应该使用数组[]或其他什么?到目前为止,我一直在尝试比较精确的图像和精确的图像B到A:不匹配,然后B到B:匹配。你是说我可以使用哈希代码比较来识别图像中的文本吗?i、 e.整张图片到A、到B、到C——匹配时写下字母。这可能是更好的解决方案,因为我不知道;我不需要做分割。基本上,必须识别的图像列表变成了一个图像,是这样吗?此外,我试图使用您的示例进行哈希比较,但我收到的名称“Utils”在当前上下文错误中不存在。CompareMemeComp是我见过的最快的位图比较方法之一,它也不安全。谢谢,我将挖掘有关Parallel的更多信息。有关。也许这就是我要找的。首先,如果性能不够,您的瓶颈是什么我希望在半小时内完成15幅图像的识别second@Alex:抱歉,我不知道CompareMemCmp,因为它不在基本库中。我怀疑这就是报道的那个,不是吗?如果是这样的话,是的,我怀疑这很难改进。也就是说,我看不出代码中存在性能问题,通过利用并行性,当n是代码的处理器/内核数时,可能会快n倍pc@Alex:可以肯定的是,你说的是完美的图像匹配,即两个比较的位图完全相等,对吗?如果是这样,您可以计算图像的哈希代码,例如,提取字节,然后利用字典查找。我不知道它是否会更快,因为散列计算可能会很长,但它可能值得一试…虽然我不确定现在我是否会看到任何不同,但当我的字典完成后-我会尝试使用你的方法!看来离开是个好主意。。顺便说一句,在字典里这样保存所有图像可以吗?也许我应该使用数组[]或其他什么?到目前为止,我一直在尝试比较精确的图像和精确的图像B到A:不匹配,然后B到B:匹配。你是说我可以使用哈希代码比较来识别图像中的文本吗?i、 e.整张图片到A、到B、到C——匹配时写下字母。这可能是更好的解决方案,因为我不知道;我不需要做分割。基本上,必须识别的图像列表变成了一个图像,是这样吗?此外,我试图使用您的示例进行哈希比较,但我收到的名称“Utils”在当前上下文错误中不存在。在一行或图像的对角线上计算哈希代码可能是一个明智的想法。不管怎么说,将列表中的所有图像导出到字典中,在计算上等于将搜索到的图像与列表中的所有图像进行比较,不同之处在于,在第一种情况下,一旦字典已满且存储了所有哈希代码,您将有更大的速度进行进一步比较。当然,如果你需要不止一次的查找,这是值得的。你是对的,exoring非常快,但取决于图像的大小,它可能很重要。此外,如果您知道不需要完整的图像,您可以通过只加载图像的相关部分来进行匹配,从而节省内存。这将大大节省IO带宽。在图像的一行或对角线上计算哈希代码可能是一个明智的想法。不管怎样,艾尔
l列表中要放入词典的图像在计算上等于将搜索图像与列表中的所有图像进行比较,不同之处在于,在第一种情况下,一旦词典已满且存储了所有哈希代码,您将有更高的速度进行进一步比较。当然,如果你需要不止一次的查找,这是值得的。你是对的,exoring非常快,但取决于图像的大小,它可能很重要。此外,如果您知道不需要完整的图像,您可以通过只加载图像的相关部分来进行匹配,从而节省内存。这将大大节省IO带宽。