如何识别棋盘游戏中的六边形拼贴?

信息处理 图像处理 opencv 图像分割
2021-12-23 02:43:06

我想识别照片中六边形平铺的边界,如下图所示:

在此处输入图像描述

在我看来,方形网格的标准方法是首先检测角点(例如 canny),然后通过霍夫变换或类似的东西提取最长的线。

这看起来不是十六进制平铺的最佳解决方案,因为外线的长度较短,并且很难将它们与其他线分开。

有没有解决这个问题的算法?在opencv中有一个解决方案会特别好,但我也对一般想法感兴趣。

更新:

使用 python 和 opencv 我能够收到这个结果: 轮廓

这是我的代码:

import cv2
import numpy as np

imgOrig = "test1";
img = cv2.imread(imgOrig+".jpg");  
lap = cv2.Laplacian(img, cv2.IPL_DEPTH_32F, ksize = 3)  
imgray = cv2.cvtColor(lap,cv2.COLOR_BGR2GRAY)  
ret,thresh = cv2.threshold(imgray,127,255,0)
contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
size = img.shape
m = np.zeros(size, dtype=np.uint8)
for i, cnt in enumerate(contours):
    if cv2.contourArea(cnt) >= 1:
        color = (255,255,255)
        cv2.drawContours(m, cnt, -1, color, -1)
cv2.imwrite(str(imgOrig)+"contours.jpg", m);

图像的拉普拉斯算子如下: 拉普拉斯算子

我将尝试优化这种方法的参数,然后尝试插入四个部分的边界。

2个回答

第一种方法:

根据本教程http://note.sonots.com/SciSoftware/haartraining.html使用 opencv 的 haartraining 方法——这应该会给出最好的结果,但到目前为止我还没有使用 haartraining...

第二种方法:

我建议对棋盘的各个图块使用“无标记跟踪”的方法。您也可以使用 OpenCV 来实现它。

准备

  1. 为此,您需要每种瓷砖的一些照片。拍摄所有瓷砖类型的照片(每一种都作为一张照片),图片中间的自上而下视图瓷砖具有均匀的背景。

  2. 然后使用一些特征检测器(OpenCV 有多种算法,但 SIFT/SURF 是非自由算法;我建议使用“FAST”)在图像中找到独特的点。

  3. 使用特征描述符来描述在图像中找到的特征(例如使用“BRIEF”)。

检测

现在,您可以通过对该图像应用相同的特征检测器/描述符算法来检测图像中的图块。获得特征/描述符后,您可以应用 FlannBasedMatcher 来查找图块。

这是来自 OpenCV 的代码示例/教程:http: //docs.opencv.org/doc/tutorials/features2d/feature_homography/feature_homography.html#feature-homography

笔记

Matcher Method 只会给你一个匹配,如果在板上找到多个该类型的瓷砖,则可能会出现问题。您可以通过仅屏蔽输入图像的某些部分来解决该问题。我建议使用检测到的特征的像素坐标来执行此操作。如果你 - 不知何故 - 首先检测到瓷砖的轮廓和大小,你可以粗略估计图片上的瓷砖位置和大小。在匹配之前过滤您检测到的特征列表(例如,仅从瓦片的预期中点开始的 x 像素半径内的特征),然后使用最强的匹配。结果,您将获得图块在图像上的确切位置(包括它的方向)。如果检测地图轮廓太复杂,可以让用户“点”在角落瓦片上手动标记轮廓……

替代方法

您还可以使用此方法通过其轮廓找到任何瓷砖。绘制一个没有任何图像的瓷砖(六边形)的示例“示意图”灰度图片。请注意,此图像中的“暗”和“亮”区域在原理图中需要正确,而不仅仅是一些“线”。您可能需要对此进行试验。您可以尝试对不同图块的多张照片进行平均,以生成图块的“平均”图像。确保角落在同一位置(相应地移动/缩放图片)并在完成后锐化图片(清晰的角落/边缘应该可见)并在需要时稍微调整对比度。

我将描述我目前的方法,它结合了利用游戏规则、图像处理和特征检测。

相关游戏规则

实现

起初我使用霍夫变换来提取游戏板的位置。源图像看起来与有问题的最终图像相似,但线条更粗,我过滤了较小的边界。我只使用检测非常长的线条(数量级:大约 60% 的图像宽度/高度)和非常小的线条匹配阈值。我也只看图像外部 40% 的线条,并取顶部、底部、左侧和右侧检测到的线条的中值。结果如下图所示: 霍夫变换

我只需要一个粗略的近似值,所以这很好。从现在开始,我只检查霍夫线内的图像,加上一些额外的空间,因为霍夫变换的不确定性。

然后,我使用 Stefan K. 在他的回答中提出的特征检测来检测图像中玩家无法拍摄的特征,即城堡、位置图块和山脉。我使用 opencv-python 中的 ORB 算法和 BruteForce-Hamming-Matcher (我还不能让 FlannBased 匹配器运行)。ORB 是比例和旋转不变的。为了检测相同特征的多次出现(例如城堡),我将图像分割成重叠的部分。只要图像分辨率足够大并且图片是直接从顶部拍摄的(仍需要一些测试),这就可以正常工作。它也有点慢。位置图块(酒馆)的检测如下图所示 城堡特征检测

目前我试图找到单应变换来提取检测到的特征的确切位置和方向。

我希望能够根据这些信息(山的位置、城堡、位置图块以及大多数情况下的水)重建网格。Currents 实验看起来很有希望,尽管必须进行大量微调和正确准备特征图像。