虚拟相机的设计-原理、设计、方案

在之前的辅助方案中,提到过我们需要设计一款相机,使用"相机"是因为我们在整个方案中,把“获取游戏截图”这个动作和工业相机中的图像采集等同起来,我们总能在任意时刻获取到一张游戏截图,故为了更好和下一环节衔接,就使用相机接口的设计方式。

这种将功能/结果相似开发任务等同起来,并使用已有的标准进行对接的方式非常普遍,例如工业上的将串口/网口/USB接口都等同起来,然后认为指定基于这些接口的Modbus协议,就是一个案例,这种协议并不关注底层是如何实现数据传输的,它仅规定传输的格式和收发的解析方法。和这个类似,我们将“获取游戏截图”这个功能封装成一个相机,更多的是为了和后续的opencv接口对接上,这么做带来了额外的工作量,但是还是值得的。

这个系列会比较难写,因为要同时获取windows、Android、IOS系统会很麻烦,其中IOS系统我自己还在研究,所以根据实际情况,如果真的发现IOS很难或者很费力,我就取掉了这部分。

可能得文章如下:

windows平台虚拟相机开发

Android平台虚拟相机开发

IOS平台虚拟相机开发

接口的定义

和鼠标有很多方案不同,这个虚拟相机的功能非常单一,就是获取图像,所以我期望的接口设计如下:

// 图像的传输模式,要么是灰度图像。要么是rgb模式
eunm ImageType
{
    _rgb,
    _grey
};

// 相机对外提供的采集模式,full是全图传输模式、woi是n个区域进行传输的精简模式式
enum CamMode
{
    _full,
    _woi
};

// 相机类型,有网络相机和USB相机两种
enmu CamType
{
    _gige,
    _usb
};

// 相机对应的参数
char **g_pParam = 
{
"version",
"name",
"width",
"height",
"img_type",
"cam_type",
"cam_mode"
};

// 图像结构
struct _tagImageInfo
{
    USHORT width;
    USHORT height;
    
    USHORT bits;
    USHORT type
    
    void  *pData;
    int    size;
}

// 打开相机并设定参数
handle open_cam(CamType, CamMode, ImageType);

// 改变参数设定
int set_cam_param(handle dev, char *pType, void *pData);

// 获取参数设定
int get_cam_param(handle dev, char *pType, void *pData);

// 获取一帧图像
int get_image(handle dev,void *pData);

// 关闭相机
void close_cam(handle dev);
需要注意的问题

1. 带宽问题: 我们要考虑最多255/128台设备会在同一时间传输数据,所以我们要谨慎的选择接口:

如果我们使用分辨率是1920*1080的图像数据,在RGB的情况下,数据量是6MB,这种情况下对于百兆网就是每秒1帧,这个速度是无法接受的。

如果使用YUV的422模式,会提高到2帧,虽然提高了100%,但是还是差太多了;

使用PNG格式的问题在于,它的压缩率不是固定的,这里我经过大量的实践,发现它接近RGB的4%~40%,这已经是在无损压缩下最好的方案了。

最可能的是使用H.264的方案,这样数据量大约是2%,那么我们确实可以实现100这个数量级的设备和主机通讯。

2. 主机的处理速度:

我们不可能使用价格太高的主机来处理如此巨大的数据,前面的带宽是一个因素,还有另外一个因素就是图像算法处理需要的时间。

在我的实际使用中,利用显卡去计算常规的图像算法是一种浪费,最合适的方案就是开启足够的线程,并在调度的基础上实现性能最为平衡的点。

在Intel的8核16线程的CPU上,可以处理16个设备的数据,这种时候鼠标方案中使用开发板的优势就出来,1GHz主频的arm开发板运行常规算法的时间大概是Intel的一倍,价格却是1/10,我们可以将大部分数据丢给开发板,让它去计算。

开发是一件相互妥协的系统工程方案,所有对系统的了解和搭配更加熟悉的人会更有优势,很多人看过22种设计模式,但是很少有人真的去分析和总结这些设计模式背后的实现思想,这就带来了在设计上巨大的差距。

开发板另外一个优势是提供了丰富的接口,几乎所有的开发板都支持串口/USB/Wifi/网口,这些接口的好处是可以将数据流均匀的荷载到设备上,我们可以在开发板上将网络接口和USB口的数据量达到理论带宽的80%,CPU的占用率达到80%。

注意: 这种情况下,我们需要看开发板内部总线的情况,譬如,树莓派3B的网络和USB是同一条总线,这种情况下速度还是1/2,当然Auduino的开发板是不同总线,这个我们可以找开发板的提供方咨询,或者自行在开发板的wiki上查找资料,一般来说这些资料都是公开的。

具体的方案

和鼠标一样,我们会在接下来的文档中提供下面的一种或者几种方案:

1. 系统编程方面提供windows、Android、IOS系统的游戏截图方案;

2. 数据传输方案: 提供USB、gige、串口三种接口的传输方案;

3. 协议方面提供图像格式转换、图像数据发包和收包;

4. 最后我们会将鼠标方案和相机方案结合起来;

你可能感兴趣的:(虚拟相机的实现,游戏辅助,数码相机,游戏,计算机外设,c++)