0

所以,我一直在用 opencv 开发一个实时跟踪系统。几天前,我不得不开始使用 directshow(这对我来说是全新的),因为我需要来自网络摄像头的更高分辨率。分辨率越高,CPU 使用率越高。当仅使用没有任何 opencv 算法的 directshow 时,cpu 以 50% 的速度运行。(我有双核 = 100% 使用一个核心)

所以现在我需要扩展这个系统,以便使用我的两个核心。

我从微软找到了这个很好的例子,并且能够使用我的两个内核运行它:

void test1(){
    parallel_invoke(
        []() { run1(); },
        []() { run2(); }
    );
}

这运行得很好,我能够使用大约 85% 的总 CPU(只有 2 个带有循环的函数)。现在我想在我的其他系统中使用它。而且我不知道该怎么做。

我的系统的简短描述:

int main(){
     startDirectshow()
};

startDirectShow(){
     //code for creating the directshow filter graph. including iSampleGrabber filter.
}

sampleCallBackFunction(....){
      // function called for every frame in the graph
}

到目前为止,每件事都在工作,每帧都会调用 sampleCB(或每秒至少多帧,使用它时可能会丢失帧?!)

我的想法是让“sampleCallBackFunction()”在第二个核心上运行(我不想将它锁定到特定的核心,只使用第一个可用的核心)

但是我发现的示例同时从同一个地方启动了这两个功能。是否有可能以某种方式告诉系统“sampleCallBackFucntion”应该在另一个核心上运行?

我的另一个想法是将数据存储在“sampleCallBackFunction()”中,并将布尔值“newFrameAvailable”设置为 true。并让另一个线程从全局数组中提取数据。

while(true)
    If (newFrameAvailable){
         get-next-frame-in-buffer-and-do-opencv-algorithm();
    }
    else{
         do-nothing();
    }
}

所以。我的问题:如何从另一个函数内部调用一个函数(从“startDirectshow”调用“sampleCallBackFunction”)?

谢谢!

4

2 回答 2

1

首先,您可能想要更好地检查究竟是什么让您的 CPU 在没有处理的情况下过热高达 50%。最有可能的是,它转换为 RGB 颜色空间,您可以通过在另一个像素格式域中处理视频来避免。裸视频捕获不需要那么高的 CPU 使用率值。

如何从另一个函数内部调用一个函数(从“startDirectshow”调用“sampleCallBackFunction”)?

如果您想并行处理和/或在处理数据时继续捕获,这并不是您真正想要做的。该startDirectshow线程是一个控制线程,它启动/停止处理并启动内部流线程。与控制线程同步不会提高性能,但会带来(a)同步开销和(b)终止死锁的机会。

如果你想并行处理,你需要在你的样本抓取回调中复制数据并尽快退出回调。然后一个线程池,例如TPL's 或您自己的线程,将在不影响捕获性能的情况下进行异步处理。

于 2013-05-13T13:11:34.867 回答
1

你的问题不是很清楚,但我想你想sampleCallbackFunction在另一个线程中调用。(函数通常在另一个函数中调用,这使得调用堆栈......)

因为 DirectShow,您sampleCallBackFunction很可能已经在与您的主线程不同的流式线程上运行。当然,流线程上发生的所有事情都是一个逻辑核心的负担。

然后,如果您在 上创建另一个线程sampleCallbackFunction,您的系统足够智能,可以将工作分配到可用内核上,这不是问题。但我怀疑是否能让你灵活地做你必须做的事情,如果你真的想在那里再找一个工人parallel_invoke,我建议你寻找。CreateThread

顺便说一句:在 GUI 应用程序中,在另一个线程中调用函数的最简单方法是使用SendMessage,因为调用总是分发给创建窗口的线程。尽管如此,那个电话还是被阻塞了......

于 2013-05-13T12:27:09.273 回答