Управление указателем мыши с помощью алгоритма кулачкового сдвига OpenCV (или как в основном функционирует мышь)
Я написал программу на C# с использованием EmguCV (обертка openCV). Программа отслеживает объект, используя алгоритм смещения. Прямоугольник нарисован вокруг объекта. Курсор перемещается по центру прямоугольника. Ввод взят с веб-камеры.
Первоначально проблема заключалась в том, что курсор не мог охватить весь экран. Его движение было ограничено размером кадра. И поэтому я применил коэффициент умножения:
ширина экрана / ширина кадра для движения в направлении X.
высота экрана / высота кадра для движения в направлении Y
При этом мышь охватывает всю область. Но движение мыши больше не плавное. Я не могу указать на две иконы, расположенные близко. Как я могу сделать движение мыши плавным, покрывая весь экран, как это происходит с настоящей мышью?
1 ответ
Чтобы указать на очевидное: негладкость реализации вашей мыши происходит из того факта, что прямоугольник, заданный camshift, является точным только с точностью до одного пикселя кадра, поэтому наименьшее возможное движение будет иметь размер экрана / размер кадра, округленный до ближайшего экрана. пиксели.
Если это так, можно применить какое-то ускорение указателя, точно так же, как это происходит, когда используются настоящие, некачественные мыши (конечно, в случае лазерных мышей с несколькими тысячами точек на дюйм, в этом нет необходимости), По сути, расстояние, на которое курсор перемещается по экрану, - это не расстояние, на которое берется указатель (в данном случае это смещение прямоугольника смещения), а его искусно выбранная функция. Итак, используя функцию ускорения f(x), шаги перемещения указателя будут такими:
- Вычислить вектор смещения входного указателя, пусть это будет обозначено как v.
- Вычислим соответствующий вектор единичной длины, пусть это будет обозначаться через u.
- Смещение указателя на экране: v ' = f (| v |) * u
Я бы выбрал f (x) в форме, подобной бета * e^(альфа * x - 1), где 0 < альфа и 0 < бета <= 1 - параметры, которые следует выбирать опытным путем.
По сути, любая функция, которая делает это с производной от 1 или меньше при 0 (позволяет использовать полную точность ввода для точных перемещений курсора), уходит в бесконечность при увеличении x (большие движения должны соответствовать большим движениям курсор), монотонно увеличивается и имеет монотонно возрастающую первую производную. Редактировать: также необходимо, чтобы функция ускорения имела значение 0 при 0, иначе произойдут очень странные движения.:)
Также желательно иметь f (framewidth) = screenwidth, чтобы перемещение отслеживаемого объекта по кадру приводило к перемещению курсора по экрану. Экспоненциальная формула довольно приятна для работы, но использование квадратичного или полинома более высокой степени может оказаться вычислительно проще, в зависимости от требований к производительности...