多线程加速图像模板匹配
代码下载地址:http://download.csdn.net/detail/zerolusta/4071088
首先这是个没有什么很好的结局的故事。所以下面这点文字不是为了表现一个怎么怎么好的结果,而是整个让人头疼的过程。
多线程加速算法的实现,不是对于算法本身的优化。而只是针对算法理论的编程实现过程中采用的技巧这里采用的算法是基于灰度的相关函数法。而一般实现图像处理算法的代码示例,都是单线程(即主线程)操作,这样的弊端至少有两点:一是速度很慢,尤其对于这里所用的计算量巨大的模板匹配算法,时间复杂度为。二是主线程进行图像处理的运算,将导致主程序无法进行其他操作和响应,如窗口重绘、鼠标操作等等,相当于卡死状态。把多线程编程应用在此,是一次尝试。到今天为止,也只完成了程序的基本功能,一直都在测试,一直都存在小问题,鲁棒性只能与菲律宾警察一个级别。现在把基本的过程写一写,留做多年后自嘲的凭据吧:-)。
【DIB位图】
程序只兼容dib图像,所以用大家都见过的一个CDib类完成一般性操作。这个类的具体实现,网上应该有很多代码可以找,择而用之。不过在这里只需要用到三四个基本的功能就够了。
【算法计时】
单线程处理的函数也不必详述,这里只是为了与多线程做个对照,看加速的效果如何。当然,为了衡量计算速度,我这里是计算了耗时长短。例如:
【规范返回值】
模板匹配的最终目的是在源图像中确定模板图像的位置,事实上只要知道一个点就可以定位,比如模板左上角点在源图像中的相对坐标。于是我定义了这样一个结构体来作为处理函数的返回值:
这样的好处在于处理结果可作为一个整体返还给调用函数,结构清晰,同时调用函数只需声明一个结构体,用处理函数进行填充,本程序中为view类成员调用doc类成员。在一定程度上是对doc类成员实现细节的隐蔽。
单线程处理返回值获取后,使用设备上下文对象在活动视图区绘制模板位置。这里遇到过一个纠缠了很久的问题。原因在于只顾使用别人封装好的类,而忽略了位图数据结构的特点。在此感谢方毅,多谢他的提示。
【关于多线程】
多线程就像那种你曾在传闻中听到的有多么神秘而又吸引人的异性,直到你亲眼去看了、亲身去相处了,才会发现其实也不过如此。一句题外话,对于一般人而言,Windows编程永远没有真正的懂与不懂。知道就是TRUE,不知道就是FALSE。Don't ask me why, just use it. 如果你连use都不会,要么是因为你不自信,要么是你过于理想化——不自信的人觉得自己不可能掌握它的用法,过于理想化的人总想自己使用自己的操作系统。
多线程属于你只管去用的东西之一。
另外想说一说的想法是,MFC并提供自己相应的线程类CWinThread,在网上你还可能会看到一些老手封装好的CThread类,但作为初学者,我还是倾向于自己使用平台SDK的函数: