优化我的图像搜索程序

时间:2015-09-03 20:09:48

标签: c# .net algorithm search image-processing

我的例程如下(SpeedyBitmap类只锁定每个位图以便更快地进行像素数据访问):

    private static bool TestRange(int number, int lower, int upper) {
        return number >= lower && number <= upper;
    }

    public static List<Point> Search(Bitmap toSearch, Bitmap toFind, double percentMatch = 0.85, byte rTol = 2, byte gTol = 2, byte bTol = 2) {
        List<Point> points = new List<Point>();
        Stopwatch stopwatch = new Stopwatch();

        stopwatch.Start();

        int findArea = toFind.Width * toFind.Height;
        int allowedMismatches = findArea - (int)(findArea * percentMatch);
        int mismatches = 0;

        using (SpeedyBitmap speedySearch = new SpeedyBitmap(toSearch)) {
            using (SpeedyBitmap speedyFind = new SpeedyBitmap(toFind)) {
                for (int i = 0; i < speedySearch.Height - speedyFind.Height + 1; i++) {
                    for (int j = 0; j < speedySearch.Width - speedyFind.Width + 1; j++) {
                        for (int k = 0; k < speedyFind.Height; k++) {
                            for (int l = 0; l < speedyFind.Width; l++) {
                                Color searchColor = speedySearch[j + l, i + k];
                                Color findColor = speedyFind[l, k];

                                if (!TestRange(searchColor.R, findColor.R - rTol, findColor.R + rTol) ||
                                    !TestRange(searchColor.G, findColor.G - gTol, findColor.G + gTol) ||
                                    !TestRange(searchColor.B, findColor.B - bTol, findColor.B + bTol)) {
                                    mismatches++;

                                    if (mismatches > allowedMismatches) {
                                        mismatches = 0;

                                        goto notFound;
                                    }
                                }
                            }
                        }

                        points.Add(new Point(j, i));

                        continue;

                        notFound:
                        ;
                    }
                }
            }
        }

        Console.WriteLine(stopwatch.ElapsedMilliseconds);

        return points;
    }

搜索中等大小的图像(1000x1000)需要20秒以上。删除百分比匹配会将其降低到几百毫秒,所以我认为我确定了主要瓶颈所在。

如何让这次跑得更快?也许我可以将二维数组展平为一维数组,然后对两者进行某种序列检查,以便可能匹配toFind位图数据出现的最长序列以及相应的公差并匹配百分。如果这是一个很好的解决方案,我将如何开始实施呢?

0 个答案:

没有答案