Где я могу узнать/найти примеры распознавания жестов, передаваемые из Kinect, с использованием OpenCV?

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


person Roman Kagan    schedule 16.12.2010    source источник
comment
Это интересная проблема. Я думаю, что ваши шансы найти решение будут выше, если вы разберете проблему и пересмотрите свои варианты для каждой проблемы. Какие данные вы ожидаете получить от Kinect? Это просто видеопоток, который вам нужно обработать? В данном случае это упрощается до общей проблемы распознавания жестов — вероятно, это довольно активная область исследований. Или вы как-то хотите воспользоваться программным обеспечением для распознавания жестов на устройстве? В любом случае, разговор с ребятами, которые внедрили демо по вашей ссылке, вероятно, будет хорошим стартовым шагом.   -  person mpenkov    schedule 16.12.2010
comment
Можете ли вы предоставить исходный код для него в С#, это будет очень полезно   -  person Rikki    schedule 25.01.2011


Ответы (3)


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

person jumanji    schedule 04.01.2011
comment
На расстоянии 1,5 м я все еще могу видеть свои пальцы на моем кинекте. Также обратите внимание, что на видео, которым поделился ОП, ведущий находится ближе. И, наконец, как это отвечает на вопрос? - person Jules Olléon; 06.01.2011

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

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

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

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

  1. Получите выпуклую оболочку рук, используя cvConvexHull2()

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

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

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

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

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

    • The data structures used in openCV might be a bit confusing at first. If you struggle too much with the CvSeq structure, cvCvtSeqToArray() might help.
    • Наконец-то вы можете выполнить некоторые (основные) математические действия, чтобы найти выпуклые углы. Помните, что вы можете использовать скалярное произведение, чтобы определить, насколько острым является угол, и векторное произведение, чтобы различить выпуклые и вогнутые углы.
  3. Вот вам и острые выпуклые углы — кончики ваших пальцев!

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

Удачи и приятного времяпровождения!

person Jules Olléon    schedule 18.12.2010

mage dest = новое изображение (this.bitmap.Width, this.bitmap.Height); CvInvoke.cvThreshold(src, dest, 220, 300, Emgu.CV.CvEnum.THRESH.CV_THRESH_BINARY); Bitmap nem1 = новый Bitmap (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);

                    }

Сделал по твоему алгоритму, но не работает Что такое wwr?

person Rikki    schedule 26.01.2011