Steve-o 的回答有助于优化您的代码效率。我建议添加一些逻辑来监控执行时间,以帮助您确定在哪里进行优化。
用于时间监控的 OpenCV 逻辑(python):
startTime = cv.getTickCount()
# your code execution
time = (cv.getTickCount() - startTime)/ cv.getTickFrequency()
时间监控的升压逻辑:
boost::posix_time::ptime start = boost::posix_time::microsec_clock::local_time();
// do something time-consuming
boost::posix_time::ptime end = boost::posix_time::microsec_clock::local_time();
boost::posix_time::time_duration timeTaken = end - start;
std::cout << timeTaken << std::endl;
根据我的经验,如何配置 OpenCV 版本非常重要。 IPP 并不是为您提供更好性能的唯一选择。为了更好地利用硬件,确实值得为您的构建努力。
要查看的其他方面是 CPU 和内存利用率。如果您观察您的 CPU 和/或内存利用率,您可能会发现 10% 的代码正在努力工作,而其余时间大部分时间都处于空闲状态。
- 考虑将您的逻辑重构为使用线程的管道,以便您可以一次处理多个图像(如果您正在跟踪并需要以前图像的结果,则需要将代码分解为多个部分,例如预处理/分析并使用 std::queue 在它们之间进行缓冲,并且 imshow 在工作线程中不起作用,因此您需要将结果图像推送到队列中并从主线程中进行 imshow)
- 考虑将持久/全局对象用于不需要每次都重新创建的内核/检测器等对象
- 您的程序运行时间越长,吞吐量是否越慢?您可能需要查看如何处理主循环范围内的图像/变量
- 在函数中分段您的代码使其更具可读性、更易于进行基准测试,并且可以更早地对变量进行去范围(临时 Mat 和结果变量在去范围时释放内存)
- 如果您对 Mat 像素进行低级处理,并在其中迭代大部分图像,请使用单个并行处理并避免写入
- 根据您运行代码的方式,您可以禁用调试以获得更好的性能
- 如果您正在流式传输和转储帧,最好更改相机设置以限制流式传输速率而不是转储帧
- 如果您要将 1 位 12 位转换为 8 位或仅使用图像的某个区域,最好在相机硬件级别执行此操作
这是一个并行 for 循环的示例:
cv::parallel_for_(cv::Range(0, img.rows * img.cols), [&](const cv::Range& range)
{
for (int r = range.start; r < range.end; r++)
{
int x = r / img.rows;
int y = r % img.rows;
uchar pixelVal = img.at<uchar>(y, x);
//do work here
}
});
如果您受到硬件限制(即充分利用 CPU 和/或内存),那么您需要考虑优先处理您的进程/操作系统性能优化/释放系统资源/升级您的硬件
- 增加进程的优先级,使其相对于计算机上运行的其他程序更加贪婪(在 linux 中, unistd.h 中有 nice(int inc),在 windows 中,在 Windows 中 SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS)。 h)
- 优化电源设置以获得最佳性能
- 禁用 CPU 内核停放
- 优化采集硬件设置(增加 rx/tx 缓冲区等)以减轻 CPU 的工作负担