绿色风's Blog
专注AutoIT(Au3)
  • 首页
  • 流●年
  • 笔●记
    • 学习随记
    • 源码示例
  • 脚●本
    • UDF(收集)
    • 工作室UDF
    • 工具●教程
    • 教程之GDI
  • 作●品
  • 下●载
  • 情怀ExcelTip
8月182015

Au3[位置不固定]验证码识别例子

作者:绿色风   发布:2015-8-18 12:32 Tuesday   分类:   阅读:9873次   评论:0条  


11111.JPG

222.JPG

使用了阿福的验证码对比方法,先感谢阿福的开源讲座。
说明,对于位置不固定,大小不固定,但是不粘连的验证码适用,输出程序功能就不加了,大家争取看懂了自己修改吧
使用说明,只要填写好字符数,手工调整到能二色化,无杂点,尽量学习多一点,识别率就会高
有机会有能力的话,以后会争取研究粘连型的

增加了判断,增加中途退出学习功能。

```#include <Constants.au3> #include <APIConstants.au3> #include <GUIConstantsEx.au3> #include <INet.au3> #include <WinAPI.au3> #include <WinAPIEx.au3> #include <Memory.au3> #include <GDIPlusex.au3> ;~ #include <Array.au3> $s_FontFile = "CodeFont.txt" Global $oldBitMap, $YzmArray, $hScaleBitmap, $DoneArray Global $Scale = 4, $Coordinate = 20 Global $LoginYzmUrl = "http://www.sharebank.com.cn/members/authimg.php" Global $learnedYzm[1][3] Global $learninput[6] Global $left, $top, $zhong, $ziwidth, $ziHeight, $zishu, $yzmclass = 10 $hGui = GUICreate("位置不固定验证码例子", 800, 400) GUICtrlCreateGroup("验证码地址", 590, 5, 180, 45) $InputYzmUrl = GUICtrlCreateInput($LoginYzmUrl, 600, 20, 160, 20) GUICtrlCreateGroup("", -99, -99, 1, 1) GUICtrlCreateGroup("放大验证码", 5, 5, 580, 255) $Pic2 = GUICtrlCreatePic("", 20, 20, 500, 200) Global $hPic2 = GUICtrlGetHandle(-1) GUICtrlCreateGroup("", -99, -99, 1, 1) GUICtrlCreateGroup("字型数据", 590, 60, 180, 110) GUICtrlCreateLabel("左边空:", 600, 80) GUICtrlCreateLabel("上边空:", 600, 110) GUICtrlCreateLabel("字间空:", 600, 140) GUICtrlCreateLabel("字符宽:", 680, 80) GUICtrlCreateLabel("字符高:", 680, 110) GUICtrlCreateLabel("字符数:", 680, 140) $input1 = GUICtrlCreateInput("0", 650, 80, 20) GUICtrlSetState(-1, $GUI_DISABLE) $input2 = GUICtrlCreateInput("0", 650, 110, 20) GUICtrlSetState(-1, $GUI_DISABLE) $input3 = GUICtrlCreateInput("0", 650, 140, 20) GUICtrlSetState(-1, $GUI_DISABLE) $input4 = GUICtrlCreateInput("0", 730, 80, 20) GUICtrlSetState(-1, $GUI_DISABLE) $input5 = GUICtrlCreateInput("0", 730, 110, 20) GUICtrlSetState(-1, $GUI_DISABLE) $input6 = GUICtrlCreateInput("5", 730, 140, 20) GUICtrlCreateGroup("", -99, -99, 1, 1) GUICtrlCreateGroup("验证码类型", 590, 180, 180, 80) GUIStartGroup() $radio1 = GUICtrlCreateRadio("仅数字", 600, 200) GUICtrlSetState(-1, $GUI_DISABLE) $radio2 = GUICtrlCreateRadio("仅字母", 680, 200) GUICtrlSetState(-1, $GUI_DISABLE) $radio3 = GUICtrlCreateRadio("数字字母混合", 600, 230) GUICtrlSetState(-1, $GUI_DISABLE) GUICtrlSetState($radio1, $GUI_CHECKED) GUICtrlCreateGroup("", -99, -99, 1, 1) GUICtrlCreateGroup("原始验证码", 5, 270, 180, 80) $Pic = GUICtrlCreatePic("", 20, 290, 50, 20) Global $hPic = GUICtrlGetHandle(-1) GUICtrlCreateGroup("", -99, -99, 1, 1) GUICtrlCreateGroup("功能区", 190, 270, 580, 80) $MF = GUICtrlCreateCheckbox("中值滤波", 200, 320, 60) $quse = GUICtrlCreateCheckbox("二色化", 280, 320, 60) $InvertsColors = GUICtrlCreateCheckbox("反相", 360, 320, 60) $qudian = GUICtrlCreateCheckbox("去噪点", 440, 320, 60) $study = GUICtrlCreateButton("学习", 520, 320, 60) $make = GUICtrlCreateButton("识别", 600, 320, 60) GUIStartGroup() $BGray = GUICtrlCreateRadio("蓝灰", 200, 290, 60) $GGray = GUICtrlCreateRadio("绿灰", 280, 290, 60) $RGray = GUICtrlCreateRadio("红灰", 360, 290, 60) $AGray = GUICtrlCreateRadio("全灰", 440, 290, 60) $MaxGray = GUICtrlCreateRadio("最大", 520, 290, 60) $MinGray = GUICtrlCreateRadio("最小", 600, 290, 60) $NGray = GUICtrlCreateRadio("原色", 680, 290, 60) GUICtrlCreateGroup("", -99, -99, 1, 1) GUISetState(@SW_SHOW) ;~ _INetGetSource(GUICtrlRead($InputYzmUrl), False) showBitmap() While 1 $nMsg = GUIGetMsg() Switch $nMsg Case -3 GUIDelete() quit() Case $Pic, $Pic2 showBitmap() Case $quse, $BGray, $GGray, $RGray, $AGray, $MaxGray, $MinGray, $NGray, $MF, $InvertsColors, $qudian $hScaleBitmap = ScaleImage() SetPicBitmap($hPic2, $hScaleBitmap) Case $study learn() Case $make shibie() EndSwitch WEnd Func quit() Exit EndFunc ;==>quit Func showBitmap() GetYzm() SetPicBitmap($hPic, $oldBitMap) $hScaleBitmap = ScaleImage() SetPicBitmap($hPic2, $hScaleBitmap) EndFunc ;==>showBitmap Func learn() If BitAND(GUICtrlRead($quse), $GUI_UNCHECKED) Then MsgBox(0, "警告", "请先选择一个灰度方法,再进行二色化。然后才能学习特征码!", -1, $hGui) Return EndIf $a_Image = myArrayClearBG($DoneArray) For $i = 1 To GUICtrlRead($input6) $a = connectedComt($a_Image) $a_Image = myArrayXORarray($a_Image, $a) $a_Image = myArrayClearBG($a_Image) $a = myArrayClearBG($a) $s_code_string = myArrarOCR($s_FontFile, $a, 0) If $s_code_string = False Then ExitLoop Next EndFunc ;==>learn Func shibie() If BitAND(GUICtrlRead($quse), $GUI_UNCHECKED) Then MsgBox(0, "警告", "请先选择一个灰度方法,再进行二色化。然后才能进行识别!", -1, $hGui) Return EndIf $begin = TimerInit() $a_Image = myArrayClearBG($DoneArray) $s_code = "" For $i = 1 To GUICtrlRead($input6) $a = connectedComt($a_Image) $a_Image = myArrayXORarray($a_Image, $a) $a_Image = myArrayClearBG($a_Image) $a = myArrayClearBG($a) $s_code_string = myArrarOCR($s_FontFile, $a, 1) $s_code &= $s_code_string Next MsgBox(4096, TimerDiff($begin), "识别结果:" & $s_code) EndFunc ;==>shibie Func SetPicBitmap($hPic, $hBitMap) Local $oldObj = _SendMessage($hPic, 0x0172, 0, $hBitMap) _WinAPI_DeleteObject($oldObj) Local $hObj = _SendMessage($hPic, 0x0173) If $hObj <> $hBitMap Then _WinAPI_DeleteObject($hBitMap) EndIf Return 1 EndFunc ;==>SetPicBitmap Func GetYzm() Local $bImage = _INetGetSource(GUICtrlRead($InputYzmUrl), False) Local $bData = Binary($bImage) Local $Lenght = BinaryLen($bData) Local $hData = _MemGlobalAlloc($Lenght, 0x0002) Local $pData = _MemGlobalLock($hData) Local $tData = DllStructCreate('byte[' & $Lenght & ']', $pData) DllStructSetData($tData, 1, $bData) _MemGlobalUnlock($hData) Local $pStream = _WinAPI_CreateStreamOnHGlobal($hData) _GDIPlus_Startup() Local $hImage = _GDIPlus_BitmapCreateFromStream($pStream) $YzmArray = YzmToArray($hImage) $oldBitMap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hImage) _GDIPlus_ImageDispose($hImage) _MemGlobalFree($hData) _GDIPlus_Shutdown() DllCall('psapi.dll', 'int', 'EmptyWorkingSet', 'hWnd', -1) Return 1 EndFunc ;==>GetYzm Func YzmToArray($hImage, $func_bg = 0xffffff) Local $BitmapData, $iwidth, $iheight, $Scan0, $pixelData, $s_BMPData, $i_Stride $iwidth = _GDIPlus_ImageGetWidth($hImage) $iheight = _GDIPlus_ImageGetHeight($hImage) $BitmapData = _GDIPlus_BitmapLockBits($hImage, 0, 0, $iwidth, $iheight, $GDIP_ILMREAD, $GDIP_PXF24RGB) $i_Stride = DllStructGetData($BitmapData, "Stride");Stride - Offset, in bytes, between consecutive scan lines of the bitmap. If the stride is positive, the bitmap is top-down. If the stride is negative, the bitmap is bottom-up. $Scan0 = DllStructGetData($BitmapData, "Scan0");Scan0 - Pointer to the first (index 0) scan line of the bitmap. $pixelData = DllStructCreate("ubyte lData[" & (Abs($i_Stride) * $iheight) & "]", $Scan0) ;不要使用官方论坛上提供的Abs($i_Stride) * $iheight-1,否则无法正确处理gif冗余等情形 $s_BMPData = DllStructGetData($pixelData, "lData") $s_BMPData = StringTrimLeft($s_BMPData, 2);去掉头部"0x" DllCall('psapi.dll', 'int', 'EmptyWorkingSet', 'hWnd', -1) ;处理图片数组 Local $a_return[$iwidth][$iheight], $x, $y, $s For $y = 0 To $iheight - 1 $s = StringMid($s_BMPData, $y * ($i_Stride * 2) + 1, $iwidth * 6) For $x = 0 To $iwidth - 1 $a_return[$x][$y] = Number("0x" & StringMid($s, $x * 6 + 1, 6)) Next Next Local $xScale = Int(510 / $iwidth) Local $yScale = Int(180 / $iheight) $Scale = $xScale If $xScale > $yScale Then $Scale = $yScale GUICtrlSetPos($Pic2, 20, 20, $iwidth * $Scale + $Coordinate * 2, $iheight * $Scale + $Coordinate * 2) GUICtrlSetPos($Pic, 20, 290, $iwidth, $iheight) Return $a_return EndFunc ;==>YzmToArray Func ArrayTo2Color($aArray, $threshold = 0x888888) Local $iwidth = UBound($aArray), $iheight = UBound($aArray, 2) Local $a_return[$iwidth][$iheight] For $y = 0 To $iheight - 1 For $x = 0 To $iwidth - 1 If $aArray[$x][$y] < $threshold Then $a_return[$x][$y] = 0x000000 Else $a_return[$x][$y] = 0xFFFFFF EndIf Next Next Return $a_return EndFunc ;==>ArrayTo2Color Func InvertsColors($aArray) Local $iwidth = UBound($aArray), $iheight = UBound($aArray, 2) Local $a_return[$iwidth][$iheight] For $y = 0 To $iheight - 1 For $x = 0 To $iwidth - 1 If $aArray[$x][$y] = 0x000000 Then $a_return[$x][$y] = 0xFFFFFF Else $a_return[$x][$y] = 0x000000 EndIf Next Next Return $a_return EndFunc ;==>InvertsColors Func Medianfilter($aArray) Local $iwidth = UBound($aArray), $iheight = UBound($aArray, 2) Local $a_return[$iwidth][$iheight] Local $window[9], $min, $temp, $k For $y = 1 To $iheight - 2 For $x = 1 To $iwidth - 2 $k = 0 For $i = $x - 1 To $x + 1 For $j = $y - 1 To $y + 1 $window[$k] = $aArray[$i][$j] $k += 1 Next Next For $m = 0 To 4 $min = $m For $n = $m + 1 To 8 If $window[$n] < $window[$min] Then $min = $n $temp = $window[$m] $window[$m] = $window[$min] $window[$min] = $temp EndIf Next Next $a_return[$x][$y] = $window[4] Next Next For $x = 0 To $iwidth - 1 $a_return[$x][0] = $aArray[$x][0] $a_return[$x][$iheight - 1] = $aArray[$x][$iheight - 1] Next For $y = 0 To $iheight - 1 $a_return[0][$y] = $aArray[0][$y] $a_return[$iwidth - 1][$y] = $aArray[$iwidth - 1][$y] Next Return $a_return EndFunc ;==>Medianfilter Func Graycolor($aArray, $color = "all") Local $iwidth = UBound($aArray), $iheight = UBound($aArray, 2) Local $a_return[$iwidth][$iheight], $b, $g, $r, $ret $func_bg = $aArray[1][1] For $y = 0 To $iheight - 1 For $x = 0 To $iwidth - 1 Switch $color Case "blue" $b = BitAND(0xFF, BitShift($aArray[$x][$y], 16)) $a_return[$x][$y] = BitOR(BitShift($b, -16), BitShift($b, -8), $b) Case "green" $g = BitAND(0xFF, BitShift($aArray[$x][$y], 8)) $a_return[$x][$y] = BitOR(BitShift($g, -16), BitShift($g, -8), $g) Case "red" $r = BitAND(0xFF, $aArray[$x][$y]) $a_return[$x][$y] = BitOR(BitShift($r, -16), BitShift($r, -8), $r) Case "all" $b = BitAND(0xFF, BitShift($aArray[$x][$y], 16)) $g = BitAND(0xFF, BitShift($aArray[$x][$y], 8)) $r = BitAND(0xFF, $aArray[$x][$y]) $ret = Int((30 * $r + $g * 59 + $b * 11) / 100) $b = BitAND(0xFF0000, BitShift($ret, -16)) $g = BitAND(0x00FF00, BitShift($ret, -8)) $r = $ret $a_return[$x][$y] = BitOR($b, $g, $r) Case "max" $b = BitAND(0xFF, BitShift($aArray[$x][$y], 16)) $g = BitAND(0xFF, BitShift($aArray[$x][$y], 8)) $r = BitAND(0xFF, $aArray[$x][$y]) $ret = $b If $g > $ret Then $ret = $g If $r > $ret Then $ret = $r $b = BitAND(0xFF0000, BitShift($ret, -16)) $g = BitAND(0x00FF00, BitShift($ret, -8)) $r = $ret $a_return[$x][$y] = BitOR($b, $g, $r) Case "min" $b = BitAND(0xFF, BitShift($aArray[$x][$y], 16)) $g = BitAND(0xFF, BitShift($aArray[$x][$y], 8)) $r = BitAND(0xFF, $aArray[$x][$y]) $ret = $b If $g < $ret Then $ret = $g If $r < $ret Then $ret = $r $b = BitAND(0xFF0000, BitShift($ret, -16)) $g = BitAND(0x00FF00, BitShift($ret, -8)) $r = $ret $a_return[$x][$y] = BitOR($b, $g, $r) EndSwitch Next Next Return $a_return EndFunc ;==>Graycolor Func pingjunColor($aArray) Local $iwidth = UBound($aArray), $iheight = UBound($aArray, 2) Local $sret For $y = 0 To $iheight - 1 For $x = 0 To $iwidth - 1 $sret += Hex($aArray[$x][$y], 6) Next Next Return $sret = Int($sret / $iwidth / $iheight) EndFunc ;==>pingjunColor Func DrawCoordinate($hMemDC, $iwidth, $iheight) For $i = 0 To $iwidth If Mod($i, 5) = 0 Then _WinAPI_DrawLine($hMemDC, $Coordinate + $i * $Scale - 1, 10, $Coordinate + $i * $Scale - 1, $Coordinate - 1) Else _WinAPI_DrawLine($hMemDC, $Coordinate + $i * $Scale - 1, 15, $Coordinate + $i * $Scale - 1, $Coordinate - 1) EndIf If Mod($i, 10) = 0 Then _WinAPI_TextOut($hMemDC, $i * $Scale + 10, 0, $i) EndIf Next For $i = 0 To $iheight If Mod($i, 5) = 0 Then _WinAPI_DrawLine($hMemDC, 10, $Coordinate + $i * $Scale - 1, $Coordinate - 1, $Coordinate + $i * $Scale - 1) Else _WinAPI_DrawLine($hMemDC, 15, $Coordinate + $i * $Scale - 1, $Coordinate - 1, $Coordinate + $i * $Scale - 1) EndIf If Mod($i, 10) = 0 And $i <> 0 Then _WinAPI_TextOut($hMemDC, 0, $i * $Scale + 10, $i) EndIf Next EndFunc ;==>DrawCoordinate Func ScaleImage() $DoneArray = $YzmArray If BitAND(GUICtrlRead($BGray), $GUI_CHECKED) Then $DoneArray = Graycolor($DoneArray, "blue") If BitAND(GUICtrlRead($GGray), $GUI_CHECKED) Then $DoneArray = Graycolor($DoneArray, "green") If BitAND(GUICtrlRead($RGray), $GUI_CHECKED) Then $DoneArray = Graycolor($DoneArray, "red") If BitAND(GUICtrlRead($AGray), $GUI_CHECKED) Then $DoneArray = Graycolor($DoneArray, "all") If BitAND(GUICtrlRead($MaxGray), $GUI_CHECKED) Then $DoneArray = Graycolor($DoneArray, "max") If BitAND(GUICtrlRead($MinGray), $GUI_CHECKED) Then $DoneArray = Graycolor($DoneArray, "min") If BitAND(GUICtrlRead($MF), $GUI_CHECKED) Then $DoneArray = Medianfilter($DoneArray) If BitAND(GUICtrlRead($quse), $GUI_CHECKED) Then $DoneArray = ArrayTo2Color($DoneArray) If BitAND(GUICtrlRead($InvertsColors), $GUI_CHECKED) Then $DoneArray = InvertsColors($DoneArray) If BitAND(GUICtrlRead($qudian), $GUI_CHECKED) Then $DoneArray = myArrayNoDrop($DoneArray, 3) Local $iwidth = UBound($DoneArray), $iheight = UBound($DoneArray, 2) Local $tRECT, $pRECT Local $hBrush Local $hDC = _WinAPI_GetDC(0) Local $hMemDC = _WinAPI_CreateCompatibleDC($hDC);建立兼容DC,即内存中的DC Local $hBitMap = _WinAPI_CreateCompatibleBitmapEx($hDC, $iwidth * $Scale + $Coordinate * 2, $iheight * $Scale + $Coordinate * 2, 0xEEEEEE);创建hBitmap Local $hSv = _WinAPI_SelectObject($hMemDC, $hBitMap);调入DC作图对象,即把图形画在$hBitmap上 _WinAPI_SetBkMode($hMemDC, $TRANSPARENT) DrawCoordinate($hMemDC, $iwidth, $iheight) For $i = 0 To $iwidth - 1 For $j = 0 To $iheight - 1 $tRECT = _WinAPI_CreateRect($i * $Scale + $Coordinate, $j * $Scale + $Coordinate, _ ($i + 1) * $Scale + $Coordinate - 1, ($j + 1) * $Scale + $Coordinate - 1) $pRECT = DllStructGetPtr($tRECT) $hBrush = _WinAPI_CreateBrushIndirect($BS_SOLID, _WinAPI_SwitchColor($DoneArray[$i][$j]), $HS_DIAGCROSS) _WinAPI_FillRect($hMemDC, $pRECT, $hBrush) _WinAPI_DeleteObject($hBrush) Next Next _WinAPI_SelectObject($hMemDC, $hSv) _WinAPI_DeleteDC($hMemDC) _WinAPI_ReleaseDC(0, $hDC) Return $hBitMap EndFunc ;==>ScaleImage ;提取连通分量 Func connectedComt($aArray) Local $x = UBound($aArray), $y = UBound($aArray, 2) Local $ConectArray[$x][$y] $ConectArray = myArrayInit($ConectArray) For $i = 0 To $x - 1 For $j = 0 To $y - 1 If $aArray[$i][$j] = 0x000000 Then connectCheck($ConectArray, $aArray, $i, $j) ExitLoop (2) EndIf Next Next Return $ConectArray EndFunc ;==>connectedComt Func connectCheck(ByRef $ConectArray, $aArray, $i, $j) Local $x = UBound($aArray), $y = UBound($aArray, 2) $ConectArray[$i][$j] = 0x000000 If $i + 1 <= $x - 1 Then If $aArray[$i + 1][$j] = 0x000000 And $ConectArray[$i + 1][$j] = 0xFFFFFF Then connectCheck($ConectArray, $aArray, $i + 1, $j) EndIf If $i - 1 >= 0 Then If $aArray[$i - 1][$j] = 0x000000 And $ConectArray[$i - 1][$j] = 0xFFFFFF Then connectCheck($ConectArray, $aArray, $i - 1, $j) EndIf If $j + 1 <= $y - 1 Then If $aArray[$i][$j + 1] = 0x000000 And $ConectArray[$i][$j + 1] = 0xFFFFFF Then connectCheck($ConectArray, $aArray, $i, $j + 1) EndIf If $j - 1 >= 0 Then If $aArray[$i][$j - 1] = 0x000000 And $ConectArray[$i][$j - 1] = 0xFFFFFF Then connectCheck($ConectArray, $aArray, $i, $j - 1) EndIf If ($i + 1 <= $x - 1) And ($j + 1 <= $y - 1) Then If $aArray[$i + 1][$j + 1] = 0x000000 And $ConectArray[$i + 1][$j + 1] = 0xFFFFFF Then connectCheck($ConectArray, $aArray, $i + 1, $j + 1) EndIf If ($i + 1 < $x - 1) And ($j - 1 >= 0) Then If $aArray[$i + 1][$j - 1] = 0x000000 And $ConectArray[$i + 1][$j - 1] = 0xFFFFFF Then connectCheck($ConectArray, $aArray, $i + 1, $j - 1) EndIf If ($i - 1 >= 0) And ($j + 1 <= $y - 1) Then If $aArray[$i - 1][$j + 1] = 0x000000 And $ConectArray[$i - 1][$j + 1] = 0xFFFFFF Then connectCheck($ConectArray, $aArray, $i - 1, $j + 1) EndIf If ($i - 1 >= 0) And ($j - 1 >= 0) Then If $aArray[$i - 1][$j - 1] = 0x000000 And $ConectArray[$i - 1][$j - 1] = 0xFFFFFF Then connectCheck($ConectArray, $aArray, $i - 1, $j - 1) EndIf Return True EndFunc ;==>connectCheck ;下面的函数来自阿福,稍做修改 Func myArrayToString($func_array, $show = False) Local $y, $x, $s = "" For $y = 0 To UBound($func_array, 2) - 1 For $x = 0 To UBound($func_array, 1) - 1 $s &= Hex($func_array[$x][$y], 6) Next If $show Then $s &= @CRLF Next If $show Then $s = StringReplace($s, "FFFFFF", ChrW(0x3000)) $s = StringReplace($s, "000000", ChrW(0x2588)) Else $s = StringReplace($s, "000000", "1") $s = StringReplace($s, "FFFFFF", "0") EndIf Return $s EndFunc ;==>myArrayToString Func myArrayXORarray($func_array, $func_array2, $func_bg = 0xFFFFFF, $func_type = True);用数组1加减数组2,得到一个新数组,数组2<=数组1 If Not IsArray($func_array) Then Return 0 If Not IsArray($func_array2) Then Return 0 If UBound($func_array, 1) < UBound($func_array2, 1) Then Return 0 If UBound($func_array, 2) < UBound($func_array2, 2) Then Return 0 Local $x, $y For $x = 0 To UBound($func_array2, 1) - 1 For $y = 0 To UBound($func_array2, 2) - 1 If $func_array2[$x][$y] <> $func_bg Then If $func_type Then $func_array[$x][$y] = $func_bg; Else $func_array[$x][$y] = $func_array2[$x][$y] ;BitXOR( $func_array2[$x][$y], $func_bg) EndIf EndIf Next Next Return $func_array EndFunc ;==>myArrayXORarray Func myArrayNoDrop($func_array, $func_drop = 1, $func_bg = 0xFFFFFF);去干扰 If Not IsArray($func_array) Then Return 0 Local $x, $y, $i, $startx, $endx, $starty, $endy, $a, $b For $y = 0 To UBound($func_array, 2) - 1 For $x = 0 To UBound($func_array, 1) - 1 If $func_array[$x][$y] = $func_bg Then ContinueLoop;底色,不处理 $startx = $x - 1 If $startx < 0 Then $startx = 0 $endx = $x + 1 If $endx > UBound($func_array, 1) - 1 Then $endx = UBound($func_array, 1) - 1 $starty = $y - 1 If $starty < 0 Then $starty = 0 $endy = $y + 1 If $endy > UBound($func_array, 2) - 1 Then $endy = UBound($func_array, 2) - 1 $i = 0 For $a = $startx To $endx For $b = $starty To $endy If $func_array[$a][$b] <> $func_bg Then $i += 1;该点非底色 Next Next If $i > 0 And $i <= $func_drop Then; $func_array[$x][$y] = $func_bg EndIf Next Next Return $func_array EndFunc ;==>myArrayNoDrop Func myArrayDelBox($func_array, $func_left = 0, $func_right = 0, $func_top = 0, $func_bottom = 0) If Not IsArray($func_array) Then Return $func_array; Local $a_msg[8] $a_msg[0] = 2;二维 $a_msg[1] = UBound($func_array, 1) $a_msg[2] = UBound($func_array, 2) $a_msg[3] = $func_left $a_msg[4] = $func_right $a_msg[5] = $func_top $a_msg[6] = $func_bottom If $a_msg[1] <= $a_msg[3] + $a_msg[4] Or $a_msg[2] <= $a_msg[5] + $a_msg[6] Then Return $func_array;超界 Local $a_return[$a_msg[1] - $a_msg[3] - $a_msg[4]][$a_msg[2] - $a_msg[5] - $a_msg[6]] Local $x, $y For $y = $a_msg[5] To $a_msg[2] - $a_msg[6] - 1 For $x = $a_msg[3] To $a_msg[1] - $a_msg[4] - 1 $a_return[$x - $a_msg[3]][$y - $a_msg[5]] = $func_array[$x][$y] Next Next Return $a_return EndFunc ;==>myArrayDelBox Func myArrayClearBG($func_array, $func_left = True, $func_right = True, $func_top = True, $func_bottom = True, $func_bg = 0xFFFFFF) Local $a_msg = myGetArrayMessage($func_array, $func_bg) If Not IsArray($a_msg) Or $a_msg[7] = 1 Then Return $func_array;$func_array不用判断是否数组了,因为myGetArrayMessage函数返回的值已经说明问题了 If Not $func_left Then $a_msg[3] = 0 If Not $func_right Then $a_msg[4] = 0 If Not $func_top Then $a_msg[5] = 0 If Not $func_bottom Then $a_msg[6] = 0 If $a_msg[0] = 2 Then Local $a_return[$a_msg[1] - $a_msg[3] - $a_msg[4]][$a_msg[2] - $a_msg[5] - $a_msg[6]] Else Local $a_return[$a_msg[2] - $a_msg[5] - $a_msg[6]] EndIf Local $x, $y For $y = $a_msg[5] To $a_msg[2] - $a_msg[6] - 1 If $a_msg[0] = 2 Then For $x = $a_msg[3] To $a_msg[1] - $a_msg[4] - 1 $a_return[$x - $a_msg[3]][$y - $a_msg[5]] = $func_array[$x][$y] Next Else $a_return[$y - $a_msg[5]] = StringMid($func_array[$y], 6 * $a_msg[3] + 1, 6 * ($a_msg[1] - $a_msg[3] - $a_msg[4])) EndIf Next Return $a_return EndFunc ;==>myArrayClearBG Func myGetArrayMessage($func_array, $func_bg = 0xFFFFFF);获取数组周边全为底色的信息,错误时返回非数组 If UBound($func_array) = 0 Then Return $func_array Local $time = TimerInit() Local $a_return[11] If UBound($func_array, 2) = 0 Then Local $i_height = UBound($func_array) Local $i_width = StringLen($func_array[0]) / 6 $a_return[0] = 1;一维 Else Local $i_height = UBound($func_array, 2) Local $i_width = UBound($func_array, 1) $a_return[0] = 2;二维 EndIf Local $x, $y, $s, $s1, $i_top = 0, $i_bottom = $i_height, $i_left = -1, $i_right = $i_width, $i_tmp, $s_all = "" $func_bg = Hex($func_bg, 6) For $y = 0 To $i_height - 1 If $a_return[0] = 1 Then $s = $func_array[$y] Else $s = "" For $x = 0 To $i_width - 1 $s &= Hex($func_array[$x][$y], 6) Next EndIf $s_all &= $s ;左空几个位置 If $i_left <> 0 Then;=0说明有一行左边第一个不为空,所以不用再找了 $s1 = StringRegExpReplace($s, "^(" & $func_bg & "){1,}", "") If $i_left = -1 Or $i_left > (StringLen($s) - StringLen($s1)) / 6 Then $i_left = (StringLen($s) - StringLen($s1)) / 6 EndIf ;ConsoleWrite($s&','&$i_left&@crlf) ;右空几个位置,经测试,用正则来做时,大文件极慢,所以不用正则 $i_tmp = 0 Do $i_tmp += 1 $s1 = StringRight($s, 6 * $i_tmp) Until StringLeft($s1, 6) <> $func_bg Or $i_tmp > $i_right If $i_right > $i_tmp - 1 Then $i_right = $i_tmp - 1 $s = StringReplace($s, $func_bg, "") If $s = "" Then If $i_bottom = $i_height Then $i_bottom = $y;下面第几行开始空 If $i_top = $y Then $i_top += 1;上面有几行空 Else $i_bottom = $i_height EndIf Next $i_bottom = $i_height - $i_bottom;变化为结果,下空几行 $a_return[1] = $i_width;宽 $a_return[2] = $i_height;高 $a_return[3] = $i_left;左空几个 $a_return[4] = $i_right;右空几个 $a_return[5] = $i_top;上空几个 $a_return[6] = $i_bottom;下空几个 $a_return[7] = 0;0不超界 If $i_width <= $i_left Or $i_height <= $i_top Then $a_return[7] = 1;1超界 $a_return[8] = 0;彩色 If StringReplace(StringReplace($s_all, "FFFFFF", ""), "000000", "") = "" Then $a_return[8] = 1;1黑白 $a_return[9] = $s_all;点阵串 $a_return[10] = TimerDiff($time);运行时间多少毫秒 ;ConsoleWrite($i_width&','&$i_height&','&$i_left&','&$i_right&','&$i_top&','&$i_bottom&@CRLF) Return $a_return EndFunc ;==>myGetArrayMessage Func OcrCompStr($string1, $string2);返回多少个不同 If $string1 = $string2 Then Return 0 Local $i_return = 0, $i For $i = 1 To StringLen($string1) If StringMid($string1, $i, 1) <> StringMid($string2, $i, 1) Then $i_return += 1 Next Return $i_return EndFunc ;==>OcrCompStr Func myArrarOCR($s_code_file, $func_array, $Ocr) If $s_code_file = "" Or Not IsArray($func_array) Then Return "" Local $a_Code, $i, $s_code, $s Local $s_file = FileRead($s_code_file);只能用于英文验证码处理,中文处理FileRead函数对Pwin有BUG要修正 If $Ocr Then Local $a_file = StringRegExp($s_file, "(.*)(?:\r\n)", 3) If Not IsArray($a_file) Then Return "";没有识别库 Local $j, $i_code, $i_code_temp, $s_code_string = "" EndIf Local $a_msg[3] If UBound($func_array, 2) > 0 Then $a_msg[0] = 2;二维 $a_msg[1] = UBound($func_array, 1) $a_msg[2] = UBound($func_array, 2) Else $a_msg[0] = 1;一维 $a_msg[1] = StringLen($func_array[0]) / 6 $a_msg[2] = UBound($func_array) EndIf Local $i_Ext $s = myArrayToString($func_array, False) StringReplace($s, "1", " ") $i_Ext = @extended ;为1个数,即点的数量 If $Ocr Then;识别 $i_code = $a_msg[1] * $a_msg[2] For $j = 0 To UBound($a_file) - 1 If Abs($i_Ext - Number(StringTrimLeft($a_file[$j], 2))) > 5 Then ContinueLoop;误差n(如50,此值待确定)个点以上的当做不对 $i_code_temp = OcrCompStr($s, StringTrimLeft($a_file[$j], StringInStr($a_file[$j], "|"))) If $i_code_temp < $i_code Then $i_code = $i_code_temp $s_code = StringLeft($a_file[$j], 1) If $i_code <= 0 Then ExitLoop EndIf Next $s_code_string &= $s_code Else;学习 $s_code = "" Do $s_code = InputBox("验证码学习", "请输入你所看到的验证码" & @CRLF & myArrayToString($func_array, True), "", "", 300, 300, @DesktopWidth / 2 - 150, @DesktopHeight / 2 - 150, -1, $hGui) If @error = 1 Then Return False Until StringLen($s_code) = 1 $s = myArrayToString($func_array, False) StringReplace(StringTrimLeft($s, StringInStr($s, "|")), "1", " ") $s = $s_code & "," & @extended & "|" & $s If StringInStr($s_file, $s) = 0 Then;未写过 FileWriteLine($s_code_file, $s) $s_file &= $s & @CRLF EndIf EndIf If $Ocr Then Return $s_code_string Else Return 1 EndIf EndFunc ;==>myArrarOCR Func myArrayInit($func_array, $func_bg = 0xFFFFFF);将数组初始化为底色 If Not IsArray($func_array) Then Return 0 Local $x, $y For $y = 0 To UBound($func_array, 2) - 1 For $x = 0 To UBound($func_array, 1) - 1 $func_array[$x][$y] = $func_bg;初始化为底色 Next Next;数组初始化 Return $func_array EndFunc ;==>myArrayInit ```





本文固定链接: http://www.jianyiit.com/post-128.html

blogger
该日志由 绿色风 于2015-8-18 12:32 Tuesday发表在 分类下。
版权所有:《绿色风's Blog》 → 《Au3[位置不固定]验证码识别例子》;
除特别标注,本博客很多文章均为原创. 互联分享,尊重版权,转载请以链接形式标明本文地址;
本文标签:

扫描二维码,在手机上阅读
上一篇::AU3内存释放
下一篇:蒙面歌王中国版第一期320K

热门文章

相关文章

  • 显示器 EDID 读取,生产日期和分辨率
  • Au3定时关机精灵(仿定时强制关机精力1.0)含源码
  • Au3载入在线WEB网页音乐
  • Au3 屏幕取色器
  • 非常酷的计算器
取消回复

发表评论

亲,头像对么?

52 + 31 =

提交中,请稍候……


木有头像就木JJ啦!还木有头像吗?点这里申请属于你的个性Gravatar头像吧!


    站点统计
    • 运行时间: 20254 天
    • 日志总数: 365 篇
    • 评论数量: 7237 条
    • 微语数量: 6 条
    • 附件总量: 388 件
  • 逝出的青春

  • 打赏"绿色风"



      扫码关注本站公众号 可搜本站内容

  • Autoit V3 脚本交流群

      常驻群1:905774875
      常驻群2:40672266


  • 链接

    • AU3中文论坛
    • Excel资料库
    • 完美者博客
    • 顺网小哥'S Blog
    • 猛牛哥的博客
    • 网吧系统下载
  • 分类

    • 流●年(66)
    • 笔●记(0)
    • 脚●本(0)
    • 作品(21)
    • 学习随记(51)
    • 源码示例(68)
    • UDF(收集)(26)
    • 工作室UDF(30)
    • 工具●教程(62)
    • 教程之GDI(24)
Copyright © 2013 绿色风's Blog. Powered by emlog. Theme by 射雕天龙. 鄂ICP备2021011689号-1 鄂公网安备42102302000078号 sitemap