作者 主题: 多点触摸软件CCV架构剖析及优化思路  (阅读 5269 次)

vinjn

  • SuperManager
  • Hero Member
  • *****
  • Thank You
  • -Given: 40
  • -Receive: 96
  • 帖子: 587
多点触摸软件CCV架构剖析及优化思路
« 于: 九月 20, 2011, 11:48:13 am »
CCV,即Core community Vision,是一个开源的多点触摸软件,也是事实上的新媒体互动行业的标配,有很多优点,社区氛围也不错。
甚至国内的多点触摸论坛mt2a上也有CCV的专区,但是没有值得一看的帖子。
我写这个系列文章,是希望可以让后来者以及有志于此的从业人员少走些弯路。
我并不是按照先易后难来安排章节,所以如果第一遍甚至第n遍都看不懂也不奇怪,这需要读者对CCV的源代码足够熟悉了。

优化一。多线程(上)

CCV并不是一个单线程的软件
它有主线程,负责图像处理、跟踪、UDP消息发送
OpenGL线程,负责渲染
摄像头线程,负责捕获数据
ofxTCPServer,负责向flash客户端(开启flash XML模式后)发送数据

CCV在单个摄像头的时候可以轻松达到640*480*30fps,但是一旦提升到高分辨的视频(比如1920*480*30fps)就吃力了
基本就是在个位数了
通过性能剖析软件(如very sleepy)可以获知,大量的cpu时间被耗费在了OpenCV的图像处理函数上,特别是cvSmooth以及cvConvertScale。坏消息是这些函数都是放在主线程里的,好消息是我们可以通过将它们分散到各自的线程中来加速运行。

首先引入一个新的类ImageEntry,每个线程都会拥有自己的ImageEntry。它封装了一个Poco::Event对象用于线程间交互,以及一个ofxCvGrayscaleImage对象以保证每个线程都有自己的一份图像,互不干扰。
程序代码: [选择]
struct ImageEntry 
{
void set(const ofxCvGrayscaleImage& img);//由上一步骤调用,设置image以及event
ofxCvGrayscaleImage& get();//返回image
void wait();//等待event
protected:
Poco::Event event;
ofxCvGrayscaleImage image;
};
接着以真实的smooth_thread和highpass_thread代码为例介绍下这些线程的编写思路

程序代码: [选择]

struct smooth_thread : public ofxThread
{
ProcessFilters* _filter;
ImageEntry& _entry;
smooth_thread(ProcessFilters* filter):_filter(filter),_entry(filter->for_smooth),ofxThread("smooth"){}
void threadedFunction()
{
while (isThreadRunning())
{
_entry.wait();//等待摄像头线程传递的原始图像
ofxCvGrayscaleImage img = _entry.get();//复制一份
if (_filter->bSmooth)//如果需要进行smooth操作
{
img.blur((_filter->smooth * 2) + 1); //调用OpenCV函数
if(!_filter->bMiniMode)
_filter->subtractBg = img; //用于GUI渲染
}
_filter->for_highpass.set(img);//将图像传递给highpass线程
}
}
};

struct highpass_thread : public ofxThread
{
ProcessFilters* _filter;
ImageEntry& _entry;
highpass_thread(ProcessFilters* filter):_filter(filter),_entry(filter->for_highpass),ofxThread("highpass"){}
void threadedFunction()
{
while (isThreadRunning())
{
_entry.wait();//等待前一个步骤(即smooth将图像传给本线程)
ofxCvGrayscaleImage img = _entry.get();//得到新的图像,并且复制一份
if (_filter->bHighpass)//如果需要进行highpass操作,这一块的代码与原始CCV是一模一样的
{
img.highpass(_filter->highpassBlur, _filter->highpassNoise);//调用OpenCV的函数
if(!_filter->bMiniMode)
_filter->highpassImg = img; //用于GUI渲染
}
_filter->for_amplify.set(img);//给下一个步骤(即amplify)传递处理后的图像,可以与_entry.wait()头尾呼应
}
}
};

剩下的几个线程就不一一写出了,图像处理这块我们需要新增五个线程
程序代码: [选择]
thread_list.push_back(new dynamic_bg_thread(this));
thread_list.push_back(new smooth_thread(this));
thread_list.push_back(new highpass_thread(this));
thread_list.push_back(new amplify_thread(this));
thread_list.push_back(new threshold_thread(this));

这样处理后,帧率可以勉强合格,但是一旦开启fiducial tracking还是会降到个位数
这留在下一篇中分享

« 最后编辑时间: 九月 21, 2011, 10:52:47 pm 作者 vinjn »

老三

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 3
  • 帖子: 2
Re: 多点触摸软件CCV架构剖析及优化思路
« 回复 #1 于: 二月 10, 2012, 09:30:35 am »
mt2a上确实没找到个很仔细的教程,一般都是晒效果图的。希望能出下CCV调试的教程,让在路上的人少走些弯路。这就是论坛的价值所在啊

peter_wwj

  • Newbie
  • *
  • Thank You
  • -Given: 0
  • -Receive: 0
  • 帖子: 2
Re: 多点触摸软件CCV架构剖析及优化思路
« 回复 #2 于: 四月 19, 2012, 09:56:48 am »
lz有没有比较简单明了点的入门级教程资料啊?我ccv的小白,刚接触,希望能得到大师指点早点入门.....Q:958782314

Tags: CCV 
 


Back to top