解决DShow采集USB摄像头数据时画面倒置问题

本文记录了使用虚拟摄像头VCAM时遇到的画面颠倒问题及其解决方案。通过调整BITMAPINFOHEADER中的biHeight字段为负值,解决了因原始位图文件扫描方式导致的画面颠倒现象。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本人用的两个摄像头测试的:

1.奥速的摄像头,型号ashu f11p,数据输出格式为YUV2,画面显示无问题;

2.本机安装虚拟摄像头:VCAM,数据输出格式为RGB24,画面显示颠倒;

一开始以为是数据输出格式不一致导致的,看其处理过程,查找了一天也没找到问题所在,流程处理无问题。

然后开始上网查找解决方法,在网上找到一条相关信息:

确认BITMAPINFOHEADER中的biHeight字段,

biHeight为正,位图自底向顶扫描,biHeight为负,位图自顶向底扫描。

如果这个值的设置和原始位图文件扫描方式不符,则图像显示可能会颠倒。

链接:https://bbs.youkuaiyun.com/topics/350081398

之前biHeight设置为正,我将biHeight设置为负,画面显示正确。

 

但是遗留一个问题:原始位图文件扫描方式(即biHeight为正还是负)未找到。

更新:按bmp文件头信息中分析得知:位图信息头中biHeight字段有两个含义,

1.指示位图的高度;2.指明该图像是一个倒向的位图(正数)还是一个正向的位图(负数);

大多数bmp文件是一个倒向的位图,高度值取正。

参考链接:https://www.cnblogs.com/wainiwann/p/7086844.html

 

//指定视频采集设备的友好名字,为它创建一个Filter IBaseFilter * CTestPreviewDlg::CreateVideoDevice(const char * inFriendlyName) { return CreateHardwareFilter(CLSID_VideoInputDeviceCategory,inFriendlyName); } //根据设备的友好名字,创建一个代表该设备的Filter IBaseFilter * CTestPreviewDlg::CreateHardwareFilter(GUID inCategory,const char * inFriendlyName) { //创建一个系统枚举组件对象 ICreateDevEnum * enumHardware = NULL; HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum,NULL,CLSCTX_ALL, IID_ICreateDevEnum,(void**)&enumHardware); if(FAILED(hr)) { return NULL; } IBaseFilter * hardwareFilter = NULL; IEnumMoniker * enumMoniker = NULL; //为指定的目录创建枚举器 hr = enumHardware->CreateClassEnumerator(inCategory,&enumMoniker,0); if(enumMoniker) { enumMoniker->Reset(); ULONG fetched = 0; IMoniker * moniker = NULL; char friendlyName[256]; //枚举得到该目录下所有的设备,逐个进行名字匹配 while(!hardwareFilter && SUCCEEDED(enumMoniker->Next(1,&moniker, &fetched)) && fetched) { if(moniker) { IPropertyBag * propertyBag = NULL; VARIANT name; friendlyName[0] = 0; hr = moniker->BindToStorage(0,0,IID_IPropertyBag,(void**)&propertyBag); //读取设备的友好名字 if(SUCCEEDED(hr)) { name.vt = VT_BSTR; hr = propertyBag->Read(L"Friendlyname",&name,NULL); } if(SUCCEEDED(hr)) { WideCharToMultiByte(CP_ACP,0,name.bstrVal,-1, friendlyName,256,NULL,NULL); //如果当前设备的友好名字与用户指定的设备名字相同, //则将当前设备标识绑定为Filter形式 if(strcmp(friendlyName,inFriendlyName) == 0) { moniker->BindToObject(0,0,IID_IBaseFilter, (void**)&hardwareFilter); } } //释放使用过的接口 if(propertyBag) { propertyBag->Release(); propertyBag = NULL; } moniker->Release(); } } enumMoniker->Release(); } enumHardware->Release(); return hardwareFilter; }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值