我正在学习cv2,并尝试从2048 game中(动态地)检测车载数字块,并用绿色勾勒出它们。在
首先,我在检测橙色到红色范围(8,16,32,64)时遇到了困难,如果我降低阈值,整个电路板似乎都包括在内。有时,会忽略较小的部分(如6的圆形部分)或整个瓷砖。我该如何检测像这样的板上的瓷砖?在
以下是我目前掌握的代码:
import cv2
import mss
import time
import numpy as np
# Static screenshot for board
monitor = {"top": 135, "left": 425, "width": 500, "height": 500}
sct = mss.mss()
# Run for a maximum of 150s or until 'q' is pressed
last_time = time.time()
while time.time() - last_time < 150:
img = np.asarray(sct.grab(monitor))
resized_img = cv2.resize(img, (100, 100))
gray_img = cv2.cvtColor(resized_img, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray_img, 200, 255, 0)[1]
contours = cv2.findContours(thresh, 1, 2)[1]
for cnt in contours:
if len(cnt) == 4:
cv2.drawContours(resized_img, [cnt], 0, (0, 255, 0), 2)
cv2.imshow("2048", resized_img)
if cv2.waitKey(25) & 0xFF == ord("q"):
break
cv2.destroyAllWindows()
样品检测:
编辑:按要求添加示例输入
样本输入:
样本输出:
感谢您的回应,即使他们是正确的方向
您可以使用
cv2.inRange
对彩色图像进行阈值化,而不是对灰度图像进行阈值化。您可以设置允许颜色的上下限,以包括编号的分幅,但不包括空的分幅和边。在另外,我假设检查} ,从而获得瓷砖的外部轮廓。在
if len(cnt) == 4:
的步骤是只返回正方形轮廓。但是,调整大小可能会导致轮廓与平铺不完全一致,并且无法通过此检查。相反,您可以通过将findContours
的第二个输入更改为0(contours = cv2.findContours(thresh, 0, 2)[1]
),从而将检索模式设置为^{下面是更改后的代码,以及您给出的示例图像的适当的颜色上限和下限。在
以下是创建的输出图像:
编辑:下面是直接使用示例图像的代码:
^{pr2}$您可以采取的一种方法是从所有瓷砖都为空的快照中获取此帧的差异。这将以最少的计算得到所需的掩码。在
由于您在问题中没有提到您可以访问所有空的tile快照,所以我还将介绍另一种称为
color segmentation
的技术。由于背景颜色是一致的,但是编号的色块会发生变化,因此我们将首先分割出背景,然后反转遮罩以找到轮廓,如下所示:中间遮罩:
+=
轮廓的最终遮罩:
输出:
相关问题 更多 >
编程相关推荐