[关闭]
@chendbdb 2017-03-03T21:28:56.000000Z 字数 3027 阅读 2211

XXTouch图像识别

XXTouch

识别图像无非是识别游戏内的金额、验证码、提示文字这几项。
以下是几种可能需要识别的图像



当考虑到识别文字时,普通情况下分为这几个步骤

因机能以及复杂程度等原因,除过滤杂线杂点、图像二化会稍加讲解其它请使用云打码平台cloud_ocr

RGB色彩讲解

RGB 百度百科

0x123456

小提示:0xfffffff这里有7个f就是典型的溢出,0xff可以忽略高位的0也就是纯蓝色。

色彩 中文 颜色
0x000000 黑色 ████████
0xffffff 白色 ████████
0xff0000 红色 ████████
0x00ff00 绿色 ████████
0x0000ff 蓝色 ████████
0xffff00 黄色 ████████
0xff00ff 粉色 ████████
0x00ffff 青色 ████████

色偏

假设有一个颜色 0x334455 需要取这个色彩的相似度尽可能接近的色彩,就要使用到色偏。

如果区间可能在

那么色偏取值就是 0x331122

再假如一个点 0xffffff 取这个

这部分不需要强行计算,手动调整数值尝试即可。

图像二化

顾名思义就是把正常的图像转换为纯黑白(仅两个色彩0xffffff,0x000000)图像。

这个步骤极其关键,因为会筛选出需要识别的以白色为基础色展示,其它则为黑色展示。

binaryzation函数

  1. img = img:binaryzation({
  2. {颜色值本身, 最大色差值},
  3. {颜色值本身, 最大色差值},
  4. ...
  5. })

测试1

测试图像

假设我们有图像,想要只获取图像内的绿色,并且绿色色偏0x10,也就是0x00ef00-0x00ff00

注意:超过0xff的则以0xff为准,同理低于0x0的则以0x0为准。

  1. local img = image.load_file('/User/Media/1ferver/res/测试图像.png')
  2. img = img:binaryzation({{0x00ff00,0x001000}})
  3. img:save_to_png_file('/User/Media/1ferver/res/转换后_测试图像.png')

转换后_测试图像

测试2

测试图像

假设我们有图像,想要只获取图像内的 0x007700,并且绿色色偏0x10,也就是0x006700-0x008700

  1. local img = image.load_file('/User/Media/1ferver/res/测试图像.png')
  2. img = img:binaryzation({{0x007700,0x001000}})
  3. img:save_to_png_file('/User/Media/1ferver/res/转换后_测试图像.png')

测试3

测试图像

假设我们有一个需要识别的金额,已知字体颜色是白色(0xffffff),其它内容直接抛弃即可。

  1. local img = image.load_file('/User/Media/1ferver/res/测试图像.png')
  2. img = img:binaryzation({{0x00ff00,0x001000}})
  3. img:save_to_png_file('/User/Media/1ferver/res/转换后_测试图像.png')

转换后_测试图像

发现转换后的图像很细小,需要加大相似度(0x404040)。
而且后面还有一个点,需要图像再次切割。
则重新修改识别方式。

  1. local img = image.load_file('/User/Media/1ferver/res/测试图像.png')
  2. img = img:crop(42,14,191,36) --截取图像
  3. img = img:binaryzation({{0xffffff,0x404040}})
  4. img:save_to_png_file('/User/Media/1ferver/res/转换后_测试图像.png')

转换后_测试图像

tesseract图像识别

Google Tesseract(最初是由惠普开发,后面交由Google维护),现在几乎大多数识别都是使用这个引擎来实现的OCR,Tesseract是开源的,而且本身就包含了很多种语言模型的训练结果,如果不是有特别的需求(比如手写的不规则字体),几乎就是开箱就用的效果。

PS:因大漠识别在手机端的识别是柔滑的,可能每个字都会有1个像素的偏差效果不理想

tess_ocr函数

  1. img:tess_ocr([{
  2. lang = 语言,
  3. white_list = 白名单,
  4. black_list = 黑名单
  5. }])

测试1

测试图像

转换后_测试图像

我们识别只需要识别的是数字部分("0123456789")。

  1. local img = image.load_file('/User/Media/1ferver/res/测试图像.png')
  2. img = img:crop(42,14,191,36) --截取图像
  3. img = img:binaryzation({{0xffffff,0x404040}})
  4. img:save_to_png_file('/User/Media/1ferver/res/转换后_测试图像.png')
  5. local text = img:tess_ocr({
  6. lang = "eng",
  7. white_list = "0123456789"
  8. })
  9. nLog(text)

我们可以看到日志得到了1000字符。

附录

因或许涉及到几个问题

则就要使用一下方法

利用string内的match来匹配数字local r = string.match(text,"%d+")可以得到数字部分。但是如果字符串不存在数字则 r 的值就变为 nil。

加强写法local r = string.match(text .. ' 0','%d+')当结果为空白内容,则匹配出末尾的0。

最后tonumber记得加上

以下是我制作的针对游戏金额的识别

  1. -- 当识别结果正确则返回 number 类型的数值
  2. -- 当识别结果失败则返回 number 类型的 -1
  3. -- 识别 0 这种数值能正常处理
  4. function get_money()
  5. local img = screen.image(100,200,300,300)
  6. img = img:crop(42,14,191,36) --截取图像
  7. img = img:binaryzation({{0xffffff,0x404040}})
  8. local text = img:tess_ocr({
  9. lang = "eng",
  10. white_list = "0123456789"
  11. })
  12. local text = (text .. ' 0000000'):match('%d+')
  13. if text == '0000000' then
  14. return -1
  15. else
  16. return tonumber(text)
  17. end
  18. end
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注