我正在学习 cv2 并尝试从 2048 game 中(动态地)检测机载数字 block ,并用绿色勾勒出它们。
首先,我无法检测到橙色到红色范围(8、16、32、64)中的那些,如果我降低阈值,整个板似乎都包括在内。有时,较小的部分(例如包含 6 的圆形部分)或整个图 block 会被忽略。我将如何去检测像这样的板上的瓷砖?
这是我目前的代码:
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
对彩色图像进行阈值处理,而不是对灰度图像进行阈值处理。您可以设置允许颜色的上限和下限以包含编号的图 block ,但排除空图 block 和边缘。
此外,我假设您检查 if len(cnt) == 4:
的步骤是仅返回方形轮廓。但是,调整大小可能会导致瓷砖的轮廓不完全是正方形,并且无法通过此检查。相反,您可以通过将 findContours
的第二个输入更改为 0 (contours = cv2.findContours(thresh, 0, 2)[1]
) 将检索模式设置为 cv2.RETR_EXTERNAL
.
这是经过更改的代码,以及您提供的示例图像的适当的上下颜色边界。
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()
# inRange bounds
lower_bound = (0, 0, 210)
upper_bound = (230, 240, 250)
# 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))[:,:,:3]
resized_img = cv2.resize(img, (100, 100))
mask = cv2.inRange(resized_img, lower_bound, upper_bound)
contours = cv2.findContours(mask, 0, 2)[1]
for cnt in contours:
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()
这是创建的输出图像:
编辑:下面是直接使用示例图片的代码:
import cv2
import numpy as np
img = cv2.imread('2048.jpg')
resized_img = cv2.resize(img, (100, 100))
lower_bound = (0,0,210)
upper_bound = (230,240,250)
mask = cv2.inRange(resized_img, lower_bound, upper_bound)
contours = cv2.findContours(mask, 0, 2)[1]
for cnt in contours:
cv2.drawContours(resized_img, [cnt], 0, (0, 255, 0), 2)
cv2.imshow('2048', resized_img)
cv2.waitKey(0)
关于python - 使用 cv2 检测 2048 年的瓷砖方 block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53439913/