Juvenile的文章

  • 摄像头图像采集及拼接程序的实现

    程序的说明实现从摄像头实时采集单帧图像,之后完成图像的拼接,本程序实现了两张图片的拼接和三张图片的拼接。
    在此之前你需要在 linux 下安装 opencv Package 这个包,因为本程序主要使用 opencv 这个包中提供的 api 函数。
    实现从摄像头实时不同视角采集视频的单帧图像并保存实时采集的视频文件之后,完成图像的拼接,由于实验室设备有限,手头只有两个摄像头一次只能抓取。
    两张不同视角的单帧图像,我们抓取的单帧图像保存在当前项目目录下的 frame1 和 frame2 文件夹中,因此我同时制作了两个完成程序。
    拼接的程序,一个实现完成两个不同视角的图像拼接,另一个实现三张不同视角的单帧图像的拼接。其中的 testusb.cpp 文件是测试摄像头的程序。在执行本程序前,你应该保证有两个是摄像头插在主机端口上,用于实时采集单帧图像。
    代码介绍在进行程序的编译前,请确定你已经安装了 opencv2.4.9 和 pkg-config 包,本程序是在 ubuntu14.04 平台下实现的,在本项目目录下,已经有编译生成的可执行程序,其中 Camera_to_Frmae.cpp 是我们从双摄像头实时抓取单帧图像的源码。

    ImageJoint.cpp 和 ImageJoint2.cpp、ImageJoint3.cpp 分别是完成两张不同视角的图像拼接和三张不同视角的图像拼接程序,其中三张图像拼接的图像是我从网上找的现成的图像库
    testusb.cpp 是我测试摄像头的程序

    程序编译g++ -o dst src.cpp \`pkg-config opencv --cflags --libs\`
    程序的执行和退出
    ./dst
    程序需要退出时,按 Ctrl + C 快捷键

    效果从摄像头设备采集两张单帧图像


    图像拼接效果图
    2  留言 2019-05-11 16:33:28
  • 基于DirectShow实现的视频捕捉与采集程序

    前言DirectShow是微软公司提供的一套在Windows平台上进行流媒体处理的开发包,与DirectX开发包一起发布。DirectShow为多媒体流的捕捉和回放提供了强有力的支持。用DirectShow开发应用程序,我们可以很方便地从支持WDM驱动模型的采集卡上捕获数据,并且进行相应的后期处理乃至存储到文件中。
    DirectShow是基于COM的,为了编写DirectShow应用程序,需要了解COM客户程序编写的基础知识。DirectShow提供了大量的接口,但在编程中发现还是不够方便,如果能构建一个视频捕捉类把常用的一些动作封装起来,那么就更方便了。
    编程思路为了更加容易建立视频捕捉应用程序,DirectShow提供了一个叫做Capture Graph Builder的对象,Capture Graph Builder提供IcaptureGraphBuilder2接口,该接口可以建立和控制Capture Graph。
    建立视频捕捉程序,必须首先获取并初始化IcaptureGraphBuilder2接口,然后选择一个适当的视频捕捉设备。选择好设备后,为该设备创建Capturefilter,然后调用AddFilter把Capture filter添加到Filter Graph。如果仅仅希望用摄像头来进行实时监控的话,只需要在上面的基础上调用ICaptureGraphBuilder2::RenderStream就可以了
    本程序在VS2010 PlatForm采用Micosoft 的DriectXShow9.0b SDK编写的一套实时视频捕捉,采集功能,并且还提供了视频和单帧图像参数设置界面,采集的视频流和单帧图像都写在文件中,之后使用OpenCV进行音视频的处理,当然这是我后期要做的事情,前面部分已经完成,前半部分开发使用了因为很多东西要查,需要学习DXShow如何设计filter graph manger 和filter graph 的创建以及pin 的连接,最后renderstream,产生视频流,之后,在视频流上捕捉单帧图像数据,加入图像头,写入文件进行保存到文件系统.
    环境配置
    首先保证已经正确安装了MicroSoft的DXSDK,请一定安装DriectXShow9.0b版本的SDK包,这里我将其安装了在C盘根目录下
    打开VS2010项目,在项目属性中设置项目需要使用的项目需要包含的包含目录和库目录
    具体步骤:

    项目-项目名属性-配置属性-VC++目录-包含目录-“C:\DXSDK\Include”项目-项目名属性-配置属性-VC++目录-包含目录-“C:\DXSDK\Lib”

    软件效果全局效果

    视频格式设置

    图像格式设置
    1  留言 2019-05-09 16:13:33
  • 修改注册表实现添加鼠标右键菜单选项

    背景我们安装一些应用程序的时候,经常都会看到程序安装完后,会创建鼠标右键菜单项,方便使用程序。创建系统右键菜单项,通常都会使用扩展Shell接口来实现,会涉及到COM的相关知识,碎语初学者来说比较难理解。
    现在,本文介绍一种简单的方法实现相同的功能。就是,修改注册表来实现。现在,把功能实现的原理以及过程,写成文档形式,分享给大家。
    函数介绍RegCreateKeyEx 函数
    该函数用来创建注册表键,如果该键已经存在,则打开它(注册表键不区分大小写)。
    函数声明
    LONG RegCreateKeyEx( HKEY hKey, LPCTSTR lpSubKey, DWORD Reserved, LPTSTR lpClass, DWORD dwOptions, REGSAM samDesired, LPSECURITY_ATTRIBUTES lpSecurityAttributes, PHKEY phkResult, LPDWORD lpdwDisposition);
    参数

    hKey[输入] 一个打开键的句柄。调用该函数的进程必须拥有KEY_CREATE_SUB_KEY的权力。该句柄可以是RegCreateKeyEx或者RegOpenKeyEx的返回值,也可以是以下预定义的值:​ HKEY_CLASSES_ROOT​ HKEY_CURRENT_USER​ HKEY_LOCAL_MACHINE​ HKEY_USERS​ HKEY_CURRENT_CONFIG
    lpSubKey[输入] 标识子键名称。该参数不能为空。参数中不能存在(\)。
    Reserved保留,必须设置为 0。
    lpClass[输入] 指向一个字符串,该字符串定义了该键的类型。可以为NULL。该参数可以在操作本地和远程注册表时使用。
    dwOptions
    [输入] 该参数可以是以下值:​ REG_OPTION_BACKUP_RESTORE,0x00000004L​ REG_OPTION_NON_VOLATILE,0x00000000L ,一般用该值​ REG_OPTION_VOLATILE,0x00000001L

    samDesired [输入] 对指定键希望得到的访问权限的访问标记。 这个参数可以使下列值的联合。



    VALUE
    MEANING




    KEY_CREATE_LINK
    准许生成符号键


    KEY_CREATE_SUB_KEY
    准许生成子键


    KEY_ENUMERATE_SUB_KEYS
    准许生成枚举子键


    KEY_EXECUTE
    准许进行读操作


    KEY_NOTIFY
    准许更换通告


    KEY_QUERY_VALUE
    准许查询子键


    KEY_ALL_ACCESS
    提供完全访问,是上面数值的组合:KEY_QUERY_VALUE, KEY_ENUMERATE_SUB_KEYS, KEY_NOTIFY, KEY_CREATE_SUB_KEY, KEY_CREATE_LINK, KEY_SET_VALUE


    KEY_READ
    是KEY_QUERY_VALUE、KEY_ENUMERATE_SUB_KEYS、KEY_NOTIFY的组合


    KEY_SET_VALUE
    准许设置子键的数值


    KEY_WRITE
    是KEY_SET_VALUE、KEY_CREATE_SUB_KEY的组合




    lpSecurityAttributes[输入]定义返回的句柄是否可以被子进程继承,为NULL时不能继承。
    phkResult
    [输出]指向一个变量的指针,该变量用来保存打开注册表键的句柄。如果不再使用返回的句柄,则调用RegCloseKey来关闭它。
    lpdwDisposition[输出]可以是以下值。如果为空,则不返回。​ REG_CREATED_NEW_KEY,0x00000001L 该键是新创建的键​ REG_OPENED_EXISTING_KEY,0x00000002L 该键是已经存在的键

    备注

    不该函数创建的键没有键值。应用程序不能创建HKEY_USERS 或者 HKEY_LOCAL_MACHINE的直接子键。
    返回值

    返回值 如果函数调用成功,则返回0(ERROR_SUCCESS)。否则,返回值为文件WINERROR.h中定义的一个非零的错误代码。

    RegSetValueEx 函数
    有名称值的数据和类型时设置指定值的数据和类型。
    函数声明
    LONG RegSetValueEx( HKEY hKey, LPCTSTR lpValueName, DWORD Reserved, DWORD dwType, CONST BYTE *lpData, DWORD cbData);
    参数

    hKey
    一个已打开项的句柄,或指定一个标准项名
    lpValueName
    指向一个字符串的指针,该字符串包含了欲设置值的名称。若拥有该值名称的值并不存在于指定的注册表项中,则此函数将其加入到该项。如果此值是NULL,或指向空字符串,则此函数为该项的默认值或未命名值设置类型和数据。
    Reserved
    保留值,必须强制为0。
    dwType
    指定将被存储的数据类型,该参数可以为:




    VALUE
    MeANING




    REG_BINARY
    任何形式的二进制数据


    REG_DWORD
    一个32位的数字


    REG_DWORD_LITTLE_ENDIAN
    一个“低字节在前”格式的32位数字


    REG_DWORD_BIG_ENDIAN
    一个“高字节在前”格式的32位数字


    REG_EXPAND_SZ
    一个以0结尾的字符串,该字符串包含对环境变量(如“%PAHT”)的


    REG_LINK
    一个Unicode格式的带符号链接


    REG_MULTI_SZ
    一个以0结尾的字符串数组,该数组以连接两个0为终止符


    REG_NONE
    未定义值类型


    REG_RESOURCE_LIST
    一个设备驱动器资源列表


    REG_SZ
    一个以0结尾的字符串




    lpData
    指向一个缓冲区,该缓冲区包含了欲为指定值名称存储的数据。
    cbData
    指定由lpData参数所指向的数据的大小,单位是字节。

    返回值

    返回0(ERROR_SUCCESS)表示成功;返回其他任何值都代表一个错误代码。

    RegCloseKey 函数
    函数功能是释放指定注册键的句柄。
    函数声明
    LONG RegCloseKey( HKEY hKey // 释放键的句柄);
    参数

    hKey
    [输入] 想要关闭的已经打开的键。

    返回值

    如果过程执行成功,返回值是 ERROR_SUCCESS。如果功能失败,返回一个非零值,错误码在 Winerror.h 定义。

    实现原理Windows提供了一个相关的注册表键,只要添加相应的键值,就可以在鼠标右键菜单中显示。这个注册表键就是:
    HKEY_CLASSES_ROOT\*\shell那么,右键菜单创建的流程就是:

    首先,我们可以在这个注册表键中,创建一个任意名称的子键,这个子键就对应右键菜单项的名称
    然后,设置子键的键值“Icon”的数据,把右键菜单项对应的图标文件写入到键值“Icon”中
    最后,在子键下面继续新建一个子键“command”,而且将右键菜单项关联的程序路径写入到“command”子键默认值中去

    这样,便实现了创建鼠标右键菜单项。要想获取鼠标右键选中的文件路径,只需将关联程序路径默认添加 “%1” ,然后写入在上述“command”子键的键值中去即可。其中%1代表右键选中的文件,这样当点击菜单后就可以执行你指定的程序(”520.exe”)并传入选中的文件名作为命令参数,这样就可以处理这个文件了。
    编码实现创建注册表键并设置键值BOOL SetRegValue(HKEY hMainKey, char *lpszSubKey, char *lpszKeyValueName, char *lpszKeyValue){ HKEY hKey; // 打开或创建注册表键 if (ERROR_SUCCESS != ::RegCreateKeyEx(hMainKey, lpszSubKey, 0, NULL, 0, KEY_WRITE, NULL, &hKey, NULL)) { ShowError("RegCreateKeyEx"); return FALSE; } // 修改注册表值,实现开机自启 if (ERROR_SUCCESS != ::RegSetValueEx(hKey, lpszKeyValueName, 0, REG_SZ, (BYTE *)lpszKeyValue, (1 + ::lstrlen(lpszKeyValue)))) { ::RegCloseKey(hKey); ShowError("RegSetValueEx"); return FALSE; } // 关闭注册表键 ::RegCloseKey(hKey); return TRUE;}
    修改注册表添加鼠标右键菜单项BOOL AddRightMouseMenu(char *lpszIconFilePath, char *lpszExeFilePath){ BOOL bRet = FALSE; // 创建键 并 设置键值 (Icon) bRet = SetRegValue(HKEY_CLASSES_ROOT, "*\\shell\\AddRightMouseMenuTest", "Icon", lpszIconFilePath); if (FALSE == bRet) { return FALSE; } // 创建键 并 设置键值 (Path) bRet = SetRegValue(HKEY_CLASSES_ROOT, "*\\shell\\AddRightMouseMenuTest\\command", "", lpszExeFilePath); if (FALSE == bRet) { return FALSE; } return TRUE;}
    程序测试在 main 函数中调用上述封装好的接口,进行测试。
    main 函数为:
    int _tmain(int argc, _TCHAR* argv[]){ // 其中%1代表右键选中的文件。 // 这样当点击菜单后就可以执行你指定的程序("520.exe")并传入选中的文件名作为命令参数,这样就可以处理这个文件了 if (FALSE == AddRightMouseMenu("C:\\Users\\Desktop\\520.ico", "C:\\Users\\Desktop\\520.exe %1")) { printf("Add Right Mouse Menu Error!\n"); } printf("Add Right Mouse Menu OK!\n"); system("pause"); return 0;}
    测试结果“以管理员身份运行程序”打开程序,提示执行成功。

    打开注册表进行查看,注册表键成功创建,注册表键值也正确。


    我们随便选中一个文件,鼠标右击,可以成功看到有刚刚我们程序添加的菜单项,点击后,变启动我们关联的程序。

    所以,测试成功。
    总结要注意的是,我们是修改 HKEY_CLASSES_ROOT 中的注册表键,所以,程序必须要有管理员权限才可以正常执行操作。这点需要注意,否则,程序会报错。
    其次,点击右键菜单项时,想要获取选中文件路径并传递给关联程序,只需要在关联程序路径后加上“%1”,然后写入“command”子键的键值中即可。这样,系统会把选中的文件路径传递给关联程序。
    参考参考自《Windows黑客编程技术详解》一书
    2  留言 2018-11-16 17:12:40

发送私信

我依旧深信时间是良药虽苦口,但有效

13
文章数
18
评论数
eject