您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

与Python相比,C#中的OpenCV MatchTemplate太慢了

与Python相比,C#中的OpenCV MatchTemplate太慢了

我在下面的源代码中结合了denfromufa和HouseCat提出的解决方案,并进行了一些总体清理,因此您可以看到代码效果。由于我使用 / 编写了重构代码,因此您还将注意到可读性方面的一些改进。

尽管 denfromula 正确地指出了实现问题,并且 HouseCat 提到使用更多的cpu资源,但真正的收益取决于减少图像搜索算法期间执行的操作数量

假设该MinMax()功能遍历图像的所有像素以收集所有这些统计信息,但是您只对使用感兴趣maxValue[0]。极好的微调是 当maxValue[0]低于最小阈值时, 。显然,这就是您功能所需要的。切记: 。

似乎您正在尝试识别图像集中的任何图像是否与您输入的屏幕截图(tela)相匹配。如果没有太多要匹配的图像,并且您一直在检查屏幕上是否有新的匹配项,则强烈建议预先加载所有这些图像匹配对象,并在函数调用之间重用它们。

以防万一您每秒要获取多个屏幕截图,然后尝试重用屏幕截图的缓冲区。 不断 。

这很难获得,并且取决于您要为此投资多少。 (图像匹配阶段,OCR阶段,鼠标位置绘画阶段,视频记录阶段等) 。这个想法是创建固定数量的容器并重用它们,避免它们的创建和破坏。容器的数量类似于管道系统的“缓冲区大小”。

最后的优化使用这些外部库确实很难实现,因为在大多数情况下,它们的API需要一些内部位图实例化,并且微调也会导致库与外部库之间的极端软件耦合。因此,您将不得不深入研究这些漂亮的库以了解它们的实际工作原理,并构建自己的自定义框架。我可以说这是一次很好的学习经历。

这些库在许多方面确实很棒。它们提供了通用API,以提高功能的可重用性。这也意味着它们在单个API调用中处理的内容远远超出您的实际需要。对于高性能算法,您应该始终重新考虑那些库中实现目标所需的基本功能是什么,如果它们是您的瓶颈,请自己解决

我可以说,一个好的微调图像识别算法只需花费几毫秒即可完成您想要的操作。我经历过图像识别应用程序,该应用程序几乎可以瞬间完成较大的屏幕截图(例如Eggplant Functional)。

您的重构代码应如下所示。我没有包括我提到的所有那些经过微调的算法-您最好在SO中为它们提出单独的问题。

        Image<Bgr, byte> source = new Image<Bgr, byte>(ofd.FileName);

        // Preferably use Path.Combine here:
        string dir = Path.Combine(Directory.GetCurrentDirectory(), "Images");

        // Check whether directory exists:
        if (!Directory.Exists(dir))
            throw new Exception($"Directory was not found: '{dir}'");

        // It looks like you just need filenames here...
        // Simple parallel foreach suggested by HouseCat (in 2.):
        Parallel.ForEach(Directory.GetFiles(dir), (fname) =>
        {
            Image<Gray, float> result = source.MatchTemplate(
                new Image<Bgr, byte>(fname.FullName),
                Emgu.CV.CvEnum.TemplateMatchingType.CcoeffNormed);

            // By using C# 7.0, we can do inline out declarations here:
            result.MinMax(
                out double[] minValues,
                out double[] maxValues,
                out Point[] minLocations,
                out Point[] maxLocations);

            if (maxValues[0] > 0.96)
            {
                // ...
                var result = ...
                return result; // <<< As suggested by: denfromufa
            }

            // ...
        });

快乐调音;-)

python 2022/1/1 18:27:27 有190人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶