左侧为示例图,右侧为子图,绿框区域为机器视觉识别到的位置。

这两天有个脑洞想要实现一下,现在有了一点眉目在这边报个喜。

传统项目开发过程中UI出图之后,进行切图。然后由UE或者程序去进行游戏引擎内的拼接,这个过程虽然伤害不大但是费眼神。那么有办法解决吗?

有,还不少,PSD to Unity 的类似方案。实际上这部分拼图的工作让UI承担了。笑容只是从UI的脸上转移到了别人脸上。工作量仍然存在。

既然如此,我们不妨换个思路,旧的流程不变,仍旧是UI出layer(底板图)以及切片过的UI。我们通过机器视觉将切片定位到layer图的精确坐标。

算法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
def match(self, single_image_path, mode=cv2.TM_CCOEFF_NORMED, show_preview=False):
single_image = cv2.imread(single_image_path)
result = cv2.matchTemplate(self.big_image, single_image, mode)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)

# 如果最大匹配值小于阈值,则认为没有找到匹配的位置
threshold = 0.8 # 设置阈值
if max_val < threshold:
return None, None

top_left = max_loc

if len(single_image.shape) == 2:
h, w = single_image.shape
else:
h, w, _ = single_image.shape

bottom_right = (top_left[0] + w, top_left[1] + h)

if show_preview:
# 在大图中标记出单独图像的位置
marked_image = self.big_image.copy()
cv2.rectangle(marked_image, top_left, bottom_right, (0, 255, 0), 2)
# 显示标记后的大图
cv2.imshow('Located Image', marked_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

return top_left, bottom_right

最后将这个坐标保存,以及定义一些切片图的命名后缀。

接下来要做的工作就是拿到坐标信息,在不同的UI环境下自动生成摆放好的UI界面。

现在我已经做了如下工作:

路径扫描,图片识别,按照文件大小排序记录位置信息保存在当前文件夹下,如果有深一层路径继续往下扫描。

目前看下来准确率非常高,后面有空就在fairygui,或者ugui中实现一版,自动拼图工具。

代码会对其他图片按照像素尺寸进行排序,以确保先处理尺寸较大的图片。

项目地址:

https://github.com/KeyleXiao/KeyleFinder