【问题标题】:Detecting a hand above a chessboard using opencv使用opencv检测棋盘上方的手
【发布时间】:2018-07-11 10:44:11
【问题描述】:

我正在开发一个基于一系列照片分析国际象棋游戏的安卓应用程序。为了处理图像,我使用 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 函数的想法和建议。

【问题讨论】:

  • 您可以在连续帧上的图像之间使用增量差异,并在没有手的情况下保留棋盘的模板图像,现在对于存在的帧,cv2.absdiff() 会更高。
  • 看看THIS
  • 在这里完全同意@JeruLuke,背景减法将是要走的路。

标签: opencv computer-vision detection


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

     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

    然后,从图中你可以看到行之间有一个适当的间隔。手所在的区域有更多的行间隔。

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

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

    【讨论】:

    • 好的,这看起来是个不错的建议。我很清楚你的意思是什么。但是我仍然不知道如何以编程方式确定是否有手。我应该遍历每一行并测量线之间的距离,还是一些 opencv 函数会为我做到这一点?在此先感谢:)
    • 您可以尝试简单地添加水平线和垂直线输出图像并从精巧的结果中减去。这会产生剩余物体,并且当您应用 findcontour 并获取最大尺寸的轮廓时,可以检测到手。
    【解决方案3】:

    非常感谢大家的建议。

    所以我主要使用 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%,那么我推断其中有手(或其他东西)。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-01-18
      • 2016-02-28
      • 2011-12-15
      • 2016-05-26
      • 1970-01-01
      • 1970-01-01
      • 2023-01-31
      • 2022-01-17
      相关资源
      最近更新 更多