使用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%,那么我推断其中有手(或其他东西)。
很可能这不是最佳方法并且有很多弱点,但它非常简单并且对我来说很好:)
我正在开发一个 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%,那么我推断其中有手(或其他东西)。
很可能这不是最佳方法并且有很多弱点,但它非常简单并且对我来说很好:)