最近老师,让我做一下关于视频处理方面的一个项目,在实时处理这里实在是卡住了太长时间,因为不知道如何使用多线程来进行实时检测,终于有点眉目,来写个笔记记录一下。

首先需要介绍一下关于项目的背景,做一个人脸检测系统,通过摄像头实时的进行检测。

刚开始,使用settimer实现,但效果视频流畅度不好。

最后使用多线程来解决这个问题。多线程的作用和定义的就不再赘述了。

介绍两个线程函数

在MFC中实现多线程有两个函数,一个是AfxBeginThread 一个是 CreateThread

 HANDLE WINAPI CreateThread(
_in LPSECURITY_ATTRIBUTES lpThreadAttributes,
_in SIZE_T dwStackSize,
_in LPTHREAD_START_ROUTINE lpStartAddress,
_in LPVOID lpParameter,
_in DWORD dwCreationFlags,
_out LPDWORD lpThreadId
);

参数:
lpThreadAttributes: 指向一个LPSECURITY_ATTRIBUTES结构的指针决定返回的句柄能否被继承,如果lpThreadAttributes为空,这个句柄不能被继承。
sdStackSize:初始化的堆栈大小,以字节为单位。如果为0,使用默认的大小,即使用和当先线程一样大的堆栈大小。
lpStartAddress:函数的入口地址,一般为线程函数名。
lpParameter:一个参数指针,被传递到线程函数里。
dwCreationFlags:线程创建的标志。如果为CREATE_SUSPENDED这个标志,那么需要使用ResumeThread函数来激活线程函数,如果为0,线程函数立刻执行。
IpThreadId:一个指向线程id的指针,如果为空,线程id不被返回。

如果函数成功执行,返回值将是这个新线程的句柄。如果失败,返回值是NULL。

如果线程函数return,返回值会隐式条用ExitThread函数,可以使用GetExitCodeThread函数获得该线程函数的返回值。

系统中的线程对象一直存活到线程结束,并且所有指向它的句柄都需要通过调用CloseHandle关闭。

 CWinThread* AfxBeginThread(
AFX_THREADPROC pfnThreadProc,
LPVOID pParam,
int nPriority = THREAD_PRIORITY_NORMAL,
UINT nStackSize = ,
DWORD dwCreateFlags = ,
LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL
);
CWinThread* AfxBeginThread(
CRuntimeClass* pThreadClass,
int nPriority = THREAD_PRIORITY_NORMAL,
UINT nStackSize = ,
DWORD dwCreateFlags = ,
LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL
);

参数:
pfnThreadProc:线程函数的入口地址。
 函数原型:UINT __cdecl MyControllingFunction( LPVOID pParam );
pThreadClass:继承CWinThread类的RUNTIME_CLASS对象。
pParam: 传递给线程函数的参数,可以为0。
nPriority:线程优先级。
nStackSize:指明线程堆栈的大小,以字节为单位,可以为0。
dwCreateFlags:线程创建标志。
lpSecurityAttrs:线程安全属性。

这两种之间的区别

CreateThread是Windows的API函数,提供操作系统级别的创建线程的操作,这个函数即是操作系统提供的接口。

CreateThread的线程函数形式为 DWORD WINAPI ThreadFun(LPVOID pParam)

AfxBeginThread则是编译器对它的封装

CreateThread的线程函数形式为 UINT ThreadFun(LPVOID pParam)

要在线程中对图片控件picturecontrol进行操作需要如下所示

CWinThread* mythread = AfxBeginThread((AFX_THREADPROC)ThreadFun,this,THREAD_PRIORITY_NORMAL,0,0,NULL);

将this作为参数传到线程函数中使用,这样即可通过下面两行代码得到一个dlg的指针,通过它来进行操作一些类的成员函数

                  HWND hwnd=(HWND)pParam;
CcaptureDlg *pMainDlg = (CcaptureDlg*)(hwnd);
                 CDC* pDC=(CDC*)pMainDlg->GetDlgItem(nID)->GetDC();
HDC hDC=pDC->GetSafeHdc ();
CRect rect;
pMainDlg->GetDlgItem(nID)->GetClientRect (&rect);
CvvImage images;
images.CopyOf(iplimg);
images.DrawToHDC (hDC,rect);
images.Destroy();
pMainDlg->ReleaseDC(pDC);

对于终止进程,通过查阅资料,了解到对于进程,不能直接暴力地终止它,这里我才用的是发送一个消息,来使进程结束运行

这里我使用的函数为:PostThreadMessage()

 BOOL WINAPI PostThreadMessage(
_In_ DWORD idThread,
_In_ UINT Msg,
_In_ WPARAM wParam,
_In_ LPARAM lParam
);

idThread 为线程id

Msg 指定发送的消息,windows常用消息含义

wParam 消息的附加信息

lParam  消息的附加信息

if(::PostThreadMessage(mythread->m_nThreadID,STOP_THREAD,0,0))
    {
        WaitForSingleObject(mythread, INFINITE );//等待进程状态发生变化
    }//结束进程

注意:调用GetLastError可以查看出错信息,而且 这里的STOP_THREAD不能是0—VM_USER-1范围内的数字,设置为这些数时,会与系统预定义发生冲突,可以设为VM_USER+1

接收消息函数使用PeekMessage()函数,

 BOOL WINAPI PeekMessage(
_Out_ LPMSG lpMsg,
_In_opt_ HWND hWnd,
_In_ UINT wMsgFilterMin,
_In_ UINT wMsgFilterMax,
_In_ UINT wRemoveMsg
);

lpMsg 为指向MSG结构的指针,用于存放消息

hWnd  指的是需要获取消息的窗口的句柄,该窗口必须属于当前线程。当其值是 NULL 时,将获取所有的当前线程的窗口消息和线程消息,当其值是 -1 时,只获取当前线程消息

wMsgFilterMin    指定被可以被获取的消息值的最小整数(消息其实就是一个被定义的整数)
wMsgFilterMax    指定被可以被获取的消息值的最小整数
wRemoveMsg

一是指定消息如何被处理(该值可以是下边一个或多个组合):
值    含义
PM_NOREMOVE    消息被获取后不从消息队列中删除
PM_REMOVE    消息被获取后并从消息队列中删除
PM_NOYIELD    1. 防止系统释放任何正在等待被调用的线程   2. 跟 PM_NOREMOVE 或 PM_REMOVE 相结合使用

二是默认设置下处理所有类型的消息,若要求只处理某些消息,则指定下列一个或多个组合:
值    含义
PM_QS_INPUT    处理鼠标和键盘消息
PM_QS_PAINT    处理绘图消息
PM_QS_POSTMESSAGE    处理所有 posted 的消息,包括计时器和快捷键消息
PM_QS_SENDMESSAGE    处理所有 send 的消息

如果PeekMessage获取到信息则返回值非零,获取不到则为零

while(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
            {         
            if(msg.message==STOP_THREAD)
            {
               
                return 0;
            }
            else{
                DispatchMessage(&msg);//分发消息
            }
            }//不断地检测消息队列是否有消息

通过这个发消息,收消息的过程即可结束进程

关于MFC实时的视频处理的更多相关文章

  1. 实时音视频互动系列(上):又拍云UTUN网络详解

    如何定义实时音视频互动, 延迟 400ms 内才能无异步感 实时音视频互动如果存在1秒左右的延时会给交流者带来异步感,必须将视频播放延迟限制在400ms以内,才能给用户较好的交互体验. 当延迟控制在4 ...

  2. 实时音视频互动系列(下):基于 WebRTC 技术的实战解析

    在 WebRTC 项目中,又拍云团队做到了覆盖系统全局,保证项目进程流畅.这牵涉到主要三大块技术点: 网络端.服务端的开发和传输算法 WebRTC 协议中牵扯到服务端的应用协议和信令服务 客户端iOS ...

  3. 融云携新版实时音视频亮相 LiveVideoStack 2019

    4 月 19 日,LiveVideoStack 2019 音视频大会在上海隆重开幕,全球多媒体创新专家.音视频技术工程师.产品负责人.高端行业用户等共襄盛会,聚焦音频.视频.图像.AI 等技术的最新探 ...

  4. 了不起的WebRTC:生态日趋完善,或将实时音视频技术白菜化

    本文原文由声网WebRTC技术专家毛玉杰分享. 1.前言 有人说 2017 年是 WebRTC 的转折之年,2018 年将是 WebRTC 的爆发之年,这并非没有根据.就在去年(2017年),WebR ...

  5. 小程序升级实时音视频录制及播放能力,开放 Wi-Fi、NFC(HCE) 等硬件连接功能

    “ 小程序升级实时音视频录制及播放能力,开放 Wi-Fi.NFC(HCE) 等硬件连接功能.同时提供按需加载.自定义组件和更多访问层级等新特性,增强了第三方平台的能力,以满足日趋丰富的业务需求.” 0 ...

  6. 利用PyQt GUI显示图片、实时播放视频

    ---作者吴疆,未经允许,严禁转载,违权必究--- ---欢迎指正,需要源码和文件可站内私信联系--- -----------点击此处链接至博客园原文----------- 功能说明:PyQt界面程序 ...

  7. 从零到一,使用实时音视频 SDK 一起开发一款 Zoom 吧

    zoom(zoom.us) 是一款受到广泛使用的在线会议软件.相信各位一定在办公.会议.聊天等各种场景下体验或者使用过,作为一款成熟的商业软件,zoom 提供了稳定的实时音视频通话质量,以及白板.聊天 ...

  8. 用Red5搭建支持WEB播放的实时监控视频

    用Red5搭建支持WEB播放的实时监控视频 1. 下载Red5:https://github.com/Red5/red5-server/releases 下载了Red5 1.0.6 release的Z ...

  9. 云-腾讯云-实时音视频:实时音视频(TRTC)

    ylbtech-云-腾讯云-实时音视频:实时音视频(TRTC) 支持跨终端.全平台之间互通,从零开始快速搭建实时音视频通信平台 1.返回顶部 1. 腾讯实时音视频(Tencent Real-Time ...

随机推荐

  1. [leetcode-623-Add One Row to Tree]

    Given the root of a binary tree, then value v and depth d, you need to add a row of nodes with value ...

  2. Example007关闭窗口时关闭父窗口

    <!--实例007关闭窗口时刷新父窗口--> <!DOCTYPE html> <html lang="en"> <head> < ...

  3. gulp 入门指南

    gulp 是基于 node 实现 Web 前端自动化开发的工具,利用它能够极大的提高开发效率. 在 Web 前端开发工作中有很多"重复工作",比如压缩CSS/JS文件.而这些工作都 ...

  4. var与let的区别

    var与let的区别 前言: 在没接触Es6之前,我们在js中声明都是通过var来声明变量的,var声明变量虽说方便,但是,又有一些自己的诟病,下边来说一说,这三个的区别! var var相信大家都不 ...

  5. Unity3D中使用BMFont制作图片字体 (NGUI版)

    [旧博客转移 - 发布于2015年9月10日 16:07] 有时美术会出这种图片格式的文字,NGUI提供了UIFont来支持BMFont导出的图片字体 BMFont原理其实很简单,首先会把文字小图拼成 ...

  6. 算法设计与分析 上机题Mergesort

    #include <iostream>using namespace std; #define N 100 int g_array[N];     //存放输入的数字static int ...

  7. Postgresql_fqw

    Postgresql_fqw 测试环境 Ubuntu 16.04 LTS云主机2台,主机名为pg1(192.168.0.34)和pg2(192.168.0.39). 安装postgresql 下面这个 ...

  8. DotNetCore跨平台~EFCore连接Mysql的方式

    回到目录 在.net frameworks的ef里连接mysql我们已经测试通过了,而在dotnet core里的efCore上去连接mysql我们需要测试一下,并且在测试过程中出现了一些问题,当然最 ...

  9. 如何查看安装的sql server是什么版本

    方法 1:通过使用 SQL Server Management Studio 中的对象资源管理器连接到服务器.连接对象资源管理器后,它将显示版本信息(在括号中),以及用于连接到 SQL Server ...

  10. js获取鼠标点击的对象,点击另一个按钮删除该对象

    作为js的一名新手,对于所谓的event的了解并不是太多,仅仅根据视频教学中的例子模仿着,写了诸如: function funcname(e) { e=window.event||event };的函 ...