1

我正在做一个涉及手势识别的项目。我必须识别手势并识别它代表的字母。我能够使用 HSV 颜色空间检测皮肤。我有一个所有字母手势的视频和所有字母手势的图像。现在我必须找到哪个手势代表哪个字母。我需要知道如何将每一帧视频中的手势与图像手势进行比较。我是 opencv 新手,请有人帮助我.这是我的代码

#include <opencv2\opencv.hpp>

using namespace cv;
using std::cout;

/*--------------- SKIN SEGMENTATION ---------------*/
   int main() {

  VideoCapture cap("E:\\videotest.mp4");

if (!cap.isOpened())
{// check if we succeeded
    printf("coundnotoepn");
    return -1;
}
Mat3b frame;
while (cap.read(frame)){

    /* THRESHOLD ON HSV*/
    cvtColor(frame, frame, CV_BGR2HSV);
    GaussianBlur(frame, frame, Size(7, 7), 1, 1);
    medianBlur(frame, frame, 15);
    for (int r = 0; r<frame.rows; ++r){
        for (int c = 0; c<frame.cols; ++c)
            // 0<H<0.25  -   0.15<S<0.9    -    0.2<V<0.95   
            if ((frame(r, c)[0]>5) && (frame(r, c)[0] < 17) && (frame(r, c)[1]>38) && (frame(r, c)[1]<250) && (frame(r, c)[2]>51) && (frame(r, c)[2]<242)); // do nothing
            else for (int i = 0; i<3; ++i)  frame(r, c)[i] = 0;
    }

    /* BGR CONVERSION AND THRESHOLD */
    Mat1b frame_gray;
    cvtColor(frame, frame, CV_HSV2BGR);
    cvtColor(frame, frame_gray, CV_BGR2GRAY);
    threshold(frame_gray, frame_gray, 60, 255, CV_THRESH_BINARY);
    morphologyEx(frame_gray, frame_gray, CV_MOP_ERODE, Mat1b(3, 3, 1), Point(-1, -1), 3);
    morphologyEx(frame_gray, frame_gray, CV_MOP_OPEN, Mat1b(7, 7, 1), Point(-1, -1), 1);
    morphologyEx(frame_gray, frame_gray, CV_MOP_CLOSE, Mat1b(9, 9, 1), Point(-1, -1), 1);

    medianBlur(frame_gray, frame_gray, 15);
//  imshow("Threshold", frame_gray);

    cvtColor(frame, frame, CV_BGR2HSV);
    resize(frame, frame, Size(), 0.5, 0.5);
    imshow("Video", frame);



    Mat3b image;
    image = imread("E:/hand.jpg", CV_LOAD_IMAGE_COLOR);   // Read the file

    if (!image.data)                              // Check for invalid input
    {
        cout << "Could not open or find the image" << std::endl;
        return -1;
    }
    cvtColor(image, image, CV_BGR2HSV);
    //printf("%d", image(2, 3)[5]);
    //resize(image,image, Size(), 0.5, 0.5);
    namedWindow("Display window", WINDOW_AUTOSIZE);// Create a window for display.
    imshow("Display window", image);                   // Show our image ins
    waitkey(1);
}
4

2 回答 2

0

有几种方法可以解决这个问题,最广泛使用和最明显的方法是跟踪每个单独的手指(或手的指向外的部分)并编写一定的规则来对每个手势进行分类(即两个手指指向手指顶部的外侧)手可能是“和平”符号或其他东西)

您可以通过跟踪凸包缺陷来做到这一点。是一个教程的链接,它将解释这个过程,它是用 Python 编写的,但我相信一旦你理解了逻辑,你就可以将它移植到 C++。

但是,如果您已经拥有每个手势的图像,我建议您使用神经网络进行分类,尝试并操作您已经拥有的图像,使它们类似于您尝试分类的图像(即进行皮肤检测和二值化图像)

是教程的另一个链接,该教程解释了神经网络是什么,它们如何工作以及如何在 C++ 中实现图像识别网络。

我必须提到,每个像素很可能都将用作网络的输入,因此为了减轻它的压力(并使其训练更快),我建议调整图像的大小以使其尽可能小(但你可以仍然做出手势)

希望这些信息对您有所帮助,祝您好运!

于 2015-03-10T11:26:47.100 回答
0

“我需要知道如何将每一帧视频的手势与图像手势进行比较。” - 关键是弄清楚哪种相似性度量对您的应用程序有效。

没有一种万能的比较图像的方法,当然也不是视频序列(比图像更难的问题)。比较图像的一种流行方法是颜色直方图上的“地球移动距离”;但这可能不适用于您的情况。您可以尝试使用经过不同手势训练的 HoG 识别器;或(例如)缩小到非常小的尺寸(如 32x32)的图像之间的 DCT 系数差异。模板匹配 (OpenCV matchTemplate) 在这里可能不起作用,因为您想将图像与类别(所有可能的同一类事物的图像)进行比较,而模板不会这样做。与 k 近邻分类和大型示例库(每个类别几千个)匹配的模板可能会起作用。

要识别手势(有运动)而不是手(不动),最好的办法是阅读文献并实施已发布的算法。尝试在 Google 学术搜索中搜索“手势识别视频”。例如:

最后,这将非常困难。不要期望 OpenCV 中的任何东西都能以简单的方式完成这项工作。OpenCV 中有 HoG,但您必须对其进行训练,并对其进行广泛的调整。您必须从头开始构建其他已发布的算法(如 3D 小波)和/或将另一个库添加到 OpenCV。祝你好运 :)

于 2015-03-10T12:38:39.253 回答