Как определить все отрезки линии из списка точек, созданных жестом мыши? - PullRequest
7 голосов
/ 07 июля 2010

В настоящее время я стажируюсь в софтверной компании, и одной из моих задач было внедрение распознавания жестов мыши.Один из старших разработчиков помог мне начать работу и предоставил код / ​​проекты, в которых используется Unistroke Recognizer за $ 1 http://depts.washington.edu/aimgroup/proj/dollar/. Я wide понимаю, что делает Unistroke Recognizer за 1 $ и как онработает, но я немного ошеломлен попыткой понять все внутренние / более тонкие детали этого.

Моя проблема в том, что я пытаюсь распознать жест перемещения мыши вниз, а затем вверх.Распознаватель Unistroke за 1 доллар определяет, что созданный мною жест был нисходящим жестом, что фактически является следствием того, что он должен делать.То, что я действительно хотел бы сделать, это сказать: «Я узнаю жест вниз, а затем жест вверх».

Я не знаю, вызывает ли полное отсутствие понимания Распознавателя Unistroke за 1 доллар, что я поцарапал свойголова, но есть ли у кого-нибудь идеи о том, как распознать два разных жеста от перемещения мыши вниз, а затем вверх?

Вот моя мысль, которая, как мне показалось, может помочь мне, но я бы полюбил кого-то, кто является экспертом илидаже знает немного больше, чем я, чтобы сообщить мне, что ты думаешь.Любая помощь или ресурсы, о которых вы знаете, будут высоко оценены.

Как работает мое приложение:

Способ работы моего текущего приложенияв том, что я фиксирую точки, где находится курсор мыши, пока пользователь удерживает левую кнопку мыши.Список точек затем передается в распознаватель жестов, и затем он выплевывает то, что он считает лучшей формой / жестом, который соответствует зафиксированным точкам.

Моя идея:

Что я хотел сделать, прежде чем передать точки распознавателю жестов, так это каким-то образом пройти все точки и разбить их на отдельныелинии или кривые.Таким образом, я мог кормить каждую линию / кривую по одной за раз, а из базовых движений вниз, вверх, влево, вправо, диагоналей и кривых я мог определить окончательную форму / жест.

Один из способов, который, как мне показалось, был бы полезен при определении наличия отдельных линий в моем списке точек, - это выборка групп точек и просмотр их наклона.Если наклон выбранной группы точек отличался на X% от некоторой другой группы выбранных точек, то можно с уверенностью предположить, что действительно есть отдельная линия.

Что я думаю возможные проблемы в моем мышлении:

  • Где я могу определить конец строки и начало отдельной строки?Если бы я использовал идею проверки наклона группы точек, а затем определил, что присутствует отдельная линия, это не значит, что я обязательно нашел наклон отдельной линии.Например, если бы вы нарисовали "L" с прямыми кромками и прямым углом и сэмплировали наклон точек вокруг угла "L", вы бы увидели, что наклон дал бы разумную индикацию того, что присутствует отдельная линия, ноэти точки не соответствуют началу отдельной линии.

  • Как бороться с постоянно меняющимся наклоном кривой линии?Распознаватель жестов, который я использую, обрабатывает кривые так, как я этого хочу.Но я не хочу, чтобы мой метод, который я использую для определения отдельных линий, продолжал искать эти так называемые отдельные линии на кривой, потому что ее наклон все время меняется, когда я выбираю группы точек.Могу ли я просто прекратить выборку точек, если наклон изменялся более чем на X% столько раз подряд?

  • Я не использую правильный "тип" математики для определения отдельных линий.Математика не мой самый сильный предмет, но я провёл небольшое исследование.Я пытался заглянуть в Dot Products и посмотреть, покажет ли это меня в каком-то направлении, но я не знаю, так ли это.Кто-нибудь использовал Dot Prodcuts для чего-то подобного или другого?

Заключительные мысли, замечания и благодарности:

Мне кажется, что часть моей проблемы в том, что я не знаю, как убедительно задать свой вопрос.Я не удивлюсь, если эта проблема уже была задана (так или иначе) и существует решение, которое можно найти в Google.Но мои результаты поиска в Google не дали никаких решений, так как я пока точно не знаю, как задать свой вопрос.Если вы чувствуете, что это сбивает с толку, пожалуйста, дайте мне знать, где и почему, и я помогу уточнить это.При этом, возможно, мои поиски в Google станут более точными, и я смогу найти решение.

Я просто хочу еще раз поблагодарить за чтение моего поста.Я знаю это долго, но не знал, где еще это спросить.Я общаюсь с другими людьми в офисе, но все мои лучшие решения, которые я использовал в школе, были из сообщества StackOverflow, поэтому я вам очень благодарен.

Изменения в этом сообщении:

(7/6 4:00 PM) Еще одна идея, о которой я подумал, это сравнение всех точек до точки Мин / Макс.Например, если я переместил мышь вниз, а затем вверх, моей начальной точкой будет текущая максимальная точка, а точкой, в которой я начну перемещать мышь назад вверх, будет моя минимальная точка.Затем я мог бы пойти дальше и посмотреть, есть ли какие-либо точки после минимальной точки, и если это так, сказать, что может быть новая потенциальная линия.Я не знаю, насколько хорошо это будет работать с другими фигурами, такими как звезды, но это еще одна вещь, которую я собираюсь рассмотреть.Кто-нибудь делал что-то подобное раньше?

Ответы [ 3 ]

1 голос
/ 07 июля 2010

если вы работаете с абсолютными углами, например, вверх и вниз, вы можете просто взять абсолютный наклон между двумя точками (не обязательно смежными), чтобы определить, ПРАВИЛЬНО, ВЛЕВО, ВВЕРХ, ВНИЗ (если этого достаточно для различия)

искусство состоит в том, чтобы найти расстояние между точками, чтобы угол не был случайным (при 1px угол будет кратен 45 °)

Существует плагин Firefox для навигации, использующий жесты мыши, который работает очень хорошо. Я думаю, что это FireGestures, но я не уверен. Я думаю, что вы можете получить вдохновение от этого

Дополнительная мысль: если вы рисуете форму, соединяя последовательные точки, а затем снова подключаетесь к первой точке, соотношение между областью и длиной конечного отрезка также является показателем "остроты" жеста

1 голос
/ 15 июля 2010

Если вас интересует только вверх / вниз / влево / вправо, первое приближение - проверить 45-градусные отрезки круга.Это легко сделать, сравнив горизонтальную разницу между (последовательными) точками с вертикальной разницей между точками.

Скажем, у вас больше положительная горизонтальная разница, чем вертикальная разница, тогда это будет 'ПРАВО'.

Единственная трудность возникает, например, в различении UP / DOWN от UP / RIGHT / DOWN.Но это может быть сделано путем расстояния между точками.Если вы определите, что мышь переместилась вправо менее чем на 20 пикселей, то вы можете проигнорировать это движение.

1 голос
/ 07 июля 2010

Если вашу проблему можно сузить, разбив общую кривую на прямые или плавно изогнутые частичные линии, тогда вы можете попробовать это.

Сравнение наклона сегментов и определение точек разрыва, когда оно превышает некоторый порог, сработало бы в очень упрощенном случае. Представьте себе идеально сформированную L-форму, где у вас прямой угол между двумя прямыми линиями. Очевидно, что угловая точка будет единственной, где разница наклона выше порога, если порог находится между 0 и 90 градусами, и, таким образом, является идентифицируемой точкой разрыва.

Однако вертикальные и горизонтальные линии могут быть слегка изогнуты, поэтому пороговое значение должно быть достаточно большим, чтобы эти небольшие различия в уклоне игнорировались как точки разрыва. Вы также должны решить, насколько острым будет угол, который алгоритм должен воспринимать как разрыв. 90 градусов или выше, или даже 30 градусов? Это важный вопрос.

Наконец, чтобы сделать это устойчивым, я не был бы удовлетворен сравнением наклонов двух соседних сегментов. Руки могут дрожать, углы могут быть сглажены, и идеальные условия для нахождения прямых линий и острых углов, вероятно, никогда не появятся. Для каждой точки, исследуемой на разрыв, я бы взял средний уклон N предыдущих сегментов и сравнил его со средним наклоном N следующих сегментов. Это может быть эффективно реализовано с использованием скользящего среднего . Выбрав правильный номер выборки N (в зависимости от точности ввода, общего количества точек и т. Д.), Алгоритм может избежать шума и улучшить обнаружение.

В основном алгоритм будет:

  • Для каждой исследуемой точки (начало N точек в последовательности и конец N точек до конца.)
    • Вычислить средний уклон N предыдущих сегментов.
    • Вычислить средний наклон следующих сегментов N .
    • Если разница средних значений больше, чем Threshold , отметьте текущую точку как точку разрыва.

Это совершенно не в моей голове. Вы должны попробовать это в своем приложении.

...