通过OpenCV的camshift算法控制鼠标指针(或鼠标基本上如何工作)

时间:2011-03-13 18:39:08

标签: c# opencv computer-vision emgucv human-computer-interface

我使用EmguCV(openCV的包装器)在C#中编写了一个程序。程序使用camshift算法跟踪对象。在对象周围绘制一个矩形。光标移动到矩形的中心。输入来自网络摄像头。

最初的问题是光标无法覆盖整个屏幕。它的移动仅限于框架尺寸。所以我应用了一个乘法因子:

在X方向上移动的screenwidth / framewidth。

在Y方向上移动的屏幕高度/框架高度

用鼠标覆盖整个区域。但鼠标移动不再平滑。我无法指出两个紧密相连的图标。如何在覆盖整个屏幕时使鼠标移动平滑,就像真正的鼠标一样?

1 个答案:

答案 0 :(得分:5)

指出显而易见的:鼠标实现的非平滑性来自于camshift给出的矩形仅精确到一帧像素的精度,因此可能的最小移动将屏幕大小/帧大小四舍五入到最近的屏幕像素。

如果是这种情况,可以应用某种指针加速,就像使用真正的低质量鼠标时一样(当然,如果是数千dpi激光鼠标,则不需要这种事)。基本上,光标在屏幕上移动的距离不是指针输入所采用的距离(在这种情况下,是camshift矩形位移),而是一个巧妙选择的功能。因此,使用加速度函数f(x),移动指针的步骤如下:

  1. 计算指针输入位移的矢量,用 v 表示。
  2. 计算相应的单位长度向量,用 u 表示。
  3. 屏幕指针位移为 v' = f(| v |)* u
  4. 我选择f(x)的形式如 beta * e ^( alpha * x - 1),其中0 < alpha 和0&lt; beta &lt; = 1是应根据经验选择的参数。

    基本上,任何函数都会在0处导出1或更小的导数(允许您使用输入的完整精度来进行精确的光标移动),随着x的增加变为无穷大(大的移动应该对应于大的光标的移动,是单调增加的并且具有单调增加的第一导数。 编辑:还需要加速度函数在0处的值为0,否则会发生非常奇怪的运动。 :)

    还希望具有f( framewidth )= screenwidth ,以便在帧上移动被跟踪对象导致光标在屏幕上移动。指数公式非常令人满意,但使用二次或更高次多项式可能会在计算上变得更简单,具体取决于性能要求......