我的目标是获得棋类游戏中棋子的颜色和位置的识别。由于github上有许多教程,因此识别非常容易。使用opencv函数 cv2.findChessboardCorners 和 cv2.drawChessboardCorners (清除Chessboard),我获得了满意的结果,如下图所示:
但是,当我尝试获取带有已识别棋子的图像的角落或棋盘上的棋子(不是空的棋盘)图像的角落时,它会失败,并且我不会获得任何结果。
我不附加任何代码,因为我仅使用这两个函数。
我该如何解决?我需要做任何手动校准吗?
我希望有人做了类似的事情并且可以解决我的问题。
最佳答案
我的答案是C++,但可以轻松转移到Python。
您正在使用OpenCV的findChessboardCorners
函数,该函数实际上不是用于在任何可能的棋盘上查找角的函数。该功能通常用于摄像机校准(确定摄像机参数),并且需要例如自印的黑白棋盘。可以找到一个较旧的示例here。有趣的是,它也适用于您的棕色棋盘。
为了找到棋盘角,我建议使用其他OpenCV工作流程。
我正在读取图像,在图像上应用双边过滤器以平滑图像但保留边缘,然后使用goodFeaturesToTrack
函数查找图像中最强的角。由于您没有提供没有附加行的图像,因此我使用了棕色棋盘的随机互联网图像: C++代码如下:
int main(int argc, char** argv)
{
// Reading the images
cv::Mat img = cv::imread("chessboard_2.jpg", cv::IMREAD_GRAYSCALE);
cv::Mat img_rgb = cv::imread("chessboard_2.jpg", cv::IMREAD_COLOR);
cv::Mat bilateral_filtered_image;
// Applying a bilateral filter to smooth the image
cv::bilateralFilter(img, bilateral_filtered_image, 5, 75, 75);
cv::namedWindow("Bilateral Filter", cv::WINDOW_NORMAL);
cv::imshow("Bilateral Filter", bilateral_filtered_image);
cv::waitKey(0);
// Find corner points using goodFeaturestoTrack with appropriate parameters
std::vector<cv::Point2f> corners;
cv::goodFeaturesToTrack(bilateral_filtered_image, corners, 200, 0.01, 120);
std::cout << corners.size() << std::endl;
// Draw all corners on the original image and show the image
for (size_t i = 0; i < corners.size(); ++i) {
cv::circle(img_rgb, cv::Point2f(corners[i].x, corners[i].y), 7, (0,0,255), 3);
}
cv::namedWindow("Corners", cv::WINDOW_NORMAL);
cv::imshow("Corners", img_rgb);
cv::waitKey(0);
}
结果: