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

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

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

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

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

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

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

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

  1. 计算指针输入位移的矢量,用v表示。
  2. 计算相应的单位长度向量,用u表示。
  3. 屏幕上的指针位移是v’ = f(| v |)* u

我选择f(x)的forms像beta * e ^( alpha * x – 1),其中0 < alpha和0 < beta <= 1是应根据经验选择的参数。

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

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