使用opencv检测棋盘上方的手

Detecting a hand above a chessboard using opencv

我正在开发一个 android 应用程序,用于根据一系列照片分析国际象棋游戏。为了处理图像,我使用的是 OpenCV。我的问题是如何检测图片上有玩家的手?因为我想过滤那些照片,只分析那些只有棋盘的照片。

到目前为止,我设法得到了 Canny,所以从这样的图像 原图

我能做到精明

.

但是我不知道接下来我能做什么...

我用来获取Canny的代码:

Mat gray, blur, cannyed;
cvtColor(img, gray, CV_BGR2GRAY);
GaussianBlur(gray, blur, Size(7, 7), 0, 0);
Canny(blur, cannyed, 50, 100, 3);

对于下一步该做什么以及我可以使用哪些 OpenCV 函数的任何想法和建议,我将不胜感激。

你在棋盘上的频谱非常好。一只手在其中弄乱了由黑色和白色方块之间的规则过渡建立的频率。试着移动一个更大的正方形(比如说 4.5 x 4.5 正方形的大小),看看频率会发生什么变化。

如果您将一系列图片拍摄成电影,另一种方法是分析动作。利用连续帧的差异(先对它们进行低通滤波)来检测运动。及时过滤运动(超过几帧)。然后对这些运动进行阈值处理以获得二值图像。侵蚀二进制形状以过滤掉小的移动物体(噪音、国际象棋图形)能够检测棋盘上是否有任何更大的移动形状(例如手)。

这里,在Canny Edge detection之后我尝试了水平和垂直线提取过程的形态学操作。

 Mat horizontal = cannyed.clone();
    // Specify size on horizontal axis
    int horizontalsize = horizontal.cols / 60;
    // Create structure element for extracting horizontal lines through morphology operations
    Mat horizontalStructure = getStructuringElement(MORPH_RECT, Size(horizontalsize,1));
    erode(horizontal, horizontal, horizontalStructure, Point(-1, -1),2);
    dilate(horizontal, horizontal, horizontalStructure, Point(-1, -1),1);
    imshow("horizontal",horizontal);

    Mat vertical = cannyed.clone();
    // Specify size on horizontal axis
    int verticalsize = vertical.cols / 60;
    // Create structure element for extracting horizontal lines through morphology operations
    Mat verticalStructure = getStructuringElement(MORPH_RECT, Size(1,verticalsize));
    erode(vertical, vertical, verticalStructure, Point(-1, -1));
    dilate(vertical, vertical, verticalStructure, Point(-1, -1),2);
    imshow("vertical",vertical);

结果是, Horizontal Lines in the chess board

那么,从图中可以看出,线条之间有一个适当的间隔。手所在的区域有更多的线条间隔。

在该位置,如果完成轮廓,则可以检测到棋盘上方的手(或任何物体)。

这有助于解决放置在棋盘上的任何物体。

非常感谢大家的建议。

所以我主要使用 Gowthaman 的方法解决了这个问题。首先我用他的代码生成垂直线和水平线。然后我像这样组合它们:

Mat combined = vertical + horizontal; 

所以我在没有手的时候得到类似的东西

或者有手的时候这样

接下来我使用代码计算白色像素:

int GetPixelCount(Mat image, uchar color)
{
    int result = 0;

    for (int i = 0; i < image.rows; i++)
    {
        for (int j = 0; j < image.cols; j++)
        {
            if (image.at<uchar>(Point(j, i)) == color)
                result++;
        }
    }

    return result;
}

我对系列中的每张照片都这样做。第一张照片总是没有手,所以我用它作为模板。如果当前照片的模板白色像素少于 98%,那么我推断其中有手(或其他东西)。

很可能这不是最佳方法并且有很多弱点,但它非常简单并且对我来说很好:)