优化二进制图像中白色像素的计算

时间:2015-09-10 04:23:12

标签: c++ opencv image-processing optimization raspberry-pi2

我有一个程序,它执行以下步骤(使用OpenCV):

  1. 连接相机
  2. 开始循环
  3. 获取框架
  4. 提取红色频道
  5. 阈值提取的频道
  6. 将它放入双端队列以构建缓冲区(此时为三个图像缓冲区)
  7. 计算缓冲区中帧的变化(包括某些形态)
  8. 将该变体视为二进制图像
  9. 计算变化量(白色像素)
  10. 如果有变化,请计算其中心。
  11. 我的问题是,从第二步开始的循环理想情况下每秒重复90次,并且它运行的CPU非常弱(Raspberry PI),所以我决定在应用程序一旦它进行基准测试颈。

    我把事情分成了四组。步骤3,4-6,6-8和9.以下是一些以微秒为单位的结果(基于系统时间的基准,而不是CPU时间,它们不是100%精确)

      

    读取相机:5101;更新缓冲区:15032;计算变化:8149;计数非零:51665

         

    读取相机:5446;更新缓冲区:16335;计算变化:8365;计数非零:50005

         

    读取相机:5394;更新缓冲区:15423;计算变化:7163;计数非零:43006

         

    读取相机:7527;更新缓冲区:20051;计算变化:7919;非零数:54895

         

    阅读相机:5492;更新缓冲区:16657;计算变化:7757;计数非零:1034739

    因此需要5到7.5ms读取帧,15到20ms才能应用一些处理并更新缓冲区,7到8.5ms来计算缓冲区变化,然后45ms到一秒钟来计算变化量。< / p>

    在最后一步经常出现这种情况,所以1秒并不罕见。

    为什么在最后一步中需要这么多?这是一行代码:

      

    variatedPixels = countNonZero(变体);

    最佳情况为72毫秒(第一步为27毫秒,最后一步为45毫米),我无法接近每秒处理90帧,这些都是超频RPi2上的时间。对PI来说,这显然过于乐观了。

    我可以采取的最差的是30 FPS的应用程序工作,但在这种情况下,它不能丢弃一个帧。这意味着代码执行时间不到33毫秒。

    有没有办法在不到6毫秒内重现该行?与其余代码相比,它似乎并没有做那么多,有些事情感觉不对。为什么它有时达到顶峰?可以是由于线程更改吗?

    到目前为止我的想法是:

    • 使程序多线程化。 (它真的不需要回答 实时,只是不能丢帧。这是一个400毫秒的窗口 显示结果)
    • 之后将位深度从8位减少到3位 阈值(它可能导致错误的结果,没有性能 好处)。

    由于我是C ++的新手,我想避免使用复杂的解决方案,例如多线程。

    修改 这是我的代码:https://gist.github.com/anonymous/90570c37f175fd2461b4 已经清理过来直接解决问题。 我可能搞砸了指针,但它确实有用。请告诉我,如果因为我是新的而有明显错误的事情,并希望代码不那么糟糕。 :)

    编辑2: 我在清理代码时修复了一个小错误。第10步总是被执行,它也被错误地包含在步骤9次中。 似乎有5-6&#34; imshows&#34;每秒更新需要在PI上占用大量CPU。 (我忽略了,因为在桌面上它甚至不占用1%的CPU来显示要调试的帧。)

    现在我觉得我在25-35ms。需要更多优化以确保它始终有效。到目前为止,我的算法的检测率似乎接近~80%。

0 个答案:

没有答案