Где я могу узнать / найти примеры распознавания жестов, передаваемых с Kinect с использованием OpenCV? - PullRequest
7 голосов
/ 16 декабря 2010

У меня есть Kinect и драйверы для Windows и MacOSX. Есть ли примеры распознавания жестов, передаваемых из Kinect с использованием OpenCV API? Я пытаюсь добиться аналогичного прототипа DaVinci на Xbox Kinect , но в Windows и MacOSX.

Ответы [ 3 ]

15 голосов
/ 18 декабря 2010

Демонстрация по вашей ссылке, похоже, не использует настоящий жест распознавание. Он просто различает две разные позиции рук (открытая / закрытая), что намного проще, и отслеживает положение рук. Учитывая то, как он держит руки в демоверсии (перед телом, лицом к kinect, когда они открыты), вот, вероятно, то, что он делает. Поскольку вы не указали, какой язык вы используете, я буду использовать имена функций C в openCV, но они должны быть похожими на других языках. Я также предполагаю, что вы можете получить карту глубины из kinect (возможно, с помощью функции обратного вызова, если вы используете libfreenect).

  1. Порог на глубине, чтобы выбрать только точки, достаточно близко (руки). Вы можете достичь этого либо сами, либо напрямую используя openCV для получения двоичного изображения (cvThreshold () с CV_THRESH_BINARY). Отобразите изображение, полученное после установки порогового значения, и отрегулируйте пороговое значение в соответствии с вашей конфигурацией (старайтесь не находиться слишком близко к кинекту, поскольку в этой области больше помех).

  2. Получить контур рук с помощью cvFindContour ()

Это основа. Теперь, когда у вас есть контуры рук, в зависимости от того, что вы хотите сделать, вы можете идти в разных направлениях. Если вы просто хотите обнаружить между открытой и закрытой рукой, вы можете сделать:

  1. Получить выпуклую оболочку рук с помощью cvConvexHull2 ()

  2. Получите дефекты выпуклости, используя cvConvexityDefect () для контуров и выпуклой оболочки, которую вы получили ранее.

  3. Проанализируйте дефекты выпуклости: если есть большие дефекты, рука открыта (потому что форма вогнута между пальцами), если не рука закрыта.

Но вы также можете обнаружить палец! Это то, что я делал на прошлой неделе, это не требует больших усилий и, вероятно, повысит вашу демонстрацию! Дешевый, но довольно надежный способ сделать это:

  1. Приблизить контуры рук с помощью многоугольника. Используйте cvApproxPoly () для контура. Вам нужно настроить параметр точности так, чтобы иметь многоугольник как можно проще, но это не смешивает пальцы (около 15 должно быть неплохо, но нарисуйте его на своем изображении, используя cvDrawContours (), чтобы проверить, что вы получите) ,

  2. Анализировать контур, чтобы найти острые выпуклые углы. Вы должны будете сделать это вручную. Это самая сложная часть, потому что:

    • Поначалу структуры данных, используемые в openCV, могут немного сбивать с толку. Если вы слишком много боретесь со структурой CvSeq, cvCvtSeqToArray () может помочь.
    • Вы, наконец, должны сделать некоторую (основную) математику, чтобы найти выпуклые углы. Помните, что вы можете использовать точечное произведение, чтобы определить, насколько точен угол, и векторное произведение, чтобы различить выпуклый и вогнутый углы.
  3. Вот вы, острые выпуклые углы - ваши кончики пальцев!

Это простой алгоритм для обнаружения пальцев, но есть много способов его повысить. Например, вы можете попытаться применить медианный фильтр на карте глубины, чтобы немного «сгладить» все, или попытаться использовать более точное приближение многоугольника, но затем отфильтровать контур, чтобы объединить точки, которые должны закрываться на кончиках пальцев, и т. Д. .

Удачи и веселья!

0 голосов
/ 26 января 2011

mage dest = new Image (this.bitmap.Width, this.bitmap.Height); CvInvoke.cvThreshold (src, dest, 220, 300, Emgu.CV.CvEnum.THRESH.CV_THRESH_BINARY); Растровое изображение nem1 = новое растровое изображение (dest.Bitmap); this.bitmap = nem1; Графика g = Graphics.FromImage (this.bitmap);

                using (MemStorage storage = new MemStorage()) //allocate storage for contour approximation
                    for (Contour<Point> contours = dest.FindContours(); contours != null; contours = contours.HNext)
                    {
                        g.DrawRectangle(new Pen(new SolidBrush(Color.Green)),contours.BoundingRectangle);
                       // CvInvoke.cvConvexHull2(contours,, Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE, 0);
                        IntPtr seq = CvInvoke.cvConvexHull2(contours,storage.Ptr, Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE, 0);
                       IntPtr defects = CvInvoke.cvConvexityDefects(contours, seq, storage);
                      Seq<Point> tr= contours.GetConvexHull(Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE);

                      Seq<Emgu.CV.Structure.MCvConvexityDefect> te = contours.GetConvexityDefacts(storage, Emgu.CV.CvEnum.ORIENTATION.CV_CLOCKWISE);
                      g.DrawRectangle(new Pen(new SolidBrush(Color.Green)), tr.BoundingRectangle);
                      //g.DrawRectangle(new Pen(new SolidBrush(Color.Green)), te.BoundingRectangle);

                    }

Я сделал по вашему алгоритму, но он не работает Что такое отжим?

0 голосов
/ 04 января 2011

Я думаю, что это не будет так просто, в основном потому, что данные глубинного изображения из kinect не так чувствительны.Таким образом, после расстояния от 1 до 1,5 м все пальцы будут объединены, и, следовательно, вы не сможете получить четкие контуры для обнаружения пальцев

...