@chendbdb
2017-03-04T05:28:56.000000Z
字数 3027
阅读 2390
XXTouch
/User/Media/1ferver/res/
目录进行测试识别图像无非是识别游戏内的金额、验证码、提示文字这几项。
以下是几种可能需要识别的图像
当考虑到识别文字时,普通情况下分为这几个步骤
因机能以及复杂程度等原因,除过滤杂线杂点、图像二化会稍加讲解其它请使用云打码平台cloud_ocr
。
0x123456
小提示:0xfffffff
这里有7个f就是典型的溢出,0xff可以忽略高位的0也就是纯蓝色。
色彩 | 中文 | 颜色 |
---|---|---|
0x000000 |
黑色 | ████████ |
0xffffff |
白色 | ████████ |
0xff0000 |
红色 | ████████ |
0x00ff00 |
绿色 | ████████ |
0x0000ff |
蓝色 | ████████ |
0xffff00 |
黄色 | ████████ |
0xff00ff |
粉色 | ████████ |
0x00ffff |
青色 | ████████ |
假设有一个颜色 0x334455
需要取这个色彩的相似度尽可能接近的色彩,就要使用到色偏。
如果区间可能在
0x00
- 0x66
上下的差值 在 0x330x33
- 0x55
上下的差值 在 0x110x33
- 0x77
上下的差值 在 0x22那么色偏取值就是 0x331122
再假如一个点 0xffffff
取这个
这部分不需要强行计算,手动调整数值尝试即可。
顾名思义就是把正常的图像转换为纯黑白(仅两个色彩0xffffff
,0x000000
)图像。
这个步骤极其关键,因为会筛选出需要识别的以白色为基础色展示,其它则为黑色展示。
binaryzation函数
img = img:binaryzation({
{颜色值本身, 最大色差值},
{颜色值本身, 最大色差值},
...
})
假设我们有图像,想要只获取图像内的绿色,并且绿色色偏0x10
,也就是0x00ef00
-0x00ff00
。
注意:超过0xff的则以0xff为准,同理低于0x0的则以0x0为准。
local img = image.load_file('/User/Media/1ferver/res/测试图像.png')
img = img:binaryzation({{0x00ff00,0x001000}})
img:save_to_png_file('/User/Media/1ferver/res/转换后_测试图像.png')
假设我们有图像,想要只获取图像内的 0x007700
,并且绿色色偏0x10,也就是0x006700
-0x008700
。
local img = image.load_file('/User/Media/1ferver/res/测试图像.png')
img = img:binaryzation({{0x007700,0x001000}})
img:save_to_png_file('/User/Media/1ferver/res/转换后_测试图像.png')
假设我们有一个需要识别的金额,已知字体颜色是白色(0xffffff),其它内容直接抛弃即可。
local img = image.load_file('/User/Media/1ferver/res/测试图像.png')
img = img:binaryzation({{0x00ff00,0x001000}})
img:save_to_png_file('/User/Media/1ferver/res/转换后_测试图像.png')
发现转换后的图像很细小,需要加大相似度(0x404040)。
而且后面还有一个点,需要图像再次切割。
则重新修改识别方式。
local img = image.load_file('/User/Media/1ferver/res/测试图像.png')
img = img:crop(42,14,191,36) --截取图像
img = img:binaryzation({{0xffffff,0x404040}})
img:save_to_png_file('/User/Media/1ferver/res/转换后_测试图像.png')
Google Tesseract(最初是由惠普开发,后面交由Google维护),现在几乎大多数识别都是使用这个引擎来实现的OCR,Tesseract是开源的,而且本身就包含了很多种语言模型的训练结果,如果不是有特别的需求(比如手写的不规则字体),几乎就是开箱就用的效果。
PS:因大漠识别在手机端的识别是柔滑的,可能每个字都会有1个像素的偏差效果不理想
tess_ocr函数
img:tess_ocr([{
lang = 语言,
white_list = 白名单,
black_list = 黑名单
}])
我们识别只需要识别的是数字部分("0123456789")。
local img = image.load_file('/User/Media/1ferver/res/测试图像.png')
img = img:crop(42,14,191,36) --截取图像
img = img:binaryzation({{0xffffff,0x404040}})
img:save_to_png_file('/User/Media/1ferver/res/转换后_测试图像.png')
local text = img:tess_ocr({
lang = "eng",
white_list = "0123456789"
})
nLog(text)
我们可以看到日志得到了1000
字符。
因或许涉及到几个问题
则就要使用一下方法
利用string内的match来匹配数字local r = string.match(text,"%d+")
可以得到数字部分。但是如果字符串不存在数字则 r 的值就变为 nil。
加强写法local r = string.match(text .. ' 0','%d+')
当结果为空白内容,则匹配出末尾的0。
最后tonumber
记得加上
以下是我制作的针对游戏金额的识别
-- 当识别结果正确则返回 number 类型的数值
-- 当识别结果失败则返回 number 类型的 -1
-- 识别 0 这种数值能正常处理
function get_money()
local img = screen.image(100,200,300,300)
img = img:crop(42,14,191,36) --截取图像
img = img:binaryzation({{0xffffff,0x404040}})
local text = img:tess_ocr({
lang = "eng",
white_list = "0123456789"
})
local text = (text .. ' 0000000'):match('%d+')
if text == '0000000' then
return -1
else
return tonumber(text)
end
end