轮廓检测是计算机视觉中占据了我大部分时间的工作,需要更快的速度。通过使用NEON指令和向量化优化了其他所有内容,但轮廓检测仍然占据着主导地位。不幸的是,我不知道如何对其进行优化。
我正在使用经典的矩形检测流程来查找基准标记,即cvFindContours(),然后从轮廓中近似出正方形。在许多标记可见的情况下(或者灾难性地,当可见的矩形网格不是标记时),仅调用cvFindContours()就可能需要超过30毫秒的时间在iPhone上。
我已经用cvFindContours()替换了非常昂贵的C++ cv::FindContours()。特别是如果传递一个vector >,C++版本花费更长的时间来分配和填充向量,比内部的cvFindContours()还要慢!
现在,我完全受制于cvFindContours中的时间,或更具体地说,受制于cvFindNextContour()的时间。cvFindNextContour内部的代码有很多分支,不太容易向量化。它还实现了一个复杂的算法,我不相信自己能在任何优化尝试中不出错。
我已经查看了cvBlobLib(为了消除歧义,我指的是这个网址:http://code.google.com/p/cvblob/),看看它是否提供了可以更快地完成相同任务的替代算法。源代码的基本下载非常缓慢,因为它将轮廓记录到std::list()中,并几乎所有时间都花在内存分配上。用预先大小为256个元素的std::vector替换该列表以消除push_back()上的初始复制仍然会使函数的运行时间比cvFindContours()长3倍,其中66%直接在cvb::cvLabel()中。因此,这种方法似乎不可行。
有没有人有任何想法可以优化检测许多矩形。我的模糊手势包括:
我正在使用经典的矩形检测流程来查找基准标记,即cvFindContours(),然后从轮廓中近似出正方形。在许多标记可见的情况下(或者灾难性地,当可见的矩形网格不是标记时),仅调用cvFindContours()就可能需要超过30毫秒的时间在iPhone上。
我已经用cvFindContours()替换了非常昂贵的C++ cv::FindContours()。特别是如果传递一个vector >,C++版本花费更长的时间来分配和填充向量,比内部的cvFindContours()还要慢!
现在,我完全受制于cvFindContours中的时间,或更具体地说,受制于cvFindNextContour()的时间。cvFindNextContour内部的代码有很多分支,不太容易向量化。它还实现了一个复杂的算法,我不相信自己能在任何优化尝试中不出错。
我已经查看了cvBlobLib(为了消除歧义,我指的是这个网址:http://code.google.com/p/cvblob/),看看它是否提供了可以更快地完成相同任务的替代算法。源代码的基本下载非常缓慢,因为它将轮廓记录到std::list()中,并几乎所有时间都花在内存分配上。用预先大小为256个元素的std::vector替换该列表以消除push_back()上的初始复制仍然会使函数的运行时间比cvFindContours()长3倍,其中66%直接在cvb::cvLabel()中。因此,这种方法似乎不可行。
有没有人有任何想法可以优化检测许多矩形。我的模糊手势包括:
是否有与cvFindContour()等效的快速实现, 最好是源代码,因为我需要多平台支持?
只有“成功”的矩形是有用的,大多数轮廓都不需要,特别是它们的内部轮廓是无用的。从理论上讲,我不需要调用cvFindContours,而是可以调用cvStartFindContours / cvFindNextContour,在找到每个轮廓时进行测试,并且如果我找到所需的矩形,则不进行递归,因为子矩形保证是无用的?
是否有完全不同的矩形检测算法可以使用,而不是经典的FindContours() / ApproxPoly()方法?
有没有一种方法可以使用感兴趣的区域来"引导"cvFindContours? 例如,即使采用非常激进的阈值,FAST角点检测几乎总是返回我的基准标记角落。有没有办法使用该点集来限制检测范围? (不幸的是,对于我的应用程序中经常出现的许多标记或与标记无关的密集网格线而言,我不确定这有多大帮助。)
与上面相同的想法,由于Blob检测(如果我理解正确)可以实现为递归洪水填充,因此是否有任何快速的矢量化实现可用于从中提取有趣的Blob矩形,并从那里开始进行轮廓检测的种子?
欢迎提出任何想法!