• 图像处理的多线程计算 2017-03-14 11:40:51
    图像处理的算法复杂度通常都比较高,计算也相应比较耗时。利用CPU多线程处理能力可以大幅度加快计算速度。但是,为了保证多线程处理的结果和单线程处理的结果完全相同,图像的多线程计算有一些需要特别考虑的地方。 ...

    图像处理的算法复杂度通常都比较高,计算也相应比较耗时。利用CPU多线程处理能力可以大幅度加快计算速度。但是,为了保证多线程处理的结果和单线程处理的结果完全相同,图像的多线程计算有一些需要特别考虑的地方。

    基本思路:为了能让多个线程同时并行处理,那么各自处理的数据不能有交集,这很好理解。那么基本思路是将一副图像分成多个子块,每个子块数据肯定是没有交集的,每个线程对一个子块数据进行处理,完成后将所有子块处理结果合成最终图像。

    首先,每个子块的大小当然是必须考虑的问题。通常当应用进行一个较长时间的操作,应该用合适的方式告知用户。既然我们把图像分子块处理,如果单个子块处理时间很短,那么每当有一个子块的数据处理完成,我们就可以立即把它相应的处理结果展示给用户。用户就会看到这个图像各个部分的处理结果不断展示出来,直至整个图像完成。这样某种程度上用这种方式就是在告知用户正在处理进行中,避免为了把整个图像处理完成,用户需要等待太长时间。从这个角度来说,如果子块尺寸取的太大,每个子块计算时间肯定相应地加长,对于快速显示部分处理结果给用户是不利的。但是如果子块太小,子块总数就会增加,肯定会增加线程开销和其他一些开销(分割图像,分配子块数据等等),对于总的计算时间是不利的。这是一个权衡问题,可以根据具体情况确定。

    另外,很多图像处理都要考虑像素领域范围的信息,因此对于每个子块的处理不能仅仅使用这个子块的内容。具体地,对于靠近子块边缘的像素,还要把子块外的部分像素信息考虑进来,加入计算,才能保证相应像素的处理结果是正确的。准确来说,如果领域半径为r(对方形或圆形领域来说,其他领域可做相应调整),那么子块处理所需要的所有数据是子块四周向外扩展r像素的范围。

    复制代码
    CRect rect1, rect2;
    rect1.CopyRect(pRect[i]);
    rect1.InflateRect(extend, extend);
    rect2.CopyRect(pRect[i]);
    rect2.MoveToXY(extend, extend);
    if (rect1.top < 0)
    {
        rect2.OffsetRect(0, rect1.top);
        rect1.top = 0;
    }
    if (rect1.left < 0)
    {
        rect2.OffsetRect(rect1.left, 0);
        rect1.left = 0;
    }
    if (rect1.bottom > Height) rect1.bottom = Height;
    if (rect1.right > Width) rect1.right = Width;
    复制代码

    代码中extend就是子块要向四周扩张的大小,其实就是领域半径r。pRect[i]是分割的第i个子块的大小。Height和Width是原图的高宽,扩展子块自然不能超过原图的尺寸。那么最后rect1就是计算所需要的数据在原图中所在的领域范围,应用原图的尺寸对它进行了限制。由于我是把每个子块当成一个新的图像进行处理,rect2就是新图像中子块处理结果所在的位置,用它来合成最终图像。

    最后关于线程具体创建销毁,资源分配与回收,线程同步和通信,不做具体讨论。只讨论一下在这里多线程如何协调工作的问题。由于计算子块的线程只负责处理子块,还需要有人来做分割子块,分配数据给子块计算线程等等工作。本来应该画流程图的,实在懒得画了,这里简单描述一下几个线程如何协调工作的,其实也很简单。界面线程A,处理和用户之间的交互,接受用户命令,发送计算消息给线程B。计算协调线程B接受A的消息,分割子块,分配子块数据,创建子块计算线程Ci。子块计算线程Ci负责子块计算,发送处理结果(成功或失败)消息给线程B或者A。界面线程A收到子块完成消息,可以立即显示子块处理结果,当然也可以什么都不做,等到所有子块处理完再显示。协调线程B收到第i个子块完成消息,回收分配给线程Ci的资源,销毁Ci。如果所有的Ci完成了工作,B发送图像处理完成的消息给A,A可以接着做后续的工作。这里单独用了一个线程B来做子块计算协调的工作,感觉这样比较清晰一些。当然也可以让界面线程A来做这个工作,协调的工作量也不是很大,这样就可以不需要B线程。

    单线程和多线程处理时间对比

    多线程处理速度肯定不能简单地是单线程处理速度的N倍,这只是理想状况。由于很多额外工作(线程开销,准备每个线程的数据,处理结果的合成,线程间同步,图像子块结合部的部分重复计算),多线程是不可能达到理想状况的。下表列出了一副2400x1350大小的24bit图像分成了12个子块,分别在一台I5 4300U(双核四线程)笔记本上和一台I5 6500(四核四线程)台式机上,处理高斯模糊的大概的平均耗时。高斯模糊算法是简单的行列方向两次一维计算,半径取50。在我的测试中,还实时显示了分块的处理结果,速度上可能要更慢一点。

      亮度通道 RGB通道
      单线程 多线程 提速 单线程 多线程 提速
    I5 4300U(双核四线程) 1100毫秒 550毫秒 50% 3060毫秒 1250毫秒 59%
    I5 6500(四核四线程) 670毫秒 240毫秒 64% 1850毫秒 560毫秒 69.7%

    理想状况下四线程耗时最多能减少75%,实际上肯定达不到。在双核四线程平台上,对亮度通道处理,多线程比单线程耗时减少了一半(50%)。对RGB通道,多线程比单线程耗时减少了大概59%。在四核四线程平台上,多线程耗时在亮度通道和RGB通道处理时,分别减少了64%和69%。可以看到,多线程处理的加速效果还是相当明显的。话说牙膏厂超线程的效果还是挺惊人的,不然在双核CPU上耗时减少是不可能超过50%的。当然物理内核的数量就更重要了。

    而且还可以看到一个现象,在单线程处理下,RGB三通道的处理耗时是亮度通道处理耗时3倍略少,约为2.8倍(亮度通道还包括一些在RGB和亮度之间转换的额外计算量)。而在多线程下,RGB三通道的处理时间大大小于亮度一个通道处理时间的3倍,约为2.38倍。相对于单线程,节省的时间更多了。这是因为RGB的处理也是在子块的一个线程中处理的,并没有增加新的线程开销。因此线程开销也是必须考虑的一个因素,不可忽略。

    展开全文
  • 本文介绍MFC中图像采集及图像处理的多线程编方法。创建了三个线程,分别为图像采集、图像处理及图像显示线程线程之间的共享数据有保存的图像链表和图像处理结果存储结构。
  • 调用相机视频进行实时处理,原本是基于c++ 的线程池实现的,后来编译成 dll,转用 c# 的线程池实现,Dll 里面的图像处理过程还是比较多的,但是经常会出现 dll 中内存地址访问冲突,通常是程序跑了一段时间之后。...
  • 线程图像获取并处理 2019-04-21 23:37:15
    实现了windows下多线程图像抓取,并后续进行处理。 #include <iostream> #include <thread> #include <windows.h> #include <opencv2/core/core.hpp> #include <opencv2/highgui/...
  • Python是一门非常适合处理数据和自动化完成重复性工作的编程语言,我们在数据训练机器学习模型之前,通常都需要数据进行预处理,而Python就非常适合完成这项工作,比如需要重新调整几十万张图像的尺寸,Python...
  • 系统开发环境为Ubuntu14.04 Qt5.8.0 opencv2.4.13 系统是在QT框架下,利用海康威视摄像机...用户可在图像处理线程中按自己的需求图像进行处理,对应的为ProcessingThread.cpp 项目源代码见https://github.com/Wa
  • OpenCV中使用线程处理图像 引用:https://gist.github.com/yinguobing/7d1318e31f6e3455f30527a39361512a #!/usr/bin/env python3 ''' Multithreaded video processing minimal sample. Usage: python3 video...
  • MFC中多线程显示相机捕获图片
  • 图像采集图像处理图像显示通过qq1进行生产者、消费者数据传输通过qq2进行生产者、消费者数据传输图像采集30ms、 图像显示30ms、图像处理10ms图像采集图像处理图像显示 这将产生一个流程图。: 链接长方形圆圆角...
  • 本文,通过实际代码演示图像的多线程处理,以下为具体的流程。
  • VC多线程实现图像采集 2020-05-29 23:31:51
    一篇关于图像采集的文章
  • 优化UI界面设计,C#实现多线程4相机测量,多种相机(大恒,巴斯勒,微视,mind微视)SDK开发。多线程实现多相机采集图像并行处理,缩短了处理时间。
  • 线程MFC处理视频 2017-10-13 10:54:23
    在工业相机获取视频的基础上,将工业相机存储的pBuffer数据(包含了一幅图像的所有像素点数据,数据存储规律为B0G0R0,B1G1R1……先行后列)转换成为Mat类图像,因而,可以在OPENCV中进行图像处理。程序如下: void ...
  • 今天刚好看到了Qt多线程,就写了个小例子放出来,希望能帮到跟我一样的初学者。 简单讲下。程序就两个界面。一个主要的QDialog,一个显示图像的自定义控件MyPicBox 。还有就是动态创建了一个QMainWindow,因为我...
  • 在这个看脸的时代,颜值... 随着台式计算机的处理能力日益增强,各种图像拍摄的设备(例如平板电脑、手机摄像头、数码相机、扫描仪等)的普及,以及互联网的加持,使得数字图像处理变得与文字处理一样普及。本书就数字
  • 当电脑与多台相机设备相连接时,需要打开多个相机进行图像信息的采集。下面使用两个线程打开两个摄像头。 #include #include #include #include using namespace cv; using namespace std; DWORD WINAPI ...
  • 最近接手一个项目,需要利用IDS双网口相机出图,并计算目标物体的解像力和均匀性。 IDS双相机分别获取目标物体一部分的外型图案...初步的设计思想是:以相机为分析对象,为每个相机开辟三个线程,分别进行图像的采...
  • 系列博客———————-海康威视摄像头+OpenCV+VS2017 图像处理小结(二)本系列博客记载博主海康威视网络摄像头以及OpenCV库和VS2017开发环境搭建 视频处理工程 的过程,主要是海康威视摄像头与电脑的有线与...
1 2 3 4 5 ... 20
收藏数 6,480
精华内容 2,592