找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 4493|回复: 13

【书籍原创】《我的眼睛--图灵识别》海报及文章内容

[复制链接]

2

主题

31

回帖

525

积分

用户组: 大·技术宅

UID
4699
精华
0
威望
4 点
宅币
345 个
贡献
139 次
宅之契约
0 份
在线时间
26 小时
注册时间
2019-2-18
发表于 2019-2-22 11:31:24 | 显示全部楼层 |阅读模式
本帖最后由 鱼头之王 于 2020-4-29 12:51 编辑

《我的眼睛--图灵识别》图像识别领域的基础入门

需要有一点的计算机编程基础(基于VB6、按键精灵),图文并茂,深入原理;适合业余感兴趣的AI人工智能图像识别的初学者入门。

适用于AI人工智能图形图像、颜色和文字识别行业相关的领域作为学习参考。读完本书,您一定会受益匪浅、脑洞大开的!

CSDN博客:https://blog.csdn.net/onedabian


图书宣传海报:
宣传海报.PNG

●专注图色文字识别
●全彩共有十三章节
●图文并茂原理易懂
●三门编程语言源码

VB6、按键精灵2014
●三步识别入门基础
颜色识别、图片识别、形状识别
●带十三套图像滤镜
彩色图像滤镜:二值化、灰度、色调分离
黑白图像滤镜:清除杂点、去掉直线、获取轮廓、提取色块、倾斜矫正、旋转纠正、颠倒颜色、膨胀腐蚀
图像通用滤镜:等比缩放、缩放归一化
●五种字符切割技术
固定位置、随机方位、连通区域、范围投影、颜色分层
●十个实战演练范例
文字类识别:标准数字、重叠数字、波浪数字、错位文字、中文选题
图像类识别:与众不同、面朝方向、清晰图像
图形类识别:箭头朝向、寻找圆心
●三篇识别分析理论
扭曲变形、旋转方向、滑块拼图

附源码,含配套教材。


【学习咨询:加群460472698/314452472】回答:是


目录.png

知识树.PNG

图书内容页2.png

图书内容页3.PNG

单选投票, 共有 3 人参与投票
33.33% (1)
0.00% (0)
66.67% (2)
您所在的用户组没有投票权限
回复

使用道具 举报

2

主题

31

回帖

525

积分

用户组: 大·技术宅

UID
4699
精华
0
威望
4 点
宅币
345 个
贡献
139 次
宅之契约
0 份
在线时间
26 小时
注册时间
2019-2-18
 楼主| 发表于 2019-2-22 12:25:44 | 显示全部楼层
开篇


        揭开面纱,不再神秘;
        图文并茂,深入原理;
        需要有一点的计算机编程基础,至少熟悉任意一门编程语言,适用于AI人工智能领域的机器人、图形图像、颜色和文字识别相关行业作为学习参考。
        附源码包含:VB6.0、按键精灵2014和VS2015(C/C++)。

        本书所授内容为个人独创,市面上也是独一无二的,可谓无价之宝。内容步骤详细,图文并茂,是一本值得珍藏的AI人工智能领域的图像与文字识别的图书,请您一定要好好珍惜保存。在实际应用过程中一定要懂的活学活用,一定要多思考,举一反三。
        可应用于手机号数字识别、数字倒计时识别、PDF文档文字识别、办公扫描件文字识别、名片文字识别、工业工件造型识别与数量定位、车牌号码识别、公共场所形象标志物识别等等。


回复

使用道具 举报

2

主题

31

回帖

525

积分

用户组: 大·技术宅

UID
4699
精华
0
威望
4 点
宅币
345 个
贡献
139 次
宅之契约
0 份
在线时间
26 小时
注册时间
2019-2-18
 楼主| 发表于 2019-2-22 12:29:15 | 显示全部楼层
本帖最后由 鱼头之王 于 2019-2-22 12:30 编辑

引言

      本人艺校专业室内设计,职位产品经理/首席设计师,对艺术具有一定的天赋,动手动脑能力都很强。从2004年开始接触编程,因为心里只想着做一个业余的编程爱好者,不同的编程语言逻辑流程、语法结构也都是相通的,所以挑选了最简单的VB6.0做为主要入门的学习编程语言,足以用于平时日常的兴趣开发。
      我本人非常喜欢研究AI人工智能领域的图像与文字识别相关技术,但是迫于没有进阶到高等数学的学习过程,在很大程度上限制了图像识别算法的编写,在本书中所讲到的内容都是基于本人潜心多年的个人自行理解领悟所发挥出来的成果积累,但极小部分内容来源于互联网。
      验证图形码识别,听起来好像很高端、大气、上档次,而且还很厉害的样子。对于一些技术宅来说,这种技术还是非常神秘的,而且他们也非常想知道电脑程序是怎么编写代码实现识别的?实现识别原理有哪些?
      身边很多的大部分朋友则都会认为,我这一辈子也学不会了。
      真的是这样吗?
      真是这样的吗?
      验证图形码识别这项工作并不适合心情浮躁的人,它需要有一点的编程基础并有足够的耐心、冷静和细心。适合业余感兴趣的AI人工智能图像识别的初学者入门,请您一定要耐心且认真的读完本书,您一定会受益匪浅、脑洞大开的,一辈子也忘不了,原来就这么简单啊!

      对了,在学习知识升级过程中,当您学会了相应的章节就会获得对应的“图灵师”称号奖励哦~




      编者
回复

使用道具 举报

2

主题

31

回帖

525

积分

用户组: 大·技术宅

UID
4699
精华
0
威望
4 点
宅币
345 个
贡献
139 次
宅之契约
0 份
在线时间
26 小时
注册时间
2019-2-18
 楼主| 发表于 2019-2-25 09:50:34 | 显示全部楼层
第三章:基础:颜色识别

1.png
七色彩虹

漂亮的彩虹是一种光学现象,使用三棱透镜进行折射就能看到七色彩虹。它分别由红、橙、黄、绿、青、蓝、紫7种颜色组成。色彩按字面含义上理解可分为色和彩,色是指人对进入眼睛的光并传至大脑时所产生的感觉;彩则指多色的意思,是人对光变化的理解。

1、颜色描述
颜色是通过光射向物体产生了反射光,不同光的波长和强度对肉眼产生刺激,引起视觉神经和中枢神经反应,大脑接收到相应的信号后,通过日常文化认识作出语义上的定义。
自然界的色彩是十分复杂的,我们处在一个五彩斑斓的世界中,日常口语化中描述的颜色不足以准确表达出我们想要的颜色,例如红色?要再亮一点?再深一点?这种模棱两可的描述在编程中将会是一种灾难问题,所以我们需要通过准确的术语来表示具体的一种颜色。
原色的一个概念性词汇,指由不同的颜色(原色)组合形成更多颜色。在不同的场景中,原色的构成并不一样。

光学三原色
在光学中,一般认为红色、绿色和蓝色是一组原色,又称为光学三原色,是一种叠加型原色。这是由于人类拥有的三种视锥细胞对红光、绿光和蓝光最为敏感。通过不同比例的红绿蓝颜色叠加,可以使人看到各种颜色。例如红色与绿色混合产生黄色或橙色,绿色和蓝色混合产生青色,蓝色和红色混合产生紫色或品红色。当这三种颜色等比例叠加到一起时会变成灰色,如果将三种颜色饱和度均调至最大时则呈现白色。电视机、摄像机、计算机和手机显示屏等都是运用了光学三原色原理。

2.png
(RGB)红绿蓝三原色

颜料三原色
在印刷、绘画等情况下,一般认为青色、洋红色和黄色是一组原色,又称为美术三原色,是一种消减型原色。例如黄色和青色混合产生绿色,黄色和洋红色混合产生红色,洋红色和青色混合产生蓝色。当这三种等比例混合时呈现灰色,如果将饱和度调至最大,理论上会呈现黑色,但是实际上由于颜料的原因会呈现出浊褐色。因此,在印刷技术上加入了第四种原色——黑色,以弥补颜料三原色的不足。

   3.png
(CMYK)红黄蓝三原色


其他原色
除了以上两种常见的三原色外,还有一些其他的原色组,例如心理原色中采用蓝色、黄色、红色、绿色、橙色和紫色这六种心理原色加上黑白两色,形成了色彩感知。再例如天然彩色相片技术中采用橙色、绿色、紫色为三原色等。


回复

使用道具 举报

2

主题

31

回帖

525

积分

用户组: 大·技术宅

UID
4699
精华
0
威望
4 点
宅币
345 个
贡献
139 次
宅之契约
0 份
在线时间
26 小时
注册时间
2019-2-18
 楼主| 发表于 2019-2-25 09:54:06 | 显示全部楼层
本帖最后由 鱼头之王 于 2019-2-25 09:55 编辑

2、色彩空间
随着技术的发展,各种各样的色彩空间被创造出来,有RGB、HSV(HSB)、HSL、CMYK等等。本书中只用到RGB和HSV色彩空间格式的颜色值。

RGB
光学三原色系统一般称为”RGB色彩空间“,也就是由红(Red:0~255)、绿(Green:0~255)、蓝(Blue:0~255)所组合呈现的色彩系统。它的几何空间模型是一个正方体,由3个向量构成,空间中每一个点都表示一个颜色。在这个空间中,可以通过以下几种不同的数值来准确描述一个点的颜色。

1.png
RGB色彩空间模型

RGB色彩总共能组合出约1678万种色彩,即三个分量最大值进行相乘256×256×256=16777216。通常被简称为1600万色或千万色,也称为24位色(2的24次方)。
虽然RGB色彩空间适合用在各种显示屏上,但是它的色彩描述并不适合人类理解,因为我们的眼睛无法识别出一个颜色中红蓝绿三者的比重大小。例如RGB色彩描述为“BB5280”表示什么颜色?一般只有通过查询才能知道这个颜色长啥样。


颜色互补色
        色彩中的互补色有红色与青色互补、蓝色与黄色互补、绿色与品红色互补等等。在光学三原色中指两种颜色以适当的比例混合而能产生白色时,则这两种颜色就称为“互为补色”,比如:RGB(255,0,0)和RGB(0,255,255),就是说它们的每个分量值分别加起来后能够等于255。

2.png
互补色


HSV(HSB)
由于RGB色彩空间描述不适合人类理解,我们看颜色一般是通过对颜色的色相、饱和度、明度来识别的,故在此基础上引申出了另一种新的模型结构——HSV色彩空间,这种模型是采取圆柱坐标系的方法进行构建。HSV即色相(Hue)、饱和度(Saturation)、明度(Value),又称为HSB,其中B的英文是Brightness。

3.png
HSV色彩空间模型

色相(H)是色彩的颜色描述,例如平时说的红色、蓝色等,取值0~360。
饱和度(S)是指色彩的纯度,饱和度越高,颜色越鲜艳,饱和度变低时,颜色逐渐变暗淡,取值范围是0~100%。
明度(V)是指颜色的亮度,越高越亮,越低越暗,取值范围是0~100%。


颜色转换
什么时候需要进行颜色转换?
一般情况下,通过RGB色彩空间来查找颜色是够用的,但是当遇到一些颜色随时间或天气变化而产生一些不同,例如乌云变浓变淡、白天变亮、夜晚变暗等,RGB色彩空间就显得很局限了,这时候就需要引入HSV色彩空间来解决这个问题。
HSV色彩空间可以通过肉眼直观的描述来定义某一个颜色。比如一块红色的纸张,正常情况下看到的是标准的红色;当白天被阳光照射后,看到的是粉红色;到了夜晚光线变暗,看到的是枣红色。

4.png
变化的红色

VB6代码:

  1. 调用例子:
  2. Dim iHSV As HSV, iRGB As RGB
  3. iHSV =RGB转HSV(255, 0, 0)
  4. MsgBox iHSV.Hue& "," &iHSV.Saturation & "," &iHSV.Value

  5. iRGB =HSV转RGB(0, 100, 100)
  6. MsgBox iRGB.Red& "," &iRGB.Green& "," & iRGB.Blue


  7. 封装函数:
  8. Public Type HSV
  9.     Hue As Integer
  10.     Saturation As Integer
  11.     Value As Integer
  12. End Type
  13. Public Type RGB
  14.     Red As Integer
  15.     Green As Integer
  16.     Blue As Integer
  17. End Type

  18. Private Function Max(c1 As Single, c2 As Single) As Single
  19.     If c1 > c2 Then
  20.         Max = c1
  21.     Else
  22.         Max = c2
  23.     End If
  24. End Function
  25. Private Function Min(c1 As Single, c2 As Single) As Single
  26.     If c1 > c2 Then
  27.         Min = c2
  28.     Else
  29.         Min = c1
  30.     End If
  31. End Function


  32. '转换RGB到HSV
  33. Public Function RGB转HSV(ByVal R As Integer, ByVal G As Integer, ByVal b As Integer) As HSV
  34. Dim nH As Single, nS As Single, nV As Single
  35. Dim nR As Single, nG As Single, nB As Single
  36. Dim ndelR As Single, ndelG As Single, ndelB As Single
  37. Dim nmax As Single, nmin As Single, ndelMax As Single
  38.     nR = R / 255
  39.     nG = G / 255
  40.     nB = b / 255
  41.     nmax = Max(Max(nR, nG), nB)
  42.     nmin = Min(Min(nR, nG), nB)
  43.     ndelMax = nmax - nmin
  44.     nV = nmax
  45.     If (ndelMax = 0) Then
  46.         nH = 0
  47.         nS = 0
  48.     Else
  49.         nS = ndelMax / nmax
  50.         ndelR = (((nmax - nR) / 6) + (ndelMax / 2)) / ndelMax
  51.         ndelG = (((nmax - nG) / 6) + (ndelMax / 2)) / ndelMax
  52.         ndelB = (((nmax - nB) / 6) + (ndelMax / 2)) / ndelMax
  53.         If (nR = nmax) Then
  54.             nH = ndelB - ndelG
  55.         ElseIf (nG = nmax) Then
  56.             nH = (1 / 3) + ndelR - ndelB
  57.         ElseIf (nB = nmax) Then
  58.             nH = (2 / 3) + ndelG - ndelR
  59.         End If
  60.         If (nH < 0) Then nH = nH + 1
  61.         If (nH > 1) Then nH = nH - 1
  62.     End If
  63.     RGB转HSV.Hue = nH * 360
  64.     RGB转HSV.Saturation = nS * 100
  65.     RGB转HSV.Value = nV * 100
  66. End Function

  67. '转换HSV到RGB
  68. Public Function HSV转RGB(ByVal h As Integer, ByVal s As Integer, ByVal v As Integer) As RGB
  69. Dim nH As Single, nS As Single, nV As Single
  70. Dim nR As Single, nG As Single, nB As Single
  71. Dim hi As Single, f As Single, p As Single, q As Single, t As Single
  72.     nH = h / 360
  73.     nS = s / 100
  74.     nV = v / 100
  75.     If (s = 0) Then
  76.         nR = nV * 255
  77.         nG = nV * 255
  78.         nB = nV * 255
  79.     Else
  80.         hi = nH * 6
  81.         If (hi = 6) Then hi = 0
  82.         f = Int(hi)
  83.         p = nV * (1 - nS)
  84.         q = nV * (1 - nS * (hi - f))
  85.         t = nV * (1 - nS * (1 - (hi - f)))
  86.         If (f = 0) Then
  87.             nR = nV
  88.             nG = t
  89.             nB = p
  90.         ElseIf (f = 1) Then
  91.             nR = q
  92.             nG = nV
  93.             nB = p
  94.         ElseIf (f = 2) Then
  95.             nR = p
  96.             nG = nV
  97.             nB = t
  98.         ElseIf (f = 3) Then
  99.             nR = p
  100.             nG = q
  101.             nB = nV
  102.         ElseIf (f = 4) Then
  103.             nR = t
  104.             nG = p
  105.             nB = nV
  106.         Else
  107.             nR = nV
  108.             nG = p
  109.             nB = q
  110.         End If
  111.     End If
  112.     HSV转RGB.Red = nR * 255
  113.     HSV转RGB.Green = nG * 255
  114.     HSV转RGB.Blue = nB * 255
  115. End Function
复制代码




按键精灵2014脚本:
  1. 调用例子:
  2. //色相(H)、饱和度(S)、明度(V)
  3. //下面这句是把16进制颜色("0000FF")转换分解到10进制(H, S, V)分量中
  4. Call Plugin.TULING.RGBtoHSV("0000FF",H,S,V)
  5. MessageBox H & "," & S & "," &V

  6. hColor=Plugin.TULING.HSVtoRGB(0,100,100)
  7. MessageBox hColor
复制代码



回复

使用道具 举报

2

主题

31

回帖

525

积分

用户组: 大·技术宅

UID
4699
精华
0
威望
4 点
宅币
345 个
贡献
139 次
宅之契约
0 份
在线时间
26 小时
注册时间
2019-2-18
 楼主| 发表于 2019-2-25 09:59:58 | 显示全部楼层
本帖最后由 鱼头之王 于 2019-2-25 10:02 编辑

3、获取颜色

屏幕坐标系
在生活中,我们要去某一个地方,需要知道详细的地址,例如人民路168号1栋608房间。而在我们屏幕中,如果要知道某一个点的具体位置时,就可以利用坐标这个概念来描述。
屏幕坐标就是表示一个点在固定分辨率屏幕上的位置数值。当一个屏幕的分辨率是1920*1080大小时,屏幕坐标最左上角的点坐标就是(0,0),屏幕最右下角的坐标就是(1919,1079),因为0到1919一共有1920个数字,正好对应1920个点,垂直方向也一样。屏幕上任意一个点都有唯一的坐标,所以我们就通过坐标来表达某个点所在的位置。
屏幕坐标系是以屏幕最左上角为起点的坐标系,从左往右为X轴方向(范围在0~1919),从上往下为Y轴方向(范围在0~1079),凡超出这个范围值的为越界,用户在屏幕上就无法看到。这就跟我们数学中的十字坐标系非常相似,两者唯一区别是y轴的方向是相反的。

1.png
屏幕坐标系
       
获取指定坐标点颜色
屏幕上显示着各种各样的颜色,这对我们写条件时经常要用到的颜色判断,要想知道屏幕上的某个位置颜色是否发生变化,就需要对指定位置的颜色进行获取,之后才能对获取的颜色值进行相应的判断操作。
直接通过“鱼鱼抓点抓色“工具(或者其他第三方工具)进行获取当前鼠标下坐标点的颜色或者输入指定屏幕坐标来获取颜色。当然也可以调用微软API的GetPixel函数对指定屏幕坐标进行颜色的获取。

2.png
鼠标位置颜色

3.png
指定坐标颜色

你们有没有这样的怀疑过,取色判断跟图像识别应该没有任何关系的吧?
其实,在日常生活中大家都是有体验过的,对吧?没有吗?

4.png
红绿灯

日常生活中最容易见到的就是“红绿灯”啦,开车的看到红灯就会停车,对吧?
你看到的这些根据人眼判断的就是一种识别,只是你没有意识到而已,对不对?这个就是根据一种颜色来判断,一种最简单的识别方法。
那么我们可以说,颜色判断就是一种最最基础的图像识别方法。
但是,有的时候,我们无法单纯的只靠一种颜色来识别,因为这样会很容易出现识别错误,比如:看到红色的广告牌就认为是红灯吗?此时就需要大范围内的多种颜色一起进行判断,就是我们经常说的多点找色(多点找色也是找图的一种形态,详情查阅:04基础:图片识别)。


VB6代码:
  1. 调用例子:
  2. Dim 颜色 As String
  3. 颜色 = 来源_获取屏幕位置颜色(100, 200)
  4. MsgBox 颜色



  5. 封装函数:
  6. Public Function 来源_获取屏幕位置颜色(x As Long, y As Long) As String
  7. Dim WindowDC As Long, 颜色 As String
  8.     On Error GoTo ErrLine
  9.     WindowDC = GetDC(0)    '获取全屏幕场景
  10.     颜色 = GetPixel(WindowDC, x, y)    '取场景中(x, y)坐标的颜色
  11.     ReleaseDC 0, WindowDC    '释放场景
  12.     来源_获取屏幕位置颜色 = Right("000000" & UCase(Hex(颜色)), 6)
  13.     Exit Function
  14. ErrLine:
  15.     来源_获取屏幕位置颜色 = ""
  16. End Function
复制代码




按键精灵2014脚本:
  1. 调用例子:
  2. 颜色 = Plugin.TULING.GetPixelColor(100, 200)
  3. TracePrint 颜色
复制代码




获取屏幕像素
仅仅通过一个个指定坐标点来获取屏幕上的所有颜色,遍历效率那是超级的慢,简直是在浪费生命,我们希望的是能够一次性的快速获取屏幕上的所有颜色。使用微软API提供的BitBlt和GetDIBits函数,就能够很轻松的一次性获取屏幕指定区域范围内的所有像素点的颜色数据。

VB6代码:

  1. 调用例子:
  2. Dim 图像数据() As Byte
  3. Call 来源_获取屏幕像素(0, 0, 200, 100, 图像数据)

  4. 封装函数:
  5. Public Sub 来源_获取屏幕像素(左 As Long, 上 As Long, 右 As Long, 下 As Long, 返回图像数据() As Byte)
  6. Dim Temp图像数据() As Byte, bi24BitInfo As BitMapInfo
  7. Dim 宽 As Long, 高 As Long
  8.     宽 = 右 - 左 + 1    '图像宽度
  9.     高 = 下 - 上 + 1    '图像高度
  10.     ReDim Temp图像数据(3, 宽 - 1, 高 - 1) As Byte
  11.     With bi24BitInfo.bmiHeader
  12.         .biBitCount = Bits
  13.         .biCompression = 0&
  14.         .biPlanes = 1
  15.         .biSize = Len(bi24BitInfo.bmiHeader)
  16.         .biWidth = 宽
  17.         .biHeight = -高    '显示正常图像
  18.     End With
  19.     Dim hWndDesk As Long, IdSource As Long, iDC As Long, iBitmap As Long
  20.     hWndDesk = GetDesktopWindow()
  21.     IdSource = GetDC(hWndDesk)    '获取屏幕场景
  22.     iDC = CreateCompatibleDC(IdSource)    '创建兼容场景
  23.     iBitmap = CreateDIBSection(iDC, bi24BitInfo, 0, 0, 0, 0)    '创建DIB场景
  24.     Call SelectObject(iDC, iBitmap)    '复原兼容DC数据
  25.     Call BitBlt(iDC, 0, 0, 宽, 高, IdSource, 左, 上, vbSrcCopy)   '拷贝图像 (半透明窗体:&H40CC0020)
  26.     Call GetDIBits(iDC, iBitmap, 0, 高, Temp图像数据(0, 0, 0), bi24BitInfo, 0)    '获得图像数据
  27.     Call DeleteDC(iDC)    '删除句柄
  28.     Call DeleteObject(iBitmap)    '删除对象
  29.     Call ReleaseDC(hWndDesk, IdSource)    '释放场景
  30.     返回图像数据 = Temp图像数据
  31. End Sub
复制代码



按键精灵2014脚本:
  1. 调用例子:
  2. Call Plugin.TULING.Pixel_FromScreen(0,0,200,100)
  3. //显示获取的图像
  4. Call Plugin.TULING.Pixel_Preview()
复制代码


回复

使用道具 举报

2

主题

31

回帖

525

积分

用户组: 大·技术宅

UID
4699
精华
0
威望
4 点
宅币
345 个
贡献
139 次
宅之契约
0 份
在线时间
26 小时
注册时间
2019-2-18
 楼主| 发表于 2019-2-25 10:05:09 | 显示全部楼层
4、颜色的查找识别

考虑到不同的电脑分辨率大小就会有所不同,需要找的目标(颜色)出现的位置可能会不一样,我们并不知道它在屏幕上是在具体的哪个位置,如果要想找到它,可以通过对屏幕上的颜色数据进行一一遍历和判断,这样就能知道所要找的目标颜色在屏幕上的位置是哪个坐标值,进而找到它。
下面举个例子,如何利用颜色找到电脑桌面上的“计算机”图标?

1.png
(Win7)计算机

首先,打开鱼鱼抓色工具,勾选或按热键【Alt+~】启动取色功能,把鼠标移动到“我的电脑”图标的淡绿色点上(其实选择其它任意颜色点也是可以的)。

2.png
启动取色功能

然后,按下热键【Alt+~】停止取色。这样,就完成了“计算机”图标的颜色获取。

3.png
抓取到颜色值

接下来,就能够在屏幕区域(左边:0, 上边:0, 右边:1919, 下边:1079)范围内使用16进制的颜色值“00FF6B”进行查找,最终返回找到的颜色在屏幕上的具体坐标值。
需要特别注意的是,要查找的颜色必须在指定的区域范围内。

4.png
在屏幕上的具体坐标值

颜色查找方向
在指定区域范围内查找颜色时,一般默认的情况下是从左上到右下的方式进行遍历,如果你要找的颜色刚好在右下角时,还用这种方向进行遍历就会浪费很多时间,这个时候你就可以对查找方向的参数进行设置,使其为从右下到左上的方式进行遍历。以下提供了8种遍历方式。

5.png
颜色查找方向

7.png
问题:
如何进行多个颜色(红、黄、蓝)查找识别,并返回每个颜色的坐标?

6.png
(作业)多个颜色查找


VB6代码:
  1. 调用例子:
  2. Dim FoundX As Long, FoundY As Long, 颜色 As String
  3. 颜色 = "0000FF"
  4. Call 查找_屏幕区域找单色(0, 0, 1024, 768, 颜色, 0, 1, FoundX, FoundY)
  5. Debug.Print FoundX, FoundY    '输出找到的坐标


  6. 封装函数:
  7. 'Call 查找_屏幕区域找单色(
  8. '       区域左边:长整数,
  9. '       区域上边:长整数,
  10. '       区域右边:长整数,
  11. '       区域下边:长整数,
  12. '       查找颜色:字符串,
  13. '       查找方向:整数[0-从左上往右下;1-从左下往右上;2-从右上往左下;3-从右下往左上,4-从上左往下右;5-从上右往下左;6-从下左往上右;7-从下右往上左],
  14. '       颜色相似度:单精度[0.5到1之间;1为精确匹配],
  15. '       输出找到的x坐标:整型变量,
  16. '       输出找到的y坐标:整型变量
  17. '               )
  18. Public Sub 查找_屏幕区域找单色(左 As Long, 上 As Long, 右 As Long, 下 As Long, 颜色值 As String, 查找方向 As Integer, 相似度 As Single, FoundX As Long, FoundY As Long)
  19. Dim 结果x As Long, 结果y As Long
  20.     结果x = -1
  21.     结果y = -1
  22.     'On Error GoTo 结束
  23.     '1.截取屏幕图片信息
  24.     Dim 屏幕像素数据() As Byte
  25.     Call 来源_获取屏幕像素(左, 上, 右, 下, 屏幕像素数据)
  26.     '2.相似度计算
  27.     Dim 颜色相似度 As Long, flag As Boolean
  28.     颜色相似度 = (1 - 相似度) * 255
  29.     '3.拆解颜色值分量
  30.     Dim 颜色 As Long, Red As Byte, Green As Byte, Blue As Byte
  31.     颜色 = CLng("&H" & 颜色值)
  32.     Red = 颜色 Mod 256: Green = (颜色 \ 256) Mod 256: Blue = 颜色 \ 256 \ 256
  33.     '4.颜色的查找识别
  34.     Dim x As Long, y As Long, 宽 As Long, 高 As Long
  35.     宽 = 右 - 左 - 1
  36.     高 = 下 - 上 - 1
  37.     flag = False
  38.     Select Case 查找方向
  39.     Case 0    '从左到右,从上到下.顺序
  40.         For y = 0 To 高: For x = 0 To 宽
  41.                 If 颜色相似度 = 0 Then
  42.                     If 屏幕像素数据(2, x, y) = Red And 屏幕像素数据(1, x, y) = Green And 屏幕像素数据(0, x, y) = Blue Then
  43.                         flag = True: GoTo 结束
  44.                     End If
  45.                 Else
  46.                     If 颜色相似度判断(屏幕像素数据(2, x, y), 屏幕像素数据(1, x, y), 屏幕像素数据(0, x, y), _
  47.                             Red, Green, Blue, 颜色相似度) = True Then
  48.                         flag = True: GoTo 结束
  49.                     End If
  50.                 End If
  51.             Next: Next
  52.     Case 1    '从左到右,从下到上.顺序
  53.         For y = 高 To 0 Step -1: For x = 0 To 宽
  54.                 If 颜色相似度 = 0 Then
  55.                     If 屏幕像素数据(2, x, y) = Red And 屏幕像素数据(1, x, y) = Green And 屏幕像素数据(0, x, y) = Blue Then
  56.                         flag = True: GoTo 结束
  57.                     End If
  58.                 Else
  59.                     If 颜色相似度判断(屏幕像素数据(2, x, y), 屏幕像素数据(1, x, y), 屏幕像素数据(0, x, y), _
  60.                             Red, Green, Blue, 颜色相似度) = True Then
  61.                         flag = True: GoTo 结束
  62.                     End If
  63.                 End If
  64.             Next: Next
  65.     Case 2    '从右到左,从上到下.顺序
  66.         For y = 0 To 高: For x = 宽 To 0 Step -1
  67.                 If 颜色相似度 = 0 Then
  68.                     If 屏幕像素数据(2, x, y) = Red And 屏幕像素数据(1, x, y) = Green And 屏幕像素数据(0, x, y) = Blue Then
  69.                         flag = True: GoTo 结束
  70.                     End If
  71.                 Else
  72.                     If 颜色相似度判断(屏幕像素数据(2, x, y), 屏幕像素数据(1, x, y), 屏幕像素数据(0, x, y), _
  73.                             Red, Green, Blue, 颜色相似度) = True Then
  74.                         flag = True: GoTo 结束
  75.                     End If
  76.                 End If
  77.             Next: Next
  78.     Case 3    '从右到左,从下到上.顺序
  79.         For y = 高 To 0 Step -1: For x = 宽 To 0 Step -1
  80.                 If 颜色相似度 = 0 Then
  81.                     If 屏幕像素数据(2, x, y) = Red And 屏幕像素数据(1, x, y) = Green And 屏幕像素数据(0, x, y) = Blue Then
  82.                         flag = True: GoTo 结束
  83.                     End If
  84.                 Else
  85.                     If 颜色相似度判断(屏幕像素数据(2, x, y), 屏幕像素数据(1, x, y), 屏幕像素数据(0, x, y), _
  86.                             Red, Green, Blue, 颜色相似度) = True Then
  87.                         flag = True: GoTo 结束
  88.                     End If
  89.                 End If
  90.             Next: Next
  91.     Case 4    '从上到下,从左到右.顺序
  92.         For x = 0 To 宽: For y = 0 To 高
  93.                 If 颜色相似度 = 0 Then
  94.                     If 屏幕像素数据(2, x, y) = Red And 屏幕像素数据(1, x, y) = Green And 屏幕像素数据(0, x, y) = Blue Then
  95.                         flag = True: GoTo 结束
  96.                     End If
  97.                 Else
  98.                     If 颜色相似度判断(屏幕像素数据(2, x, y), 屏幕像素数据(1, x, y), 屏幕像素数据(0, x, y), _
  99.                             Red, Green, Blue, 颜色相似度) = True Then
  100.                         flag = True: GoTo 结束
  101.                     End If
  102.                 End If
  103.             Next: Next
  104.     Case 5    '从上到下,从右到左.顺序
  105.         For x = 宽 To 0 Step -1: For y = 0 To 高
  106.                 If 颜色相似度 = 0 Then
  107.                     If 屏幕像素数据(2, x, y) = Red And 屏幕像素数据(1, x, y) = Green And 屏幕像素数据(0, x, y) = Blue Then
  108.                         flag = True: GoTo 结束
  109.                     End If
  110.                 Else
  111.                     If 颜色相似度判断(屏幕像素数据(2, x, y), 屏幕像素数据(1, x, y), 屏幕像素数据(0, x, y), _
  112.                             Red, Green, Blue, 颜色相似度) = True Then
  113.                         flag = True: GoTo 结束
  114.                     End If
  115.                 End If
  116.             Next: Next
  117.     Case 6    '从下到上,从左到右.顺序
  118.         For x = 0 To 宽: For y = 高 To 0 Step -1
  119.                 If 颜色相似度 = 0 Then
  120.                     If 屏幕像素数据(2, x, y) = Red And 屏幕像素数据(1, x, y) = Green And 屏幕像素数据(0, x, y) = Blue Then
  121.                         flag = True: GoTo 结束
  122.                     End If
  123.                 Else
  124.                     If 颜色相似度判断(屏幕像素数据(2, x, y), 屏幕像素数据(1, x, y), 屏幕像素数据(0, x, y), _
  125.                             Red, Green, Blue, 颜色相似度) = True Then
  126.                         flag = True: GoTo 结束
  127.                     End If
  128.                 End If
  129.             Next: Next
  130.     Case 7    '从下到上,从右到左.顺序
  131.         For x = 宽 To 0 Step -1: For y = 高 To 0 Step -1
  132.                 If 颜色相似度 = 0 Then
  133.                     If 屏幕像素数据(2, x, y) = Red And 屏幕像素数据(1, x, y) = Green And 屏幕像素数据(0, x, y) = Blue Then
  134.                         flag = True: GoTo 结束
  135.                     End If
  136.                 Else
  137.                     If 颜色相似度判断(屏幕像素数据(2, x, y), 屏幕像素数据(1, x, y), 屏幕像素数据(0, x, y), _
  138.                             Red, Green, Blue, 颜色相似度) = True Then
  139.                         flag = True: GoTo 结束
  140.                     End If
  141.                 End If
  142.             Next: Next
  143.     End Select
  144. 结束:
  145.     If flag = True Then
  146.         结果x = x + 左
  147.         结果y = y + 上
  148.     End If
  149.     FoundX = 结果x
  150.     FoundY = 结果y
  151. End Sub

  152. Private Function 颜色相似度判断(屏幕R As Byte, 屏幕G As Byte, 屏幕B As Byte, _
  153.         图片R As Byte, 图片G As Byte, 图片B As Byte, 阈值 As Long) As Boolean
  154.     If _
  155.             Abs(CLng(屏幕R) - 图片R) <= 阈值 And _
  156.             Abs(CLng(屏幕G) - 图片G) <= 阈值 And _
  157.             Abs(CLng(屏幕B) - 图片B) <= 阈值 Then
  158.         颜色相似度判断 = True
  159.     Else
  160.         颜色相似度判断 = False
  161.     End If
  162. End Function
复制代码


按键精灵2014脚本:
  1. 调用例子:
  2. Dim x, y, 颜色
  3. 颜色 = "0000FF"
  4. Call Plugin.TULING.FindColor(0, 0, 1024, 768, 颜色, 0, 1, x, y)
  5. TracePrint x & "," & y    //输出找到的坐标
复制代码

回复

使用道具 举报

2

主题

31

回帖

525

积分

用户组: 大·技术宅

UID
4699
精华
0
威望
4 点
宅币
345 个
贡献
139 次
宅之契约
0 份
在线时间
26 小时
注册时间
2019-2-18
 楼主| 发表于 2019-2-25 10:14:00 | 显示全部楼层
第五章:基础:形状识别

1、图形认识
三角形
三角形是由同一平面内不在同一直线上的三条线段‘首尾’顺次连接所组成的封闭图形。
三角形按边分有不等边、等腰和等边三角形;按角分有直角、锐角和钝角三角形等,其中锐角和钝角三角形统称斜三角形。
周长公式:周长 = a + b + c
面积公式:面积 = 底(任意边) * 高(h) / 2


1.png
不等边、等腰和等边三角形

2.png
锐角、直角和钝角三角形


矩形(四边形)
至少有三个内角都是直角的四边形是矩形,有一个内角是直角的平行四边形是矩形,对角线相等的平行四边形是矩形。矩形是一种特殊的平行四边形,正方形是特殊的矩形。矩形也叫长方形。
周长公式:周长 = 2 * (a + b)
面积公式:面积 = a * b


3.png
长方形、正方形和菱形


多边形
由三条或三条以上的线段‘首尾’顺次连接所组成的平面图形叫做多边形。多边形可以分为正多边形和非正多边形、凸多边形及凹多边形。
组成多边形的线段至少有3条,三角形是最简单的多边形。组成多边形的每一条线段叫做多边形的边;相邻的两条线段的公共端点叫做多边形的顶点;连接多边形的两个不相邻顶点的线段叫做多边形的对角线。

4.png
正凸多边形和非正凸多边形

5.png
正凹多边形和非正凹多边形


圆形(椭圆形)
在一个平面内,一动点以一定点为中心,以一定长度为距离旋转一周所形成的封闭曲线叫做圆,这个定点叫做圆的圆心。
圆是一种几何图形。圆是轴对称、中心对称图形。对称轴是直径所在的直线。同时,圆又是“正无限多边形”,而“无限”只是一个概念。当多边形的边数越多时,其形状、周长、面积就都越接近于圆。所以,世界上没有真正的圆,圆实际上只是概念性的图形。
椭圆形比圆形长,比圆形扁,椭圆形是由圆形变成的长圆形。椭圆是围绕两个焦点的平面中的曲线,使得对于曲线上的每个点,到两个焦点的距离之和是恒定的。因此,它是圆的概括,其是具有两个焦点在相同位置处的特殊类型的椭圆。
圆形周长公式:周长 = 2 * 3.14 * r
圆形面积公式:面积 = (3.14 * r ) ^ 2
椭圆形周长公式:周长 = (r / R) * (r + R)
椭圆形面积公式:面积 = 3.14 * a * b



6.png
圆形、椭圆形和同心圆

回复

使用道具 举报

2

主题

31

回帖

525

积分

用户组: 大·技术宅

UID
4699
精华
0
威望
4 点
宅币
345 个
贡献
139 次
宅之契约
0 份
在线时间
26 小时
注册时间
2019-2-18
 楼主| 发表于 2019-2-25 10:20:42 | 显示全部楼层
2、多边形识别
多边形识别(Find Shape)包含三角形、多边形、矩形和圆形的识别。主要识别的核心算法思路是统计形状的顶点数量和线段数量,根据筛选规则识别得到对应的形状图形。
数据统计筛选识别规则分别为:有3个顶点和3条线段的组成为三角形,有 4个顶点和至少3条线段以上的组成为多边形,有4个顶点和4条线段的组成为矩形,有4个顶点和0条线段的组成为圆形。

1.png
(核心算法)多边形

人眼在识别形状的时候速度是非常快的,因为线条简单。但是电脑程序要实现形状识别就需要用到很多的数学几何公式。看似简单做起来却很难,要识别二维物体的形状需要以下的几个步骤:

2.png
识别步骤

第1步,获取像素
使用“来源_获取图片像素()”的函数命令(封装了微软提供的LoadImage和GetBitmapBits等API函数)根据图片文件的路径进行图像数据的像素获取。(详情查阅:04基础:图片识别->像素获取)

3.png
(预览)图像数据

第2步,滤镜处理
二值化
因为准备的示例图已经是黑白的图像,所以这里暂时不需要进行二值化等图像滤镜的处理。在之后章节的复杂图像识别上会有详细的介绍。(详情查阅:07预处理:图像滤镜->彩色图像滤镜->二值化)

第3步,定位区域
获取顶点
相邻的两条线段的公共端点叫做多边形的顶点。
首先对图形的显示区域进行定位,分别使用从上往下从左往右的方式进行遍历找出左边的边界、从左往右从下往上的方式进行遍历找出下边的边界、从下往上从右往左的方式进行遍历找出右边的边界和从右往左从上往下的方式进行遍历找出上边的边界,这样就得到的图形的显示区域和对应4个方向的边界值。

4.png
左边界

5.png
下边界

6.png
右边界

8.png
上边界

9.png
显示区域

然后再确定顶点的数量,规则为根据设定2个顶点之间的最小距离大于一定的阈值时则认为是2个顶点(注意看圆形的边界线比较长,这里设定的阈值为15像素距离)。因为图像通过二值化处理后,存在有锯齿或一小段线条的情况会影响顶点数量的计算,此过程主要是去除计算时的干扰。最终才能得到二维图形的有效顶点数量。

10.png
圆形的边界线比较长

11.png
有效顶点

获取线段
组成多边形的每一条边叫做线段。要确定是否为线段,道理很简单,只需要计算2个顶点之间直线上的白色点数达到一定的数量后(这里设定的阈值为15像素长度),则为判定为有效线段。

12.png
(绿色)有效线段

获取2个顶点之间直线上的所有像素点的坐标采用的是,直线的斜截式方程:y=kx+b,其中k是直线的斜率,b是直线在y轴上的截距。该方程叫做直线的斜截式方程,简称斜截式。此斜截式类似于一次函数的表达式。

13.png
直线方程式

第4步,进行识别
形状特征统计
接下来,只需要根据前面获得的顶点数量和线段数量,针对不同的形状进行不同的判定条件,即可完成图形的识别。
首先,判断线段数量小于2时则为圆形。
然后,判断顶点数量等于线段数量同时等3时则为三角形,同时等4时则为矩形。
最后,判断顶点数量大于线段数量且都大于4时则为多边形。

14.png
三角形

15.png
多边形

16.png
矩形

17.png
圆形

7.png
问题:
分别识别找出直线段和曲线段的数量。(可以使用之后章节的切割函数)

18.png
(作业)直线段和曲线段


VB6代码:
  1. 调用例子:
  2. Dim 图像数据() As Byte
  3. '1.获取
  4. Call 来源_获取图片像素("C:\未命名.bmp", 图像数据)
  5. '2.识别
  6. Dim 识别形状 As String, 距离 As Long, 长度 As Long
  7. 距离 = 15    '顶点距离
  8. 长度 = 15    '线段长度
  9. 识别形状 = 形状比对(图像数据, 距离, 长度)
  10. MsgBox 识别形状


  11. 封装函数:
  12. '识别
  13. Public Function 形状比对(图像数据() As Byte, 顶点距离 As Long, 线条长度 As Long) As String
  14. Dim w As Long, h As Long, 宽 As Long, 高 As Long
  15. Dim x As Long, y As Long, 顶点() As 坐标结构, i As Long, Point As Long, bo As Boolean
  16.     宽 = UBound(图像数据, 2)
  17.     高 = UBound(图像数据, 3)
  18.     i = 0
  19.     '按顺序 找出4个边界上的顶点,根据阈值筛选是否为2个点
  20.     '找出左边所有顶点
  21.     For w = 0 To 宽
  22.         Point = 0
  23.         bo = False
  24.         For h = 0 To 高
  25.             If 图像数据(2, w, h) = 255 Then
  26.                 If bo = False Then    '找到白色点
  27.                     bo = True    '记录开关
  28.                     ReDim Preserve 顶点(i) As 坐标结构    '第1个点
  29.                     顶点(i).x = w
  30.                     顶点(i).y = h
  31.                     i = i + 1
  32.                 End If
  33.                 Point = Point + 1    '记录白色点数
  34.             ElseIf 图像数据(2, w, h) = 0 And bo = True Then
  35.                 If Point > 顶点距离 Then    '筛选是否为第2个点
  36.                     ReDim Preserve 顶点(i) As 坐标结构
  37.                     顶点(i).x = w
  38.                     顶点(i).y = h
  39.                     i = i + 1
  40.                 End If
  41.                 Exit For
  42.             End If
  43.         Next
  44.         If bo = True Then Exit For
  45.     Next
  46.         If i = 0 Then 形状比对 = "":  Exit Function
  47.     '找出下边所有顶点
  48.     For h = 高 To 0 Step -1
  49.         Point = 0
  50.         bo = False
  51.         For w = 0 To 宽
  52.             If 图像数据(2, w, h) = 255 Then
  53.                 If bo = False Then    '找到白色点
  54.                     bo = True    '记录开关
  55.                     If 顶点(i - 1).x <> w And 顶点(i - 1).y <> h Then    '排除重叠顶点
  56.                         ReDim Preserve 顶点(i) As 坐标结构    '覆盖前面的点记录
  57.                         顶点(i).x = w
  58.                         顶点(i).y = h
  59.                         i = i + 1
  60.                     End If
  61.                 End If
  62.                 Point = Point + 1    '记录白色点数
  63.             ElseIf 图像数据(2, w, h) = 0 And bo = True Then
  64.                 If Point > 顶点距离 Then    '筛选是否为第2个点
  65.                     ReDim Preserve 顶点(i) As 坐标结构
  66.                     顶点(i).x = w
  67.                     顶点(i).y = h
  68.                     i = i + 1
  69.                 End If
  70.                 Exit For
  71.             End If
  72.         Next
  73.         If bo = True Then Exit For
  74.     Next
  75.     '找出右边所有顶点
  76.     For w = 宽 To 0 Step -1
  77.         Point = 0
  78.         bo = False
  79.         For h = 高 To 0 Step -1
  80.             If 图像数据(2, w, h) = 255 Then
  81.                 If bo = False Then    '找到白色点
  82.                     bo = True    '记录开关
  83.                     If 顶点(i - 1).x <> w And 顶点(i - 1).y <> h Then    '排除重叠顶点
  84.                         ReDim Preserve 顶点(i) As 坐标结构    '覆盖前面的点记录
  85.                         顶点(i).x = w
  86.                         顶点(i).y = h
  87.                         i = i + 1
  88.                     End If
  89.                 End If
  90.                 Point = Point + 1    '记录白色点数
  91.             ElseIf 图像数据(2, w, h) = 0 And bo = True Then
  92.                 If Point > 顶点距离 Then    '筛选是否为第2个点
  93.                     ReDim Preserve 顶点(i) As 坐标结构
  94.                     顶点(i).x = w
  95.                     顶点(i).y = h
  96.                     i = i + 1
  97.                 End If
  98.                 Exit For
  99.             End If
  100.         Next
  101.         If bo = True Then Exit For
  102.     Next
  103.     '找出上边所有顶点
  104.     For h = 0 To 高
  105.         Point = 0
  106.         bo = False
  107.         For w = 宽 To 0 Step -1
  108.             If 图像数据(2, w, h) = 255 Then
  109.                 If bo = False Then    '找到白色点
  110.                     bo = True    '记录开关
  111.                     If 顶点(i - 1).x <> w And 顶点(i - 1).y <> h Then    '排除重叠顶点
  112.                         ReDim Preserve 顶点(i) As 坐标结构    '覆盖前面的点记录
  113.                         顶点(i).x = w
  114.                         顶点(i).y = h
  115.                         i = i + 1
  116.                     End If
  117.                 End If
  118.                 Point = Point + 1    '记录白色点数
  119.             ElseIf 图像数据(2, w, h) = 0 And bo = True Then
  120.                 '最后的点不为记录,因为返回到了起点
  121.                 Exit For
  122.             End If
  123.         Next
  124.         If bo = True Then Exit For
  125.     Next
  126.     '按顺序 计算 当前点和下一个点的 直线上 的点数是否满足一定的阈值,为线条
  127.     Dim n As Long, m As Long, k As Long, 线条数量 As Long, 顶点数量 As Long
  128.     Dim xx() As Long, yy() As Long
  129.     n = UBound(顶点)
  130.     顶点数量 = n + 1
  131.     线条数量 = 0
  132.     For i = 0 To n
  133.         If i = n Then
  134.             Call 取直线上所有坐标(顶点(i).x, 顶点(i).y, 顶点(0).x, 顶点(0).y, xx, yy)
  135.         Else
  136.             Call 取直线上所有坐标(顶点(i).x, 顶点(i).y, 顶点(i + 1).x, 顶点(i + 1).y, xx, yy)
  137.         End If
  138.         m = UBound(xx)
  139.         Point = 0
  140.         For k = 0 To m
  141.             If 图像数据(2, xx(k), yy(k)) = 255 Then
  142.                 Point = Point + 1
  143.             End If
  144.         Next
  145.         If Point > 线条长度 Then
  146.             线条数量 = 线条数量 + 1
  147.         End If
  148.     Next
  149.     '判断线条数量 和 顶点数量  最终得到 形状识别
  150.     If 线条数量 > 2 Then
  151.         If 顶点数量 > 线条数量 Then
  152.             形状比对 = "多边形"
  153.         Else
  154.             If 顶点数量 = 线条数量 Then
  155.                 If 线条数量 = 3 Then
  156.                     形状比对 = "三角形"
  157.                 ElseIf 线条数量 = 4 Then
  158.                     形状比对 = "矩形(四边形)"
  159.                 Else
  160.                     形状比对 = "多边形"
  161.                 End If
  162.             End If
  163.         End If
  164.     Else
  165.         形状比对 = "圆形(椭圆形)"
  166.     End If
  167. End Function




  168. Public Type 坐标结构
  169.     x As Long
  170.     y As Long
  171. End Type

  172. '直线方程为:y = k * x + b
  173. Public Sub 取直线上所有坐标(x1 As Long, y1 As Long, x2 As Long, y2 As Long, x() As Long, y() As Long)
  174. Dim b As Double, k As Double, nx As Long, ny As Long
  175. Dim TempX() As Long, TempY() As Long, i As Long
  176.     nx = Abs(x1 - x2)
  177.     ny = Abs(y1 - y2)
  178.     If nx >= ny Then
  179.         ReDim TempX(nx) As Long, TempY(nx) As Long
  180.         For i = 0 To nx - 1
  181.             k = (y2 - y1) / ((x2 - x1) + 0.000001)    '加个极小数,防止除0情况
  182.             b = y1 - k * x1
  183.             If x2 <= x1 And y2 <= y1 Then
  184.                 TempX(i) = x1 + i - nx
  185.                 TempY(i) = k * (x1 + i) + b - ny
  186.             ElseIf x2 < x1 And y2 > y1 Then
  187.                 TempX(i) = x1 + i - nx
  188.                 TempY(i) = k * (x1 + i) + b + ny
  189.             Else
  190.                 TempX(i) = x1 + i
  191.                 TempY(i) = k * (x1 + i) + b
  192.             End If
  193.         Next
  194.     Else
  195.         ReDim TempX(ny) As Long, TempY(ny) As Long
  196.         For i = 0 To ny - 1
  197.             k = (y2 - y1) / ((x2 - x1) + 0.000001)    '加个极小数,防止除0情况
  198.             b = y1 - k * x1
  199.             If x2 <= x1 And y2 <= y1 Then
  200.                 TempX(i) = (y1 + i - b) / k - nx
  201.                 TempY(i) = y1 + i - ny
  202.             Else
  203.                 TempX(i) = (y1 + i - b) / k
  204.                 TempY(i) = y1 + i
  205.             End If
  206.         Next
  207.     End If
  208.     x = TempX
  209.     y = TempY
  210. End Sub
复制代码




按键精灵2014脚本:
  1. 调用例子:
  2. Call Plugin.TULING.Pixel_FromPicture("C:\图形.bmp")
  3. //显示获取的图像
  4. Call Plugin.TULING.Pixel_Preview()
  5. shape=Plugin.TULING.FindShape(15,15)
  6. TracePrint shape
复制代码

回复

使用道具 举报

2

主题

31

回帖

525

积分

用户组: 大·技术宅

UID
4699
精华
0
威望
4 点
宅币
345 个
贡献
139 次
宅之契约
0 份
在线时间
26 小时
注册时间
2019-2-18
 楼主| 发表于 2019-2-25 10:24:23 | 显示全部楼层
第六章:基础:验证图形码识别

1、什么是识别
识别的意思是辨认、辨别、区分,分辨识别真假。对事物或现象进行描述、辨认、分类和解释的过程。
我们人的眼睛随便看到一个物体,就能知道它是什么东西,这是为什么呢?当然也会有不认识的事物时,仅进行归类方式代替。这里就会得到这样一个现象,要认识一个物体需要事先有人告诉它是什么或者自己临时给予定义了一个新名字,这样就能够识别它们是什么。
当你看到一辆车时,就能知道它是车。因为车有它独有的识别特征,那就是圆形的轮子,没有轮子的都不是车。当然,你就不要再钻牛角尖的问我为什么轮子是圆形的了?

1.png
(谷歌)无人驾驶汽车

7.png
问题:
怎么从表面上去区分一个人是男的还是女的?他们独有的识别特征是什么?

2.png
(作业)区分男女

2、什么是相似度
利用公式计算分析比较两条序列的相似性并设定一个阈值即为相似度。相似度是一个数值,反映两条序列的相似程度,如:人类与黑猩猩DNA基因相似度达99%。

3.png
相似程度

3、颜色相似度
很多时候我们需要在程序中判断一个颜色是否与指定的另一个颜色相似,例如用户选择了一个红色(16进制:0101FF,10进制:66047),这个红色与标准的纯红色(16进制:0000FF,10进制:255)是很接近的,肉眼根本区分不出来,但颜色值还是有一点点的差别。

4.png
相似颜色

怎样判断它们的两个颜色是否相似呢?这里就需要用到相似度的设置(RGB:0~255),即设置两个颜色在RGB空间的距离值(色差),这个值就是所谓的颜色相似度。
简单的做法就是判断两颜色RGB分量值的差值(绝对值)符合设定的相似度的值,当3个分量值同时满足则就符合颜色相似,条件表达式如下:

Abs(R1 - R2) <相似度And Abs(G1 - G2) <相似度And Abs(B1 - B2) <相似度


不仅可以使用颜色RGB分量值来判断颜色相似,也可以使用颜色HSV分量值的上限和下限的范围来判断颜色相似,条件表达式如下:

Abs(H1 - H2) <相似度And Abs(S1 - S2) <相似度And Abs(V1 - V2) <相似度



4、点数相似度
判断2张图的颜色匹配数量,符合预设的点数范围内,则即为满足点数相似。这个预设的点数就是百分比点数相似度,通常用来判断一个字符和字库比对识别时的百分比条件。
例如,当点数相似度百分比设置为85时,在比对识别时匹配的点数符合这个百分比条件的则为字符识别成功。

5.png
点数比对识别
回复

使用道具 举报

2

主题

31

回帖

525

积分

用户组: 大·技术宅

UID
4699
精华
0
威望
4 点
宅币
345 个
贡献
139 次
宅之契约
0 份
在线时间
26 小时
注册时间
2019-2-18
 楼主| 发表于 2019-2-25 10:30:05 | 显示全部楼层
第七章:预处理:图像滤镜


什么是滤镜?
滤镜就好比是一种药物,医生会针对不同情况的病人开不一样的药方,这样才能做到对症下药解决问题。一般是指针对数字图像的某种数学处理,比如:二值化、灰度、色调分离、清除杂点、获取轮廓、缩放及各种数据变换等等。
图像滤镜预处理是指在进行文字识别之前的一些准备工作,主要目的是突出图像上字符的有关信息,去掉原始图像中的显见噪声(干扰)等影响识别的无关信息。这一阶段的工作非常重要,处理的效果直接影响到文字识别的准确率。

1.png
对症下药

1、彩色图像滤镜
二值化
二值化(Binaryzation)即所谓的图像仅有两种的颜色存在,如:黑白图像,就是将一张彩色图像上的每个像素点(px)的颜色RGB分量值根据一定的阈值条件分别设置为0或255数值,也就是将整张图像呈现出明显的仅有黑色(背景)和白色(目标字符)的视觉效果。

2.png
二值化图像

1.利用RGB分量的平均值作为阈值条件:
当颜色RGB分量值的总和除以3,大于预设置的阈值128时,等于白色(16进制:FFFFFF,10进制:16777215),否则等于黑色(16进制:000000,10进制:0)。
白色 = (R + G + B) / 3 > 128
黑色 = (R + G + B) / 3 < 128

这样,就完成了对图像的二值化滤镜处理,呈现出明显的仅有黑色和白色的视觉效果。


3.png
滤镜效果

4.png
实现流程

        5.png
       
VB6代码:
  1. 调用例子:
  2. Dim 滤镜图像() As Byte
  3. Call 滤镜_二值化_Average(图像数据, 128, 滤镜图像)

  4. 封装函数:
  5. '阈值 = 128
  6. Public Sub 滤镜_二值化_Average(图像数据() As Byte, 阈值 As Long, 返回滤镜图像() As Byte)
  7. Dim w As Long, h As Long, 宽 As Long, 高 As Long, 平均值 As Long
  8. Dim R As Byte, G As Byte, B As Byte
  9.     宽 = UBound(图像数据, 2)
  10.     高 = UBound(图像数据, 3)
  11.     For w = 0 To 宽
  12.         For h = 0 To 高
  13.             '为阈值条件
  14.             R = 图像数据(2, w, h)
  15.             G = 图像数据(1, w, h)
  16.             B = 图像数据(0, w, h)
  17.             平均值 = (CLng(R) + G + B) / 3
  18.             If 平均值 > 阈值 Then
  19.                 '为白色
  20.                 图像数据(0, w, h) = 255
  21.                 图像数据(1, w, h) = 255
  22.                 图像数据(2, w, h) = 255
  23.             Else
  24.                 '为黑色
  25.                 图像数据(0, w, h) = 0
  26.                 图像数据(1, w, h) = 0
  27.                 图像数据(2, w, h) = 0
  28.             End If
  29.         Next
  30.     Next
  31.     返回滤镜图像 = 图像数据
  32. End Sub
复制代码



按键精灵2014脚本:
  1. 调用例子:
  2. Call Plugin.TULING.Pixel_FromScreen(0,0,200,100)
  3. //显示获取的图像
  4. Call Plugin.TULING.Pixel_Preview()
  5. Call Plugin.TULING.Filter_Binaryzation("0-128")    //二值化
  6. Call Plugin.TULING.Pixel_Preview()
复制代码





2.利用选取多个颜色值作为阈值条件:
可以直接通过拾取图像中所有文字上的颜色值作为阈值条件,符合其中某一个文字的颜色值时等于白色(16进制:FFFFFF,10进制:16777215),否则即为黑色(16进制:000000,10进制:0)。
拾取图像中的文字颜色值分别为:
数字0        (16进制:E1AC46,10进制:14789702)
数字5        (16进制:6465F2,10进制:6579698)
数字9        (16进制:AA5F61,10进制:11165537)
数字1        (16进制:47C280,10进制:4702848)



6.png
滤镜效果

8.png
实现流程

         
9.png


7.png
问题:
如何实现多值化滤镜处理效果?
比如实现三值化:黑(0,0,0),白(255,255,255),灰(127,127,127)。

10.png
(作业)三值化

VB6代码:
  1. 调用例子:
  2. Dim 滤镜图像() As Byte
  3. Dim 颜色串(2) As Long
  4. 颜色串(0) = 16777215
  5. 颜色串(1) = 0
  6. 颜色串(2) = 255
  7. Call 滤镜_二值化_Picker(图像数据, 颜色串,滤镜图像)


  8. 封装函数:
  9. Public Sub 滤镜_二值化_Picker(图像数据() As Byte, 颜色串() As Long, 返回滤镜图像() As Byte)
  10. Dim w As Long, h As Long, 宽 As Long, 高 As Long, 查找颜色 As Long, 数量 As Long, n As Long
  11. Dim R As Byte, G As Byte, B As Byte
  12.     宽 = UBound(图像数据, 2)
  13.     高 = UBound(图像数据, 3)
  14.     数量 = UBound(颜色串)
  15.     For w = 0 To 宽
  16.         For h = 0 To 高
  17.             '为阈值条件
  18.             R = 图像数据(2, w, h)
  19.             G = 图像数据(1, w, h)
  20.             B = 图像数据(0, w, h)
  21.             查找颜色 = RGB(R, G, B)
  22.             '为黑色
  23.             图像数据(0, w, h) = 0
  24.             图像数据(1, w, h) = 0
  25.             图像数据(2, w, h) = 0
  26.             For n = 0 To 数量
  27.                 If 查找颜色 = 颜色串(n) Then
  28.                     '为白色
  29.                     图像数据(0, w, h) = 255
  30.                     图像数据(1, w, h) = 255
  31.                     图像数据(2, w, h) = 255
  32.                     Exit For
  33.                 End If
  34.             Next
  35.         Next
  36.     Next
  37.     返回滤镜图像 = 图像数据
  38. End Sub
复制代码



按键精灵2014脚本:
  1. 调用例子:
  2. Dim 颜色串
  3. Call Plugin.TULING.Pixel_FromScreen(0,0,200,100)
  4. //显示获取的图像
  5. Call Plugin.TULING.Pixel_Preview()
  6. 颜色串 = "FF0000|00FF00|0000FF|"
  7. Call Plugin.TULING.Filter_Binaryzation(颜色串)    //二值化
  8. Call Plugin.TULING.Pixel_Preview()
复制代码

回复

使用道具 举报

2

主题

31

回帖

525

积分

用户组: 大·技术宅

UID
4699
精华
0
威望
4 点
宅币
345 个
贡献
139 次
宅之契约
0 份
在线时间
26 小时
注册时间
2019-2-18
 楼主| 发表于 2019-2-25 10:34:58 | 显示全部楼层
第八章:训练:图像字符切割
图像字符切割是把图像上的每个文字分割成独立的单个字符,这是识别最有效的基础。
字符分割是图像识别最关键的一步,因为分割的正确与否直接关系到最后的结果,如果4个字符分割成了3个,即便后面的识别算法识别率达到100%,结果也是错的。当然,前面预处理如果做得够好,干扰因素能够有效的去除,而没有影响到字符的像素点(px),那么对分割来讲就容易得多。反过来,如果前面的干扰因素都没有去除掉,那么分割出来的可能就不是字符了。
字符的黏连是分割的难点,这一点也可以作为验证图形码安全系数的标准,如果图像上的几个字符完全是分开的,那么可以保证字符分割成功率是百分之百的,这样识别的难度就降低了很多。
图像字符切割的方法很多,比如:滴水分岭、水平垂直投影、离散聚类、傅里叶变换、八皇后、泛水填充、直方图和扫描线等等,这些都太专业了,不一般的人不用学,一般的人又学不会,至少我现在还都不会懂的玩:)


1、固定位置
固定位置(Fixed Location)切割方法就是,首先确定图像上的首个字符左上角的位置作为起始点坐标,并设置宽度和高度组成单个字符的切割范围,再确定切割的字符数量,即可进行准确定位切割出每个同等大小的独立字符。
主要适用于图像中的字符都是固定位置的,而且字与字之间还必须是间距相等的。

1.png
(等间距)固定位置切割

这是最基础的、最简单的和最粗暴的一种字符切割方法,它会无视字符黏连、位置错乱和干扰因素等等,但无法保证切割出来的字符是完整性的,有可能会出现少一部分或者多一部分数据的情况。

2.png
固定位置切割情况

等间距的图像字符如何进行固定位置切割?
具体操作步骤如下:
第1步,首先找到图像上的每个字与字之间的间隔距离,只需要对同大小或同个字符的左边位置进行距离计算即可;

3.png
原始图片

4.png
字之间的间距尺

第2步,之后在不变距离的情况下调整间距尺的位置,使其每个字符的最左边不能留有像素做到刚好对齐,这样就能确定每个字符最左边的位置;

5.png
字符最左边的位置

第3步,再找到所有字符的最上边和最下边的位置,就完成了高度范围的确定;

6.png
确定高度范围

第4步,此时已经能够得到首个字符的左上角的位置,完成了起点坐标的确定;

8.png
每个字符左上角位置

第5步,接着设置每个字符需要切割的宽度和切割的字符数量;

9.png
字符宽度和数量

第6步,最后根据首个字符左上角位置的起点坐标(假设1,1)、字符的宽高(5px和8px)、字符的间距(6px)和字符的切割数量(8),最终就完成了固定位置的字符切割。

10.png
进行固定切割

11.png
切割完成的字符

固定位置切割方法优缺点也是非常的明显,就是不灵活太死板了。优点就是不需要去遍历定位切割范围的时间;缺点就是切割位置死板,切割大小和数量都是固定的。

12.png

7.png
问题:
如果存在双排字符的图像,如何进行固定位置切割?

13.png
(作业)双排字符

VB6代码:
  1. 调用例子:
  2. Dim 切割字符() As 切割类型
  3. Call 切割_固定位置(图像数据, 0, 0, 5, 8, 6, 4, 切割字符)


  4. 封装函数:
  5. Public Type 切割类型
  6.     宽 As Long
  7.     高 As Long
  8.     点阵 As String
  9. End Type

  10. Public Sub 切割_固定位置(图像数据() As Byte, 起点x As Long, 起点y As Long, 字宽 As Long, 字高 As Long, 字间距 As Long, 字数 As Long, 返回切割字符() As 切割类型)
  11. Dim w As Long, h As Long, 宽 As Long, 高 As Long
  12. Dim i As Long, x As Long, n As Long, 点数 As Long
  13. Dim 字库点阵() As 切割类型, 单个点阵() As String, 多个点阵() As String
  14.     宽 = UBound(图像数据, 2)
  15.     高 = UBound(图像数据, 3)
  16.     n = 字数 - 1
  17.     ReDim 字库点阵(n) As 切割类型
  18.     ReDim 单个点阵(字高 - 1) As String, 多个点阵(字宽 - 1) As String
  19.     x = 起点x
  20.     For i = 0 To n
  21.         For w = 0 To 字宽 - 1
  22.             If w + x > 宽 Then Exit For    '为数据越界处理
  23.             For h = 0 To 字高 - 1
  24.                 If h + 起点y > 高 Then Exit For    '为数据越界处理
  25.                 If 图像数据(0, w + x, h + 起点y) = 255 Then
  26.                     单个点阵(h) = 1
  27.                 Else
  28.                     单个点阵(h) = 0
  29.                 End If
  30.             Next
  31.             多个点阵(w) = Left(Join(单个点阵, "") & String(字高, "0"), 字高)    '拼接点阵
  32.         Next
  33.         点数 = 字宽 * 字高
  34.         字库点阵(i).宽 = 字宽
  35.         字库点阵(i).高 = 字高
  36.         字库点阵(i).点阵 = Left(Join(多个点阵, "") & String(点数, "0"), 点数)    '拼接点阵
  37.         x = x + 字间距
  38.     Next
  39.     返回切割字符 = 字库点阵
  40. End Sub
复制代码



按键精灵2014脚本:
  1. 调用例子:
  2. Call Plugin.TULING.Pixel_FromScreen(0,0,200,100)
  3. Call Plugin.TULING.Filter_Binaryzation("0-128")
  4. //显示获取的图像
  5. Call Plugin.TULING.Pixel_Preview()
  6. 数量=Plugin.TULING.Incise_FixedLocation(0,0,64,64,50,3)    //固定位置切割
  7. For i = 0 To 数量
  8.     Call Plugin.TULING.Incise_Preview(i)
  9. Next
复制代码

回复

使用道具 举报

2

主题

31

回帖

525

积分

用户组: 大·技术宅

UID
4699
精华
0
威望
4 点
宅币
345 个
贡献
139 次
宅之契约
0 份
在线时间
26 小时
注册时间
2019-2-18
 楼主| 发表于 2019-2-25 10:37:19 | 显示全部楼层
第十三章:研究:识别分析论

1、扭曲变形
扭曲变形(Twisted)在这里是指,图像上的字符每行像素数据被经过左右的移位产生扭曲的效果,已经不能对其进行正常的字符切割,需要通过图像扭正处理。

1.png
扭曲变形

在分析它的有效识别特征过程中,发现这个验证图形码是固定扭曲路线的方式,所以只要按照它的固定扭曲路线进行纠正即可。

2.png
扭曲路线纠正
       
当图像被扭正之后再继续分析,还会发现它的字间距是固定的,只是存在奇偶数位置上的字符出现固定的上下错位摆放,但对识别是没有任何影响的,也不需要进行水平位置的对齐处理。

3.png
间距固定

接下来进行二值化处理。只要根据颜色RGB分量值的平均值判断(阈值判断:大于等于200时为黑色,否则为白色),就能很容易得到与背景区分的二值化字符图像。(详情查阅:07预处理:图像滤镜->彩色图像滤镜->二值化)

4.png
二值化图像

得到起点位置坐标、数字宽高、字间距和文字数量之后,使用“切割_固定位置()”函数的切割方法进行切割,最终得到独立的字符图像数据。(详情查阅:08训练:图像字符切割->固定位置)

5.png
字符图像数据
回复

使用道具 举报

2

主题

31

回帖

525

积分

用户组: 大·技术宅

UID
4699
精华
0
威望
4 点
宅币
345 个
贡献
139 次
宅之契约
0 份
在线时间
26 小时
注册时间
2019-2-18
 楼主| 发表于 2019-2-25 10:44:51 | 显示全部楼层
本帖最后由 鱼头之王 于 2020-4-29 12:52 编辑

《我的眼睛--图灵识别》按键精灵

回复

使用道具 举报

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-4-19 01:51 , Processed in 0.054831 second(s), 38 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表