找回密码
 加入

AUTOIT CN

搜索
查看: 13163|回复: 75

[图形处理] 大漠最后免费版/阿福找图/MyImageSearchwithoutDLL竟然相差17.9倍(2016-3-2日晚更新)

[复制链接]
发表于 2016-2-20 20:55:19 | 显示全部楼层 |阅读模式
本帖最后由 love008 于 2016-3-2 20:28 编辑

此文向本坛阿福致敬!
因为有了阿福的代码,可以说AUTOIT更加强大!
此外,我用AUTOIT时间不长,阿福的代码核心算法_ArrayComp,_myReadBitmapMsg函数看不懂,所以也无限佩服阿福!
阿福似乎几年未来本坛了,有问题也不能找他请教了,可惜!

写此文的原因:
    因为之前用过按键精灵,但不喜欢他的收费模式,不喜欢他免费输出编译后生成的糟糕界面和主程序,不喜欢他的windows窗口获取与控制(AUTOIT的控件一行代码解决(按键有可能需要十多行代码),不喜欢他的广告......
    但按键精灵的抓抓取色是我经常用的,并且用来辅助AUIOIT,还有他的标题获取也是一个有用功能,能解决AU3一个我认为的BUG(这个改天开贴与大家讨论)

    找图是自动控制软件一个非常重要的功能,如果不用好这个功能,许多应用编程会无法解决,所以最近研究AU3找图功能,对比了一下"大漠DM.dll" "阿福找图"  "MyImageSearchwithoutDLL.au3"这三个找图方法的效率与优点缺点。
   原来本贴是写"大漠DM.dll"  "MyImageSearchwithoutDLL.au3"两个找图比较的,感谢“zch11230”提出研究一下阿福的代码,所以这段时间有空的测试,标题与内容会不断更新,大家见谅,也怪我没有系统想好写此文。

——————————————————————————————————————
优点比较:
"大漠DM.dll"
1、效率高
2、包含许多其它找图找色等等函数。

"阿福找图"
效率高,不需要其它库文件,32位,64位都兼容。

"MyImageSearchwithoutDLL.au3"
没有
——————————————————————————————————
缺点比较
"大漠DM.dll"
1、最后免费版是3.1233,最新是6.5**版(要收费),所以收费就没有人会用在AU3上。
2、需要大漠用C++写的库文件DM.dll,要注册,这样对AU生成的程序会在其它电脑上释放DM.DLL,会让其它人怀疑程序的安全性。
3、64位系统下可用,感谢“xin266”测试用regsvr32注册成功,首行加入#AutoIt3Wrapper_UseX64=no,如果不加运行时出现"Variable must be of type "Object".:",这是我之前出错的原因。

""阿福找图"
未发现

"MyImageSearchwithoutDLL.au3"
效率低
——————————————————————————

我的小低配置PC


测试思路:
1、在我的PC上,1152*864分辩率环境下找到SciTE编辑器上的打印机图标,并移动鼠标到图标上为成功,(截取SciTE编辑器上的打印机图标保持为@MyDocumentsDir & "\GDIPlus_Image1.bmp").

下面贴出三段各自找图的语法
(2016年3月1日测试发现之前的测试有误,因每次鼠标位置没有初始放在一相同位置导致时间差异大,所以统一用;号注释一下不用MOUSEMOVE,这样更准确找图时间。

1.大漠算法,用时55.2916641640208毫秒.
  1. Global $DM = ObjCreate("dm.dmsoft")
  2. $x=@DesktopWidth
  3. $y=@DesktopHeight
  4. Local $hTimer = TimerInit()
  5. $array=$DM.FindPicEX (0,0,$x,$y,@MyDocumentsDir & "\GDIPlus_Image1.bmp","000000",0.9,0)
  6. $array2=StringSplit ($array,",",2)
  7. ;MouseMove(Number($array2[1]),Number($array2[2]))
  8. ConsoleWrite(TimerDiff($hTimer)&@CRLF)
复制代码


2.调用MyImageSearchwithoutDLL.au3 UDF 718.335989629967毫秒
  1. #include <ScreenCapture.au3>
  2. #include<ImageSearchWithoutDLL.au3>
  3. Local $hTimer = TimerInit()
  4. $array=myImageSearch_Desktop(@MyDocumentsDir & "\GDIPlus_Image1.bmp", 0, 0, @DesktopWidth, @DesktopHeight, '',  true)
  5. ;MouseMove($array[0] ,$array[1] )
  6. ConsoleWrite(TimerDiff($hTimer)&@CRLF)
复制代码


3.用阿福代码找图,用时40.2757892413701毫秒

  1. #include<af_search_pic.au3>;包含阿福源代码文件到脚本中
  2. $t=TimerInit()
  3. search_pic (0,0, @DesktopWidth, @DesktopHeight,@MyDocumentsDir & "\GDIPlus_Image1.bmp") ;search_pic($x1,$y1,$x2,$y2,$pic)"当前屏幕找图",说明:$x1:屏幕上的左上角X坐标,$y1:屏幕上的左上角Y坐标,$x2:屏幕上的右下角X坐标,$y2:屏幕上的右下角Y坐标,$pic:要找图的路径及名称,$aPosMsg:返回坐标值(X坐标,Y坐标,长,高)
  4. If $aPosMsg<>"" Then
  5. $array=StringSplit ($aPosMsg,",",2)
  6. ;MouseMove($array[0],$array[1])
  7. ConsoleWrite(TimerDiff($t)&@CRLF)       
  8. EndIf
复制代码







2016年3月1日晚小总结:

1、阿福速度最好,大漠3.1233最后的免费版其次,MyImageSearchwithoutDLL.au3最慢,
阿福速度是MyImageSearchwithoutDLL.au3的17.95倍,大漠是MyImageSearchwithoutDLL.au3的13.05倍,阿福是大漠1.35倍。
2、大家测试时可以屏蔽MouseMove语句,这是最准确的.因为有MouseMove的话,除非三个测试运行之前的Mouse位置都一样,否则会有差异.


思考:最近准备测试两个大图720×576以上像素的找图测试,如果也能在40毫秒找到,会有更大的用途。

免费精神!
1.大漠DM.DLL  
2. 我改写了一下阿福的源代码变成屏幕找图函数调用(其中用;号了部份阿福的代码,调整效率),
复制进AutoIt3\Include目录   。
阿福的源代码感谢zch11230已经在楼下放出.大家研究
3.MyImageSearchwithoutDLL.au3本论坛有,自己搜索.

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?加入

x

评分

4

查看全部评分

发表于 2016-2-20 22:01:06 | 显示全部楼层
支持了,不错
发表于 2016-2-23 08:41:44 | 显示全部楼层
代码收了,正想要
发表于 2016-2-23 11:22:55 | 显示全部楼层
正在研究找图
发表于 2016-2-23 11:57:30 | 显示全部楼层
回复 1# love008
楼主,我创建不了大漠对象?已经注册大漠插件了!
 楼主| 发表于 2016-2-23 12:14:26 | 显示全部楼层
回复 5# wen
32位系统的话把dm. dll copy到system32目录,然后regsvr32 dm. dll注册。
然后
Global $DM = ObjCreate("dm.dmsoft")
    就是这句创建对象
发表于 2016-2-23 12:26:37 | 显示全部楼层
本帖最后由 zch11230 于 2016-2-23 12:40 编辑

楼主有没有试过阿福的找图代码啊,我现在电脑的配置可能比楼主的要好,用阿福的代码,找图部分用时30毫秒,加上载入图片一共110毫秒,大漠我用win10没有注册成功,MyImageSearchwithoutDLL我也没找到没法测试。
很多年前搞过,我印象中阿福的代码和大漠效率应该是差不多的,只是大漠可以定义模糊查询,比阿福的方便,阿福的当时我也改了一下,大多数情况下也可以实现模糊查询,但不完美,有空再研究看看。精确找图,阿福真的不错
 楼主| 发表于 2016-2-23 12:52:29 | 显示全部楼层
回复 7# zch11230
好的,抽空测试。
发表于 2016-2-23 14:01:52 | 显示全部楼层
回复 7# zch11230
我也win10,大漠也用不了,试一下阿福的!
发表于 2016-2-24 16:58:55 | 显示全部楼层
我这里测试相差十倍,估计是找图原理不一样。
发表于 2016-2-24 21:09:59 | 显示全部楼层
无限支持。。。。
发表于 2016-2-25 08:28:24 | 显示全部楼层
回复 7# zch11230


    共享下可以吗?
发表于 2016-2-25 10:30:00 | 显示全部楼层
回复 12# 骗子
Source.bmp源图片,Search.bmp需要搜索的图片

  1. #include <GdiPlus.au3>
  2. ;#include <myOcrFunc.au3>

  3. _GDIPlus_Startup ()

  4. $s_dir = @ScriptDir
  5. $hBitmap1 = _GDIPlus_BitmapCreateFromFile($s_dir & "\Source.bmp")
  6. $array1 = _myReadBitmapMsg($hBitmap1, 1)

  7. $hBitmap2 = _GDIPlus_BitmapCreateFromFile($s_dir & "\Search.bmp")
  8. $array2 = _myReadBitmapMsg($hBitmap2, 1)

  9. $iMax = _GDIPlus_ImageGetWidth ($hBitmap1) / _GDIPlus_ImageGetWidth ($hBitmap2)

  10. $t=TimerInit()
  11. $aPosMsg = _ArrayComp($array1, $array2, False, $iMax)
  12. ConsoleWrite("找到一个图片块用去时间:"&TimerDiff($t)&'毫秒,位置信息(为空未找到):'&$aPosMsg&@CRLF)

  13. $t=TimerInit()
  14. $aPosMsg = _ArrayComp($array1, $array2, True, $iMax)
  15. ConsoleWrite("找到所有图片块用去时间:"&TimerDiff($t)&'毫秒,位置信息(为空未找到):'&$aPosMsg&@CRLF)

  16. If $aPosMsg<>"" Then
  17.         Local $aPos, $i, $hGraphics = _GDIPlus_ImageGetGraphicsContext ($hBitmap1)
  18.         $aPosMsg = StringSplit($aPosMsg,"|",2)
  19.         For $i = 0 To UBound($aPosMsg)-1
  20.                 $aPos = StringSplit($aPosMsg[$i],",",2)
  21.                 _GDIPlus_GraphicsDrawRect($hGraphics, $aPos[0], $aPos[1], $aPos[2], $aPos[3])
  22.         Next
  23.         _GDIPlus_ImageSaveToFile($hBitmap1, $s_dir&"\Target.bmp")
  24.         _GDIPlus_GraphicsDispose ($hGraphics)
  25. EndIf

  26. _GDIPlus_ImageDispose ($hBitmap1)
  27. _WinAPI_DeleteObject ($hBitmap1)
  28. _GDIPlus_ImageDispose ($hBitmap2)
  29. _WinAPI_DeleteObject ($hBitmap2)
  30. _GDIPlus_ShutDown ()
  31. Exit

  32. ;一般来说,当$hBitmap2是小图时$iType=1, 较大时$iType=0, 如果已知$array2哪个元素进行搜索比较合理,直接指定为$iY
  33. Func _ArrayComp($array1, $array2, $SearchAll=False, $iMax=0, $iY=0, $iType=0)
  34.         Local $iExtended=0
  35.         If $iMax>0 And $iY=0 Then
  36.                 Local $t=TimerInit()
  37.                 Local $sBmpData1 = ""
  38.                 For $i = 0 To UBound($array1)-1;相当于_ArrayToString或_myReadBitmapMsg($hBitmap,0),但更快
  39.                         $sBmpData1 &= $array1[$i]
  40.                 Next;===>当多个$array2搜索时,这个内容考虑在udf外执行,_ArrayComp($sBmpData1, $array1, $array2, $SearchAll=False, $iMax=0, $iY=0, $iType=0)
  41.                 For $i = 0 To UBound($array2)-1
  42.                         If StringReplace($array2[$i], StringLeft($array2[$i],6),"")="" Then ContinueLoop
  43.                         Select
  44.                                 Case $iType = 0
  45.                                         $iY = $i
  46.                                         ExitLoop
  47.                                 #cs
  48.                                 Case $iType = 1 And Not @AutoItX64 ;pusofalse提供的多线程方法
  49.                                         ;该方法中映射文件到内容部分 $pBaseAddress 暂用本段代替
  50.                                         Local $tBuff = DllStructCreate("char ["&StringLen($sBmpData1)+1&"]")
  51.                                         DllStructSetData($tBuff, 1, $sBmpData1)
  52.                                         $pBaseAddress = DllStructGetPtr($tBuff)
  53.                                         ;[url]http://www.autoitx.com/thread-20592-1-3.html[/url]
  54.                                 #ce
  55.                                 Case Else
  56.                                         StringReplace($sBmpData1,$array2[$i],"",0, 1)
  57.                                         If $iExtended=0 Or $iExtended>@extended Then
  58.                                                 $iExtended=@extended
  59.                                                 If $iExtended=0 Then Return "";没有匹配的图块
  60.                                                 $iY = $i
  61.                                                 If $iExtended<=$iMax Then ExitLoop
  62.                                         EndIf
  63.                         EndSelect
  64.                 Next
  65.                 ConsoleWrite("获取最佳搜索串"&TimerDiff($t)&','&$iExtended&@CRLF)
  66.         EndIf

  67.         ;Local $t=TimerInit()
  68.         If UBound($array1)<UBound($array2) Then Return ""
  69.         Local $s_re="", $y, $y2, $iW2=StringLen($array2[$iY]), $iPos;, $iSearchPos
  70.         For $y = $iy To UBound($array1)-1
  71.                 $iPos = 0;$iSearchPos = 1
  72.                 While $y+UBound($array2)<=UBound($array1)
  73.                         $iPos = StringInStr($array1[$y], $array2[$iY], 1, 1, $iPos+1);$iPos = StringInStr($array1[$y], $array2[$iY], 1, 1, $iSearchPos)
  74.                         Select
  75.                         Case $iPos = 0
  76.                                 ContinueLoop(2)
  77.                         Case Mod($iPos-1,6)<>0 ;Or $y<$iy
  78.                                 ;$iSearchPos = $iPos+1
  79.                                 ContinueLoop
  80.                         EndSelect
  81.                         For $y2 = $iY To UBound($array2)-1
  82.                                 If StringMid($array1[$y+$y2-$iy], $iPos, $iW2)<>$array2[$y2] Then
  83.                                         ;$iSearchPos = $iPos+1
  84.                                         ContinueLoop(2)
  85.                                 EndIf
  86.                         Next
  87.                         For $y2 = 0 To $iY-1
  88.                                 If StringMid($array1[$y+$y2-$iy], $iPos, $iW2)<>$array2[$y2] Then
  89.                                         ;$iSearchPos = $iPos+1
  90.                                         ContinueLoop(2)
  91.                                 EndIf
  92.                         Next
  93.                         $s_re &= ($iPos-1)/6&','&$y-$iy&','&$iW2/6&','&UBound($array2)&"|"
  94.                         StringReplace($s_re,"|","")
  95.                         If (Not $SearchAll) Or ($iExtended>0 And @extended>=$iExtended) Then ExitLoop(2)
  96.                         ;$iSearchPos = $iPos+1
  97.                 WEnd
  98.         Next
  99.         If StringRight($s_re,1)="|" Then $s_re = StringTrimRight($s_re,1)
  100.         ;ConsoleWrite(TimerDiff($t)&@CRLF);18
  101.         Return $s_re
  102. EndFunc

  103. Func _myReadBitmapMsg($hBitmap, $iType=1);
  104.         Local $aBmpData[5]
  105.     $aBmpData[1] = _GDIPlus_ImageGetWidth ($hBitmap)
  106.     $aBmpData[2] = _GDIPlus_ImageGetHeight ($hBitmap)
  107.         Local $BitmapData = _GDIPlus_BitmapLockBits($hBitmap, 0, 0, $aBmpData[1], $aBmpData[2], $GDIP_ILMREAD, $GDIP_PXF24RGB)
  108.         $aBmpData[3] = Abs(DllStructGetData($BitmapData, "Stride"))
  109.         $aBmpData[4] = DllStructGetData($BitmapData, "Scan0");
  110.         _GDIPlus_BitmapUnlockBits($hBitmap, $BitmapData)
  111.         Local $tBuff, $iH
  112.         Switch $iType;已测试比StringRegExp快
  113.                 Case -1
  114.                         Return $aBmpData
  115.                 Case 0
  116.                         For $iH = 1 To $aBmpData[2]
  117.                                 $tBuff = DllStructCreate("byte[" & ($aBmpData[1]*3) & "]", $aBmpData[4] + ($iH-1)*$aBmpData[3])
  118.                                 $aBmpData[0] &= StringTrimLeft(DllStructGetData($tBuff, 1),2)
  119.                         Next
  120.                         Return $aBmpData
  121.                 Case Else
  122.                         Local $aRet[$aBmpData[2]]
  123.                         For $iH = 1 To $aBmpData[2]
  124.                                 $tBuff = DllStructCreate("byte[" & ($aBmpData[1]*3) & "]", $aBmpData[4] + ($iH-1)*$aBmpData[3])
  125.                                 $aRet[$iH-1] = StringTrimLeft(DllStructGetData($tBuff, 1), 2)
  126.                         Next
  127.                         Return $aRet
  128.         EndSwitch
  129. EndFunc
复制代码

评分

1

查看全部评分

发表于 2016-2-25 13:52:38 | 显示全部楼层
强力插入,马克留脚印!!!
发表于 2016-2-28 01:30:12 | 显示全部楼层
强力插入,马克留脚印!!!
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|小黑屋|手机版|AUTOIT CN ( 鲁ICP备15028933号-3 )谷歌 百度

GMT+8, 2018-6-21 09:05 , Processed in 0.103793 second(s), 20 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

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