我正在开发一个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功能,我将深表感谢。
答案 0 :(得分:2)
您在国际象棋棋盘上的频谱非常好。一只手插进去,弄乱了黑白方格之间的常规过渡所建立的频率。尝试在周围移动一个更大的正方形(假设尺寸为4.5 x 4.5正方形),看看频率发生了什么。
如果您将一系列照片作为电影拍摄,则另一种方法是分析运动。取连续帧的差异(先对它们进行低通滤波)以检测运动。及时过滤运动(超过几帧)。然后对这些运动进行阈值处理以获得二进制图像。侵蚀二进制形状以过滤掉小的运动物体(噪声,国际象棋棋子),从而能够检测棋盘上是否有更大的运动形状(例如手)。
答案 1 :(得分:1)
在这里,在检测到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
然后,从图中您可以看到两行之间有一个适当的间隔。出现手的区域在行中有更多的间隔。
在该位置,如果完成轮廓绘制,则可以检测到棋盘上的手(或任何物体)。
这有助于解决将任何物体放在国际象棋棋盘上的问题。
答案 2 :(得分:0)
非常感谢大家的建议。
所以我主要使用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%,那么我推断其中有手(或其他东西)。
这很可能不是一种最佳方法,并且有很多缺点,但是它非常简单,对我来说也很好:)
答案 3 :(得分:-1)
您如何考虑将图像转换为HSV颜色空间并搜索手的颜色。然后,您可以搜索轮廓,并且如果最大轮廓的大小大于您设置的值,则可以说图像上有一只手。我已经用您发布的图像制作了一个样本,并且可以对此图像进行处理,但是需要与其他人进行测试(可能会更改颜色范围)。
示例:
import cv2
import numpy as np
img = cv2.imread('chess.jpg')
kernel = np.ones((7,7),np.uint8)
erosion = cv2.erode(img,kernel,iterations = 1)
hsv = cv2.cvtColor(erosion, cv2.COLOR_BGR2HSV)
lower_skin = np.array([0,100,200])
upper_skin = np.array([10,255,255])
mask = cv2.inRange(hsv, lower_skin, upper_skin)
im, contours, hierarchy = cv2.findContours(mask,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
cnt = max(contours, key=cv2.contourArea)
size = cv2.contourArea(cnt)
if size > 300:
x,y,w,h = cv2.boundingRect(cnt)
cv2.rectangle(img,(x,y),(x+w,y+h),(0,0,255),2)
print('Hand detected')
else:
print('No hand detected')
cv2.imshow('img',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
结果:
Hand detected
No hand detected