問題描述
我使用 EmguCV(openCV 的包裝器)在 C# 中編寫了一個程序.該程序使用 camshift 算法跟蹤對象.圍繞對象繪制一個矩形.光標移動到矩形的中心.輸入來自網絡攝像頭.
I have written a program in C# using EmguCV (wrapper of openCV). The program tracks an object using camshift algorithm. A rectangle is drawn around the object. The cursor is moved by center of the rectangle. Input is taken from a webcam.
最初的問題是光標無法覆蓋整個屏幕.它的運動僅限于框架尺寸.所以我應用了一個乘法因子:
Initially the problem was that the cursor couldn't cover the entire screen. Its movement was limited to frame size. And so i applied a multiplication factor:
X 方向移動的屏幕寬度/幀寬度.
screenwidth/framewidth for movement in X direction.
Y 方向移動的屏幕高度/幀高度
screenheight/frameheight for movement in Y direction
這樣鼠標就可以覆蓋整個區域.但是鼠標移動不再流暢了.我無法指出靠近的兩個圖標.如何在覆蓋整個屏幕時使鼠標移動平滑,就像使用真正的鼠標一樣?
With this the mouse covers entire area. But the mouse movement is not smooth any more. I am unable to point to two icons closely situated. How can I make mouse movement smooth while covering the entire screen, just as it happens with a real mouse?
推薦答案
指出明顯的一點: 你的鼠標實現的不流暢是因為 camshift 給出的矩形只是精確到一幀像素的精度,因此可能的最小移動將屏幕大小/幀大小四舍五入到最近的屏幕像素.
To point out the obvious: the non-smoothness of your mouse implementation comes from the fact that the rectangle given by camshift is only accurate to the accuracy of one frame pixel, so the smallest movement possible will be screensize/framesize rounded to the nearest screen pixel.
如果是這種情況,可以應用某種指針加速,就像使用真實的低質量鼠標時那樣(當然,如果有數千個 dpi 激光鼠標,則無需這樣的事情).基本上,光標在屏幕上移動的距離不是指針輸入所走的距離(在本例中為 camshift 矩形位移),而是它的一個巧妙選擇的函數.因此,使用加速度函數 f(x),移動指針的步驟如下:
If that is the case, some kind of pointer acceleration could be applied, just like it is done when real, low-quality mice are used (of course, in case of multiple thousand dpi laser mice, there is no need for such thing). Basically, the distance the cursor moves on screen is not the distance taken by the pointer input (in this case, camshift rectangle displacement), but a cleverly chosen function of it. So, using an acceleration function f(x), the steps of moving the pointer will be like this:
- 計算指針輸入位移向量,記為v.
- 計算對應的單位長度向量,記為u.
- 屏幕指針位移為v'=f(|v|) * u
- Calculate vector of pointer input displacement, let that be denoted by v.
- Calculate the corresponding unit-length vector, let that be denoted by u.
- The on-screen pointer displacement is v'=f(|v|) * u
我會以 beta * e^(alpha * x - 1) 之類的形式選擇 f(x),其中 0 <alpha 和 0 <beta <= 1 是應該根據經驗選擇的參數.
I'd chose f(x) in a form like beta * e^(alpha * x - 1), where 0 < alpha and 0 < beta <= 1 are parameters which should be empirically chosen.
基本上,任何在 0 處導數為 1 或更少的函數都會執行此操作(允許您使用輸入的完全準確度來進行精確的光標移動),隨著 x 的增加變為無窮大(大的移動應該對應于大光標的移動),是單調遞增的,并且具有單調遞增的一階導數.還需要加速函數在0時的值為0,否則會出現很奇怪的動作.:)
Basically, any function will do it that has a derivate of 1 or less at 0 (allows you to use the full accuracy of the input for precise cursor movements), goes to infinity as x increases (large movements should correspond to large movements of the cursor), is monotonically increasing and has a monotonically increasing first derivate. It is also needed that the acceleration function has a value of 0 at 0, otherwise very strange movements will happen. :)
還需要 f(framewidth) = screenwidth,這樣在框架上移動被跟蹤對象會導致光標在屏幕上移動.指數公式很容易使用,但使用二次或更高次多項式可能會在計算上更簡單,具體取決于那里的性能要求......
It is also desirable to have f(framewidth) = screenwidth so that moving the tracked object across the frame results in the cursor being moved across the screen. An exponential formula is quite pleasing to work with, but using a quadratic or higher degree polynomial may turn out to be computationally simpler, depending on what performance requirements are there...
這篇關于通過 OpenCV 的 camshift 算法控制鼠標指針(或鼠標的基本功能)的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!