python识图坐标_python 识别minecraft截图坐标

作为一个我的世界资深玩家,从一个地方到另外的一个地方也得徒步旅行,哪怕是开船,骑马也是很慢的,通过下界还可以,远点也要跑好久。

我是服务器的 op 角色可以直接使用 tp 命令到达某个地方,依然有个很头疼的地方,不知道要去的地方乍样,坐标如何。

于是我就想着做一个相册,然后通过 OCR 来识别坐标,然后点击一下图片就能到那一个地方。

我们来开一下几个 tp 命令吧

execute in world tp user x y z

我们需要把截图的世界类型和坐标识别出来,我试了一些现成的 OCR 工具不能很好的识别出来,于是自己用 python 写了一个。

2020-10-09_21.40.43.png

分析截图,我们发现坐标和世界类型位置比较固定,我们使用 graphicsmagick 将坐标和世界类型截下来。

gm convert -crop 600x30+0+260 ${image} world.jpg # 切出世界类型

gm convert -crop 800x30+90+330 ${image} position.jpg # 切出坐标图

初始化,并对图片进行预处理

import numpy as np

from PIL import Image

读取一张图片转成 numpy 数组

data = np.array(Image.open('world.jpg').convert("L"))

图片进行二值化

def normal_image(data, revert = False):

# 获取矩阵(图像)的长宽

data = np.copy(data)

rows, cols = data.shape

for i in range(rows):

for j in range(cols):

# 与阈值比较

if data[i, j] <= 220:

# 设为灰度最小值

if revert:

data[i, j] = 0

else:

data[i, j] = 1

else:

# 设为灰度最大值

if revert:

data[i, j] = 1

else:

data[i, j] = 0

return data

data = normal_image(data)

切除图片的空白边框

def strip_row(data):

# 每行最小值

row_min = np.min(data, axis=1)

# 找到第一个有图像的行

row_start = np.argmin(row_min)

# 找到最后一个有图像的行

row_end = np.argmin(np.flip(row_min))

# 只取有图像的行

if row_end > 0:

data = data[row_start:-row_end, :]

else:

data = data[row_start:, :]

return data

def strip_col(data):

# 每行最小值

col_min = np.min(data, axis=0)

# 找到第一个有图像的行

col_start = np.argmin(col_min)

# 找到最后一个有图像的行

col_end = np.argmin(np.flip(col_min))

# 只取有图像的行

if col_end > 0:

data = data[:, col_start:-col_end]

else:

data = data[:, col_start:]

return data

data = strip_row(data)

data = strip_col(data)

识别世界类型

我的世界类型在原版的只有三种类型,minecraft:overworld, minecraft:the_nether 和 minecraft:the_end。

我们只要比对三张图片是否一致就可以。

分别找到三个世界类型的图片,分别预处理后保存成图片,作为世界类型库。

def to_image_array(data):

data = np.copy(data)

# 获取矩阵(图像)的长宽

rows, cols = data.shape

for i in range(rows):

for j in range(cols):

# 与阈值比较

if data[i, j] == 0:

# 设为灰度最小值

data[i, j] = 0

else:

# 设为灰度最大值

data[i, j] = 255

return data

data = to_image_array(data)

img = Image.fromarray(data)

img.save('datasets/overworld.jpg') # 保存成黑白图

# img.save('datasets/the_nether.jpg')

# img.save('datasets/the_end.jpg')

读取世界类型库

datasets = []

dataset = np.array(Image.open('dataset/overworld.jpg').convert("L"))

dataset = normal_image(dataset, True)

datasets.append(dataset)

对比两个世界类型是不是一样(识别)

def recog_one(data, datasets):

x = data.flatten()

got = -1

score = -1

for num, dataset in datasets:

try:

new_score = np.sum(x ^ dataset)

if score == -1:

score = new_score

got = num

if score > new_score:

score = new_score

got = num

except Exception:

pass

return got, score

recog_one(data, datasets)

到这里我们已经把世界类型识别给搞定了。

识别坐标

识别坐标与识别世界类型相识,我们需要把数字切出来,然后手动做字库,最后比对数字,拼成坐标字符就可以搞定。

找出数字的坐标

def find_num_poses(data):

poses = [0]

for pos in range(4, data.shape[1]):

img_matrix_spited = data[:, :pos]

col_min = np.min(img_matrix_spited, axis=0)

col_end = np.argmin(np.flip(col_min))

if col_end > 0:

rel_pos = pos - col_end

if rel_pos not in poses:

poses.append(rel_pos)

return poses

poses = find_num_poses(data)

将数字切出来并保存成文件

poses_start = poses[0:-1]

poses_end = poses[1:]

got_nums = []

for col_start, col_end in zip(poses_start, poses_end):

img_matrix_spited = img_matrix[:, col_start:col_end]

img_matrix_spited = strip_col(img_matrix_spited)

save_image(img_matrix_spited, 'position-{}-{}'.format(col_start, col_end))

手工制作字体库

同样的方法识别每一个数字,最后形成一个坐标。

总结

我们到此位置已经完成了我的世界截图的坐标识别和世界类型识别。

相关代码详见

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值