0.从游戏开始入门计算机视觉
最近开始将我的教程翻译成英文,由于翻译过程中涉及示例代码的i18n修改,进度可能要稍微落后于我的中文博客。如果您对英文版感兴趣,可以移步这里。
Recently, I started translating my tutorials into English.Due to internationalization modifications in the example code during the translation process, and the progress may be slightly behind my Chinese blog. If you're interested in the English version, you can move HERE.
最近迷上一款游戏叫做《月圆之夜》,是一个类似云顶之弈和炉石传说的卡牌自走棋类游戏。
因为官方缺乏成体系的资料,让我这样的技术宅很难入门。
所以我们要一起制作一个游戏资料数据库。
游戏里的卡牌看上去是这样的:
| 中文实例 | 英文实例 |
|---|---|
机器视觉部分的目的:通过对游戏截图的识别,将游戏中的随从牌信息录入数据库。
因为游戏中的随从非常多(202张),想要一目了然的分析随从之间的匹配程度,就需要更直观且方便的数据过滤和展现方式。
为了实现这一目的,我们先整理一下大致的思路和步骤:
- 识别出图片中的卡片。
- 识别卡片中的文字信息
- 去重后录入数据库
这其中会用到哪些技术手段和开源库,我们后面慢慢讲。
为了更好的阅读体验,本文档中的代码均为关键性功能示例,省去了项目中相对复杂的逻辑判断。
代码仅供参考学习,在您的项目里,可能需要针对具体业务做出调整。
1.识别出图片中的卡牌
对于人类而言,什么是卡牌我们显然很清楚,但是如何让计算机知道什么是卡牌?
当然是我们先给出明确的定义:
卡牌(Card)是一种长方形的平面小物件,上面有图案、数字、文字或符号。
那么接下来,我们就要让计算机从图片中识别出我们所定义的卡牌。
具体思路是:
- 加载图像
- 将图像转换为灰度图
- 进行Canny边缘检测
这里我们主要会用到OpenCV这个库来做图片处理。
OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉库,它提供了大量用于处理图像和视频的工具、算法和函数。
OpenCV最初由Intel开发,以BSD许可证授权发行,可以在商业和研究领域中免费使用。 这个库的主要目标是使计算机视觉任务变得更加容易实现,并且它在许多领域中都有广泛的应用,包括机器学习、图像处理、计算机视觉研究、工业自动化和嵌入式系统等。
import cv2
# 载入图片 Load the image
img = cv2.imread('images/01.jpg')
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 设置边缘检测 Apply edge detection
edges = cv2.Canny(img_gray, threshold1=30, threshold2=100)
# 查找边缘 Find contours
contours, hierarchy = cv2.findContours(edges.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
从上图可以看出,我们已经找到了一些轮廓。
但是问题来了,最上面的种族、卡牌类型、卡牌等级这样的信息也被边缘检测找到了。
这显然不符合我们的预期,我们重新定义卡牌的概念,同时可以通过剔除过小的轮廓来改进这一点。
卡牌(Card)是一种长方形的平面小物件,上面有图案、数字、文字或符号。
面积最少36000平方像素(>=150x240)。
import cv2
# Load the image
img_path = 'images/01.jpg'
img = cv2.imread(img_path)
if img is None:
print("Image load failed!")
exit(0)
# Convert the image to RGB before displaying
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# Find contours
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(img_gray, threshold1=30, threshold2=100)
contours, hierarcy = cv2.findContours(edges.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# Filter out small contours based on the area[HA]
min_contour_area = 36000
large_contours = [cnt for cnt in contours if cv2.contourArea(cnt) > min_contour_area]
# Draw contours and label them
img_contours = img_rgb.copy()
for i, contour in enumerate(large_contours):
# Get the bounding box of the contour
x, y, w, h = cv2.boundingRect(contour)
# Draw the contour and label it
cv2.rectangle(img_contours, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.putText(img_contours, str(i + 1), (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2)
# Display the image with contours and labels
cv2.imshow('Contours', img_contours)
cv2.waitKey(0)
让我们看一下成果[HA]
| 我们看到的 | 计算机看到的 |
|---|---|
在代码中,我们转换了颜色,其目的是为了查找边缘的时候减少信息干扰,这部分我们暂时只需要了解个大概,更多的颜色转化目的如下:
-
灰度图像 (Grayscale) :
- 减少计算复杂性:当你的任务涉及到图像处理或分析时,而不需要考虑颜色信息时,可以将图像转换为灰度图像。灰度图像只包含亮度信息,而不包括颜色信息,因此在某些情况下可以减少计算复杂性。
- 特征提取:在一些计算机视觉任务中,如人脸检测或目标识别,灰度图像通常足够用于提取重要的特征,因为颜色信息可能不是那么关键。
-
RGB图像:
- 颜色相关任务:如果你的任务涉及到颜色信息,例如图像分类中的颜色作为重要特征之一,那么你应该保留RGB(红绿蓝)图像的色彩信息。
- 分割任务:在图像分割任务中,RGB图像通常更有用,因为颜色可以帮助区分不同的对象或区域。
-
其他色彩模式:
- HSV模式:HSV(色调、饱和度、亮度)模式常用于颜色分析和处理,因为它更直观地表示颜色属性。它对某些颜色相关的任务可能更有用。
- Lab模式:Lab色彩模式通常用于颜色相关任务和图像分析,因为它分离了亮度信息(L通道)和颜色信息(a和b通道),使得颜色处理更容易。