Jump to content

OCR from a small area


Recommended Posts

Here my two cents.

 

#include <GDIPlus.au3>

Example()

Func Example()
    _GDIPlus_Startup()     ;initialize GDI+
    Local Const $iWidth = 150, $iHeight = 150
    Local $iColor = 0
    Local $hBitmap = _GDIPlus_BitmapCreateFromFile(@ScriptDir & "\TestImage.png")

    Local $Y0 = 0
    For $iY = 0 To $iHeight - 1
        For $iX = 0 To $iWidth - 1
            $iColor = _GDIPlus_BitmapGetPixel($hBitmap, $iX, $iY)             ;get current pixel color
            If $iColor = 4278255360 Then
;~              _GDIPlus_BitmapSetPixel($hBitmap, $iX, $iY, 0xFFFF0000)
;~              ConsoleWrite($iX & "," & $iY & @CRLF)
                $Y0 = $iY
                ExitLoop 2
            EndIf
        Next
    Next

    ;Find X
    Local $X0 = 0
    For $iX = 0 To $iWidth - 1
        For $iY = 0 To $iHeight - 1
            $iColor = _GDIPlus_BitmapGetPixel($hBitmap, $iX, $iY)             ;get current pixel color
            If $iColor = 4278255360 Then
;~              _GDIPlus_BitmapSetPixel($hBitmap, $iX, $iY, 0xFFFF0000)
;~              ConsoleWrite($iX & "," & $iY & @CRLF)
                $X0 = $iX
                ExitLoop 2
            EndIf
        Next
    Next

;~  _GDIPlus_BitmapSetPixel($hBitmap, $X0, $Y0, 0xFFFF0000)
    ConsoleWrite("TOP CORNER TEXT: " & $X0 & "," & $Y0 & @CRLF)
    Local $iFieldSizePixel14 = 16
    Local $sNumber = ""
    For $iX = $X0 To $iWidth - 1 Step $iFieldSizePixel14
        $sNumber &= _NumberFromPattern($hBitmap, $iX, $Y0)
    Next
    ConsoleWrite("Number: " & $sNumber & @CRLF)
    _GDIPlus_BitmapDispose($hBitmap)
    _GDIPlus_Shutdown()

EndFunc   ;==>Example

Func _NumberFromPattern(ByRef $hBitmap, $X0, $Y0)
    Local $a3[] = ["0,4", "6,9"]
    Local $a7[] = ["0,0", "13,0"]
    Local $a4[] = ["9,0", "0,9"]

    Local $aSplit = 0
    Local $iCount = 0
    For $i = 0 To UBound($a3) - 1
        $aSplit = StringSplit($a3[$i], ",", 2)
        If _GDIPlus_BitmapGetPixel($hBitmap, $X0 + ($aSplit[0]), $Y0 + ($aSplit[1])) = 4278255360 Then
            $iCount += 1
        EndIf
    Next
    If $iCount = UBound($aSplit) Then Return 3

    $iCount = 0
    For $i = 0 To UBound($a7) - 1
        $aSplit = StringSplit($a7[$i], ",", 2)
        If _GDIPlus_BitmapGetPixel($hBitmap, $X0 + ($aSplit[0]), $Y0 + ($aSplit[1])) = 4278255360 Then
            $iCount += 1
        EndIf
    Next
    If $iCount = UBound($aSplit) Then Return 7

    $iCount = 0
    For $i = 0 To UBound($a4) - 1
        $aSplit = StringSplit($a4[$i], ",", 2)
        If _GDIPlus_BitmapGetPixel($hBitmap, $X0 + ($aSplit[0]), $Y0 + ($aSplit[1])) = 4278255360 Then
            $iCount += 1
        EndIf
    Next
    If $iCount = UBound($aSplit) Then Return 4

    Return ""

EndFunc   ;==>_NumberFromPattern

 

Using the image from here.

 

You just need to build the pattern for the other numbers and try to make them unique.

 

Saludos

Edited by Danyfirex
typo
Link to comment
Share on other sites

47 minutes ago, Danyfirex said:

You just need to build the pattern for the other numbers

Func _NumberFromPattern(ByRef $hBitmap, $X0, $Y0, $iAlphaColor = 4278255360)
    Local $a3[] = ["0,4", "6,9"]
    Local $a7[] = ["0,0", "13,0"]
    Local $a4[] = ["9,0", "0,9"]

    Local $aTemp, $aSplit, $iCount
    For $n = 0 To 9
        $iCount = 0
        $aTemp = Eval('a' & $n)
        If Not UBound($aTemp) Then ContinueLoop ; array for digit not declared
        For $i = 0 To UBound($aTemp) - 1
            $aSplit = StringSplit($aTemp[$i], ",", 2)
            If _GDIPlus_BitmapGetPixel($hBitmap, $X0 + ($aSplit[0]), $Y0 + ($aSplit[1])) = $iAlphaColor Then
                $iCount += 1
            EndIf
        Next
        If $iCount = UBound($aSplit) Then Return $n
    Next
    Return ""
EndFunc   ;==>_NumberFromPattern

my contribution ? :)

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Link to comment
Share on other sites

3 hours ago, Danyfirex said:

You just need to build the pattern for the other numbers and try to make them unique.

the selected ones
the pixel selection for 3 also grabs 0 and 8
the pixel selection for 7 also grabs 5
the pixel selection for 4 also grabs 0 and 6 and 8
(I think)

what will happen when the first number is 1, which does not start from the beginning of the screen?

I know this is a simple example
I'm just adding difficulty parameters for consideration.  (food for thought) :)

 

Edited by ioa747

I know that I know nothing

Link to comment
Share on other sites

You would need to build some unique pattern. I've done things similar for for number before and worked perfectly. It is just a sample to handle it. but for sure it will work if you add a correct pattern for each number. 

 

Saludos

Link to comment
Share on other sites

...
    Local $hBitmap = _GDIPlus_BitmapCreateFromFile(@ScriptDir & "\code_000000.png")
    Local $Y0 = 0
    For $iY = 0 To $iHeight - 1
        ConsoleWrite(@CRLF)
        For $iX = 0 To $iWidth - 1
            $iColor = _GDIPlus_BitmapGetPixel($hBitmap, $iX, $iY) ;get current pixel color
            Switch $iColor ; 4278190080,FF000000,4294967295,FFFFFFFF,4288716960,FFA0A0A0,4278222848,FF008000,4278255360,FF00FF00,
                Case 0 ;          0x00000000
                    ConsoleWrite(",")
                Case 4278190080 ; 0xFF000000
                    ConsoleWrite(" ")
                Case 4288716960 ; 0xFFA0A0A0
                    ConsoleWrite("_")
                Case 4278222848 ; 0xFF008000
                    ConsoleWrite("`")
                Case 4278255360 ; 0xFF00FF00
                    ConsoleWrite("O")
            EndSwitch
...
     ;  ExitLoop 2 ; remove this to list all the "color match"

Making an array to match a char./number, should not be that hard to map/create with a complete set. code_000000.png

____________________________________________________________________________________________________________________________________ ,,,,,,,,,,,,,,
 ___________________________________________________________________________________________________________________________________ ,,,,,,,,,,,,,,
 __                                                                                                                                _ ,,,,,,,,,,,,,,
 __ `  `  `  `  `   `  `  `  `  `   `  OO OO OO `   OO OO OO OO OO  `  `  `  OO `   `  `  `  `  `   `  `  `  `  `   `  `  `  `  `  _ ,,,,,,,,,,,,,,
 __  `  `  `  `  `   `  `  `  `  `   ` OO OO OO  `  OO OO OO OO OO   `  `  ` OO  `   `  `  `  `  `   `  `  `  `  `   `  `  `  `  ` _ ,,,,,,,,,,,,,,
 __                                                                                                                                _ ,,,,,,,,,,,,,,
 __ `  `  `  `  `   `  `  `  `  `   OO `  `  `  OO  `  `  `  `  OO  `  `  OO OO `   `  `  `  `  `   `  `  `  `  `   `  `  `  `  `  _ ,,,,,,,,,,,,,,
 __  `  `  `  `  `   `  `  `  `  `  OO  `  `  ` OO   `  `  `  ` OO   `  ` OO OO  `   `  `  `  `  `   `  `  `  `  `   `  `  `  `  ` _ ,,,,,,,,,,,,,,
 __                                                                                                                                _ ,,,,,,,,,,,,,,
 __ `  `  `  `  `   `  `  `  `  `   `  `  `  `  OO  `  `  `  OO `   `  OO `  OO `   `  `  `  `  `   `  `  `  `  `   `  `  `  `  `  _ ,,,,,,,,,,,,,,
 __  `  `  `  `  `   `  `  `  `  `   `  `  `  ` OO   `  `  ` OO  `   ` OO  ` OO  `   `  `  `  `  `   `  `  `  `  `   `  `  `  `  ` _ ,,,,,,,,,,,,,,
 __                                                                                                                                _ ,,,,,,,,,,,,,,
 __ `  `  `  `  `   `  `  `  `  `   `  `  OO OO `   `  `  OO `  `   OO `  `  OO `   `  `  `  `  `   `  `  `  `  `   `  `  `  `  `  _ ,,,,,,,,,,,,,,
 __  `  `  `  `  `   `  `  `  `  `   `  ` OO OO  `   `  ` OO  `  `  OO  `  ` OO  `   `  `  `  `  `   `  `  `  `  `   `  `  `  `  ` _ ,,,,,,,,,,,,,,
 __                                                                                                                                _ ,,,,,,,,,,,,,,
 __ `  `  `  `  `   `  `  `  `  `   `  `  `  `  OO  `  OO `  `  `   OO OO OO OO OO  `  `  `  `  `   `  `  `  `  `   `  `  `  `  `  _ ,,,,,,,,,,,,,,
 __  `  `  `  `  `   `  `  `  `  `   `  `  `  ` OO   ` OO  `  `  `  OO OO OO OO OO   `  `  `  `  `   `  `  `  `  `   `  `  `  `  ` _ ,,,,,,,,,,,,,,
 __                                                                                                                                _ ,,,,,,,,,,,,,,
 __ `  `  `  `  `   `  `  `  `  `   OO `  `  `  OO  `  OO `  `  `   `  `  `  OO `   `  `  `  `  `   `  `  `  `  `   `  `  `  `  `  _ ,,,,,,,,,,,,,,
 __  `  `  `  `  `   `  `  `  `  `  OO  `  `  ` OO   ` OO  `  `  `   `  `  ` OO  `   `  `  `  `  `   `  `  `  `  `   `  `  `  `  ` _ ,,,,,,,,,,,,,,
 __                                                                                                                                _ ,,,,,,,,,,,,,,
 __ `  `  `  `  `   `  `  `  `  `   `  OO OO OO `   `  OO `  `  `   `  `  `  OO `   `  `  `  `  `   `  `  `  `  `   `  `  `  `  `  _ ,,,,,,,,,,,,,,
 __  `  `  `  `  `   `  `  `  `  `   ` OO OO OO  `   ` OO  `  `  `   `  `  ` OO  `   `  `  `  `  `   `  `  `  `  `   `  `  `  `  ` _ ,,,,,,,,,,,,,,
 __                                                                                                                                _ ,,,,,,,,,,,,,,

 

Edited by argumentum

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

Link to comment
Share on other sites

6 hours ago, ioa747 said:

Try this part  (it's one of the first ones I did)
which piece only does the delimitation of the number area  (and not the recognition of the pattern)
where the procedures are a bit more simplified and it goes step by step,
so you can figure out what  the procedures are doing.

#AutoIt3Wrapper_UseX64=N

#include <WinAPI.au3>
#include <GDIPlus.au3>
#include <ScreenCapture.au3>
#include <Array.au3>
#include <File.au3>
#include <WindowsConstants.au3>
#include <MsgBoxConstants.au3>
#include <Misc.au3>

$aTSR = _GetTotalScreenResolution()
ConsoleWrite("before -> Total Screen Resolution: " & $aTSR[0] & " x " & $aTSR[1] & @CRLF)

; Initialization
DllCall("user32.dll", "bool", "SetProcessDpiAwarenessContext", "int", -4) ; -4=PerMonitorAwareV2

$aTSR = _GetTotalScreenResolution()
ConsoleWrite("after  -> Total Screen Resolution: " & $aTSR[0] & " x " & $aTSR[1] & @CRLF)
ConsoleWrite("Desktop: " & @DesktopWidth & "x" & @DesktopHeight & @CRLF)
ConsoleWrite("" & @CRLF)

Global $hDLL = DllOpen("user32.dll")
HotKeySet("{END}", "_Main")  ; * <- selection of outer area with margin
HotKeySet("{ESC}", "_Exit")

;**********************************
While 1
    Switch GUIGetMsg()
        Case -3 ;$GUI_EVENT_CLOSE
            ExitLoop
    EndSwitch
WEnd
;**********************************
_Exit()


Func _Exit()
    DllClose($hDLL)
    Exit
EndFunc   ;==>_Exit

Func _Main()   ; Main Program
    Local $aArea = SelectArea() ; Define the area to scan
    Local $hColor = 0x00FF00

    ; Capture the color map for the specified area
    Local $aColorMap = CaptureAreaColorMap($aArea)
    ;_ArrayDisplay($aColorMap)

    ; set outer area manual
    ;_Test(61, 212, 287, 498)

    _Test($aArea[0], $aArea[1], $aArea[2], $aArea[3])

EndFunc   ;==>_Main

Func _Test($iLeft, $iTop, $iRight, $iBottom, $hColor = 0x00FF00)

    Local $aArea = [$iLeft, $iTop, $iRight, $iBottom] ; area to scan

    ; Capture the color map for the specified area
    Local $colorMap = CaptureAreaColorMap($aArea)
    ; _ArrayDisplay($colorMap)

    ; and then try to find digit positions
    Local $aNumArea = FindGreenBoundariesUsingColorMap($colorMap, $aArea, $hColor)
    ;Local $aNumArea = [$firstRow, $lastRow, $firstCol, $lastCol]

    Local $aMarkArea[4] = [$aArea[0] + $aNumArea[2], $aArea[1] + $aNumArea[0], _
            $aNumArea[3] - $aNumArea[2] + 1, $aNumArea[1] - $aNumArea[0] + 1]

    DRC($aMarkArea, 0xFF0000, "Color_Gui")

    ConsoleWrite("$MarkArea: x=" & $aMarkArea[0] & ", y=" & $aMarkArea[1] & ", w=" & $aMarkArea[2] & ", h=" & $aMarkArea[3] & @CRLF)


EndFunc   ;==>_Test

Func CaptureAreaColorMap($aArea)
    ; Initialize GDI+ to work with bitmaps
    _GDIPlus_Startup()

    ; Capture the screen area as a bitmap
    Local $hBitmap = _ScreenCapture_Capture("", $aArea[0], $aArea[1], $aArea[2], $aArea[3])

    ; Convert the captured bitmap to a GDI+ bitmap
    Local $hGDIPlusBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hBitmap)

    ; Get the width and height of the captured area
    Local $width = $aArea[2] - $aArea[0]
    Local $height = $aArea[3] - $aArea[1]

    ; Create an array to store color values
    Local $colorMap[$width][$height]

    ; Loop through each pixel in the bitmap and retrieve its color
    For $y = 0 To $height - 1
        For $x = 0 To $width - 1
            ; Get the pixel color from the bitmap in ARGB format
            Local $argbColor = _GDIPlus_BitmapGetPixel($hGDIPlusBitmap, $x, $y)
            ; Convert ARGB to BGR for comparison (ignore the alpha channel)
            Local $bgrColor = BitAND($argbColor, 0x00FFFFFF)
            $colorMap[$x][$y] = $bgrColor
        Next
    Next

    ; Cleanup resources
    _GDIPlus_BitmapDispose($hGDIPlusBitmap)
    _WinAPI_DeleteObject($hBitmap)
    _GDIPlus_Shutdown()

    Return $colorMap
EndFunc   ;==>CaptureAreaColorMap

Func FindGreenBoundariesUsingColorMap($colorMap, $aArea, $hColor = 0x00FF00)
    Local $width = UBound($colorMap, 1)
    Local $height = UBound($colorMap, 2)
    ConsoleWrite("$width=" & $width & ", $height=" & $height & @CRLF)

    Local $firstRow = -1, $lastRow = -1, $firstCol = -1, $lastCol = -1, $blockWidth = 0

    ; Scan for the first row with green color
    For $y = 0 To $height - 1
        For $x = 0 To $width - 1
            If $colorMap[$x][$y] = $hColor Then
                $firstRow = $y
                ExitLoop 2
            EndIf
        Next
    Next

    ; Scan for the last row with green color
    For $y = $height - 1 To 0 Step -1
        For $x = 0 To $width - 1
            If $colorMap[$x][$y] = $hColor Then
                $lastRow = $y
                ExitLoop 2
            EndIf
        Next
    Next

    ; Scan for the first column with green color
    For $x = 0 To $width - 1
        For $y = 0 To $height - 1
            If $colorMap[$x][$y] = $hColor Then
                $firstCol = $x
                ExitLoop 2
            EndIf
        Next
    Next

    ; Scan for the last column with green color
    For $x = $width - 1 To 0 Step -1
        For $y = 0 To $height - 1
            If $colorMap[$x][$y] = $hColor Then
                $lastCol = $x
                ExitLoop 2
            EndIf
        Next
    Next

    ; find the width of block pixel
    For $x = $firstCol To $width - 1
        For $y = $firstRow To $height - 1
            If $colorMap[$x][$y] = $hColor Then
                For $w = $x To $width - 1
                    If $colorMap[$w][$y] = $hColor Then
                        $blockWidth += 1
                    Else
                        ExitLoop 3
                    EndIf
                Next
            EndIf
        Next
    Next

    $blockSize = $blockWidth / 2
    ConsoleWrite("$blockSize=" & $blockSize & @CRLF)

    ; each number Display is a matrix of 14x20 Vpoint
    ; each Vpoint is a 3x3 pixel
    ; each number Display is 42x60 pixel

    ConsoleWrite("X:" & $aArea[0] & " Y:" & $aArea[1] & @CRLF)
    ConsoleWrite("Area firstRow:" & $firstRow & " lastRow:" & $lastRow & " firstCol:" & $firstCol & " lastCol:" & $lastCol & @CRLF)

    Local $aNumArea = [$firstRow, $lastRow, $firstCol, $lastCol]

    Return $aNumArea

EndFunc   ;==>FindGreenBoundariesUsingColorMap

;Original code by Larry.
;Edited by BrettF
Func _GetTotalScreenResolution()
    Local $aRet[2]
    Local Const $SM_CXVIRTUALSCREEN = 78
    Local Const $SM_VIRTUALHEIGHT = 79
    $VirtualDesktopWidth = DllCall("user32.dll", "int", "GetSystemMetrics", "int", $SM_CXVIRTUALSCREEN)
    $aRet[0] = $VirtualDesktopWidth[0]
    $VirtualDesktopHeight = DllCall("user32.dll", "int", "GetSystemMetrics", "int", $SM_VIRTUALHEIGHT)
    $aRet[1] = $VirtualDesktopHeight[0]
    Return $aRet
EndFunc   ;==>_GetTotalScreenResolution

;--------------------------------------------------------------------------------------------------------------------------------
Func SelectArea()   ; SelectArea

    Local $aRecPos[4], $aMPos[2], $tPos ;, $aTipPos[4], $iX, $iY
    Local $iDeskWidth, $iDeskHeight, $iDeskLeft, $iDeskTop
    Local $sDevice, $hMonitor, $sCurDevice, $aData, $Status = 0

    ; make Capture gui
    $hGUICapture = GUICreate("Capture_gui", 1, 1, 1, 1, $WS_POPUP, BitOR($WS_EX_TOOLWINDOW, $WS_EX_TOPMOST))
    GUISetBkColor("0xFFFF00", $hGUICapture) ; $COLOR_YELLOW
    WinSetTrans($hGUICapture, "", 50)

    ; make mouse block gui
    $block_gui = GUICreate("block_gui", 1, 1, 1, 1, $WS_POPUP, BitOR($WS_EX_TOOLWINDOW, $WS_EX_TOPMOST))
    WinSetTrans($block_gui, "", 1)
    GUISetState(@SW_SHOW, $block_gui)
    GUISetCursor($MCID_CROSS, 1, $block_gui)

    Sleep(200)

    Local $iMaxLoop = 1200, $iCntLoop = 0

    While Sleep(10)
        $iCntLoop += 1
        If $iCntLoop = $iMaxLoop Then ExitLoop

        ; get mouse coordinates
        $tPos = _WinAPI_GetMousePos()
        $aMPos[0] = DllStructGetData($tPos, 1)
        $aMPos[1] = DllStructGetData($tPos, 2)

        ; get $hMonitor from previously defined Mouse coordinates
        $hMonitor = _WinAPI_MonitorFromPoint($tPos)

        ; get monitor $aData appropriate for previously defined coordinates
        $aData = _WinAPI_GetMonitorInfo($hMonitor)
        If Not @error Then
            $sDevice = $aData[3]
            $iDeskLeft = DllStructGetData($aData[0], 1)
            $iDeskTop = DllStructGetData($aData[0], 2)
            $iDeskWidth = DllStructGetData($aData[0], 3)
            $iDeskHeight = DllStructGetData($aData[0], 4)
        EndIf

        ;move the $block_gui to active monitor
        If $sCurDevice <> $sDevice Then
            $sCurDevice = $sDevice
            ;ConsoleWrite("- $sCurDevice=" & $sCurDevice & @CRLF)
            WinMove($block_gui, "", $iDeskLeft, $iDeskTop, $iDeskWidth, $iDeskHeight)
        EndIf

        ; whait  Left_mouse_button _IsPressed
        If _IsPressed("01", $hDLL) Then
            $Status = 1
            $aMPos = MouseGetPos()
            $aRecPos[0] = $aMPos[0]
            $aRecPos[1] = $aMPos[1]

            ; Wait until key is released.
            While _IsPressed("01", $hDLL)
                Sleep(50)
                $aMPos = MouseGetPos()
                $aRecPos[2] = $aMPos[0]
                $aRecPos[3] = $aMPos[1]

                ; show Capture gui
                GUISetState(@SW_SHOW, $hGUICapture)
                WinMove($hGUICapture, "", $aRecPos[0], $aRecPos[1], $aRecPos[2] - $aRecPos[0], $aRecPos[3] - $aRecPos[1])
            WEnd
        ElseIf _IsPressed("1B", $hDLL) Then ;1B=ESC key - emergency exit
            GUIDelete($hGUICapture)
            GUIDelete($block_gui)
            Return SetError(1, 1, 0)
        EndIf

        If $Status = 1 Then ExitLoop
    WEnd

    GUIDelete($hGUICapture)
    GUIDelete($block_gui)

    ConsoleWrite("outer area: " & $aRecPos[0] & ";" & $aRecPos[1] & ";" & $aRecPos[2] + $aRecPos[0] & ";" & $aRecPos[3] + $aRecPos[1] & @CRLF)

    Return $aRecPos

EndFunc   ;==>SelectArea

Func DRC($aArray, $color = 0xFFFF00, $sTitle = "Gui")
    Local $gGUI = GUICreate($sTitle, $aArray[2], $aArray[3], $aArray[0], $aArray[1], $WS_POPUP, $WS_EX_TRANSPARENT)
    GUISetBkColor($color)
    WinSetTrans($gGUI, '', 150)
    GUISetState(@SW_SHOW, $gGUI)
    Return $gGUI
EndFunc   ;==>DRC

 

My console output

before -> Total Screen Resolution: 3840 x 1341
after  -> Total Screen Resolution: 5760 x 2160
Desktop: 1920x1080

outer area: 124;273;426;670
$width=178, $height=124
$blockSize=3
X:124 Y:273
Area firstRow:29 lastRow:88 firstCol:43 lastCol:123
$MarkArea: x=167, y=302, w=81, h=60

 

This one also has a bug/bad error-handling in it, "variable subscript badly formatted" on line 166.

6 hours ago, ioa747 said:

P.S.:
upload some numbers to 100% like this 
to make the rest num patterns and some test

 

Here are all the digits and some extra examples.

000000.png

000001.png

000002.png

000013.png

000031.png

000048.png

000049.png

000058.png

000059.png

000060.png

000063.png

Edited by Hashim
Link to comment
Share on other sites

this is for small numbers like 000000.png

I simplified the process as much as possible by removing the unnecessary stuff like the area selector.

; https://www.autoitscript.com/forum/topic/211521-ocr-from-a-small-area/?do=findComment&comment=1538057
; Version: 4.0

#include <GDIPlus.au3>
#include <Array.au3>
#include <File.au3>

Local $Result = _GetNumber(@ScriptDir & "\100num\152.png")
MsgBox($MB_SYSTEMMODAL, "_GetNumber", $Result)

;~ Test(@ScriptDir & "\100num")

;--------------------------------------------------------------------------------------------------------------------------------
Func _GetNumber($sFileName, $hColor = 0x00FF00)   ; Main Program
    ; Capture the color map for the specified area
    Local $aColorMap = CaptureAreaColorMap($sFileName)
;~  _ArrayDisplay($aColorMap)

    Local $Result = FindNumberUsingColorMap($aColorMap, $hColor)
;~  MsgBox($MB_SYSTEMMODAL, "$Result", $Result)
    Return $Result
EndFunc   ;==>_GetNumber
;--------------------------------------------------------------------------------------------------------------------------------
Func CaptureAreaColorMap($sFileName)   ; create color map array
    ; Initialize GDI+ to work with bitmaps
    _GDIPlus_Startup()

    ; Capture the screen area as a bitmap
    Local $hBitmap = _GDIPlus_BitmapCreateFromFile($sFileName)

    ; Get the width and height of the captured area
    Local $width = _GDIPlus_ImageGetWidth($hBitmap)
    Local $height = _GDIPlus_ImageGetHeight($hBitmap)
;~  ConsoleWrite("Image: $width=" & $width & ", $height=" & $height & @CRLF)

    ; Create an array to store color values
    Local $aColorMap[$width][$height]

    ; Loop through each pixel in the bitmap and retrieve its color
    For $y = 0 To $height - 1
        For $x = 0 To $width - 1
            ; Get the pixel color from the bitmap in ARGB format
            Local $argbColor = _GDIPlus_BitmapGetPixel($hBitmap, $x, $y)
            ; Convert ARGB to BGR for comparison (ignore the alpha channel)
            Local $bgrColor = BitAND($argbColor, 0x00FFFFFF)
            $aColorMap[$x][$y] = $bgrColor
        Next
    Next

    ; Cleanup resources
    _GDIPlus_BitmapDispose($hBitmap)
    _GDIPlus_Shutdown()

    Return $aColorMap
EndFunc   ;==>CaptureAreaColorMap
;--------------------------------------------------------------------------------------------------------------------------------
Func FindNumberUsingColorMap($aColorMap, $hColor = 0x00FF00)   ; find number in color map array
    Local $width = UBound($aColorMap, 1)
    Local $height = UBound($aColorMap, 2)

    Local $firstRow = -1, $lastRow = -1, $firstCol = -1, $lastCol = -1

    ; Scan for the first and last rows and columns with $hColor pixels
    For $y = 0 To $height - 1
        For $x = 0 To $width - 1
            If $aColorMap[$x][$y] = $hColor Then
                If $firstRow = -1 Then $firstRow = $y
                $lastRow = $y
                If $firstCol = -1 Or $x < $firstCol Then $firstCol = $x
                If $lastCol = -1 Or $x > $lastCol Then $lastCol = $x
            EndIf
        Next
    Next

    If $firstRow = -1 Or $lastRow = -1 Or $firstCol = -1 Or $lastCol = -1 Then
        MsgBox($MB_SYSTEMMODAL, "LineNumber:" & @ScriptLineNumber, "No color found" & @TAB & @TAB)
        Exit
    EndIf

    ; each number Display is a matrix of 14x20 pixels
    Local $numberWidth = 14 ; set number width per digit
    Local $numberSpace = 2  ; set Space between digits

    Local $Empty = 0, $Corection = 0

    ; Corection for boundaries if 1st digit = 1
    For $x = $firstCol To $lastCol - 1
        If $aColorMap[$x][$firstRow] = 0x000000 Then
            $Empty += 1
            If $Empty = 3 Then
                ;found 1st Space between digits
                $Corection = $firstCol - 1 - Abs($x - $numberWidth - $numberSpace)
                ExitLoop
            EndIf
        Else
            $Empty = 0
        EndIf
    Next

    If $Corection > 0 Then $firstCol = $firstCol - $Corection

    Local $numberStart = $firstCol

;~  ConsoleWrite("$Corection=" & $Corection & @CRLF)
;~  ConsoleWrite("Display_boundaries firstRow:" & $firstRow & " lastRow:" & $lastRow & " firstCol:" & $firstCol & " lastCol:" & $lastCol & @CRLF)
;~  ConsoleWrite("" & @CRLF)

    Local $aNum[11][3]

    ; Define boundaries for each number position
    For $i = 1 To 10
        $aNum[$i][0] = $numberStart
        $aNum[$i][1] = $numberStart + $numberWidth
        If $numberStart + $numberWidth + $numberSpace > $lastCol Then ExitLoop
        $numberStart += $numberWidth + $numberSpace
        $aNum[0][0] = $i + 1
    Next

    Local $sNumber

    ; Generate patterns for each found number
    For $i = 1 To $aNum[0][0]
        Local $sPattern = ""
        For $y = $firstRow To $lastRow
            For $x = $aNum[$i][0] To $aNum[$i][1] - 1
                If $aColorMap[$x][$y] = $hColor Then
                    $sPattern &= "1"
                Else
                    $sPattern &= "."
                EndIf
            Next
            $sPattern &= @CRLF
        Next
        $sNumber &= _GetPattern($sPattern)
    Next

    Return $sNumber
EndFunc   ;==>FindNumberUsingColorMap
;--------------------------------------------------------------------------------------------------------------------------------
Func _GetPattern($sPattern)  ; patterns for each digit
;~  ConsoleWrite("**************" & @CRLF & $sPattern & @CRLF)
    Local $aNumber[10]

    ; Define simplified patterns for each digit

    $aNumber[0] = "" ; Pattern for '0'
    $aNumber[0] &= "...11.11.11..." & @CRLF
    $aNumber[0] &= "...11.11.11..." & @CRLF
    $aNumber[0] &= ".............." & @CRLF
    $aNumber[0] &= "11..........11" & @CRLF
    $aNumber[0] &= "11..........11" & @CRLF
    $aNumber[0] &= ".............." & @CRLF
    $aNumber[0] &= "11.......11.11" & @CRLF
    $aNumber[0] &= "11.......11.11" & @CRLF
    $aNumber[0] &= ".............." & @CRLF
    $aNumber[0] &= "11....11....11" & @CRLF
    $aNumber[0] &= "11....11....11" & @CRLF
    $aNumber[0] &= ".............." & @CRLF
    $aNumber[0] &= "11.11.......11" & @CRLF
    $aNumber[0] &= "11.11.......11" & @CRLF
    $aNumber[0] &= ".............." & @CRLF
    $aNumber[0] &= "11..........11" & @CRLF
    $aNumber[0] &= "11..........11" & @CRLF
    $aNumber[0] &= ".............." & @CRLF
    $aNumber[0] &= "...11.11.11..." & @CRLF
    $aNumber[0] &= "...11.11.11..." & @CRLF


    $aNumber[1] = "" ; Pattern for '1'
    $aNumber[1] &= "......11......" & @CRLF
    $aNumber[1] &= "......11......" & @CRLF
    $aNumber[1] &= ".............." & @CRLF
    $aNumber[1] &= "...11.11......" & @CRLF
    $aNumber[1] &= "...11.11......" & @CRLF
    $aNumber[1] &= ".............." & @CRLF
    $aNumber[1] &= "......11......" & @CRLF
    $aNumber[1] &= "......11......" & @CRLF
    $aNumber[1] &= ".............." & @CRLF
    $aNumber[1] &= "......11......" & @CRLF
    $aNumber[1] &= "......11......" & @CRLF
    $aNumber[1] &= ".............." & @CRLF
    $aNumber[1] &= "......11......" & @CRLF
    $aNumber[1] &= "......11......" & @CRLF
    $aNumber[1] &= ".............." & @CRLF
    $aNumber[1] &= "......11......" & @CRLF
    $aNumber[1] &= "......11......" & @CRLF
    $aNumber[1] &= ".............." & @CRLF
    $aNumber[1] &= "...11.11.11..." & @CRLF
    $aNumber[1] &= "...11.11.11..." & @CRLF


    $aNumber[2] = "" ; Pattern for '2'
    $aNumber[2] &= "...11.11.11..." & @CRLF
    $aNumber[2] &= "...11.11.11..." & @CRLF
    $aNumber[2] &= ".............." & @CRLF
    $aNumber[2] &= "11..........11" & @CRLF
    $aNumber[2] &= "11..........11" & @CRLF
    $aNumber[2] &= ".............." & @CRLF
    $aNumber[2] &= "............11" & @CRLF
    $aNumber[2] &= "............11" & @CRLF
    $aNumber[2] &= ".............." & @CRLF
    $aNumber[2] &= "......11.11..." & @CRLF
    $aNumber[2] &= "......11.11..." & @CRLF
    $aNumber[2] &= ".............." & @CRLF
    $aNumber[2] &= "...11........." & @CRLF
    $aNumber[2] &= "...11........." & @CRLF
    $aNumber[2] &= ".............." & @CRLF
    $aNumber[2] &= "11............" & @CRLF
    $aNumber[2] &= "11............" & @CRLF
    $aNumber[2] &= ".............." & @CRLF
    $aNumber[2] &= "11.11.11.11.11" & @CRLF
    $aNumber[2] &= "11.11.11.11.11" & @CRLF


    $aNumber[3] = "" ; Pattern for '3'
    $aNumber[3] &= "...11.11.11..." & @CRLF
    $aNumber[3] &= "...11.11.11..." & @CRLF
    $aNumber[3] &= ".............." & @CRLF
    $aNumber[3] &= "11..........11" & @CRLF
    $aNumber[3] &= "11..........11" & @CRLF
    $aNumber[3] &= ".............." & @CRLF
    $aNumber[3] &= "............11" & @CRLF
    $aNumber[3] &= "............11" & @CRLF
    $aNumber[3] &= ".............." & @CRLF
    $aNumber[3] &= "......11.11..." & @CRLF
    $aNumber[3] &= "......11.11..." & @CRLF
    $aNumber[3] &= ".............." & @CRLF
    $aNumber[3] &= "............11" & @CRLF
    $aNumber[3] &= "............11" & @CRLF
    $aNumber[3] &= ".............." & @CRLF
    $aNumber[3] &= "11..........11" & @CRLF
    $aNumber[3] &= "11..........11" & @CRLF
    $aNumber[3] &= ".............." & @CRLF
    $aNumber[3] &= "...11.11.11..." & @CRLF
    $aNumber[3] &= "...11.11.11..." & @CRLF


    $aNumber[4] = "" ; Pattern for '4'
    $aNumber[4] &= ".........11..." & @CRLF
    $aNumber[4] &= ".........11..." & @CRLF
    $aNumber[4] &= ".............." & @CRLF
    $aNumber[4] &= "......11.11..." & @CRLF
    $aNumber[4] &= "......11.11..." & @CRLF
    $aNumber[4] &= ".............." & @CRLF
    $aNumber[4] &= "...11....11..." & @CRLF
    $aNumber[4] &= "...11....11..." & @CRLF
    $aNumber[4] &= ".............." & @CRLF
    $aNumber[4] &= "11.......11..." & @CRLF
    $aNumber[4] &= "11.......11..." & @CRLF
    $aNumber[4] &= ".............." & @CRLF
    $aNumber[4] &= "11.11.11.11.11" & @CRLF
    $aNumber[4] &= "11.11.11.11.11" & @CRLF
    $aNumber[4] &= ".............." & @CRLF
    $aNumber[4] &= ".........11..." & @CRLF
    $aNumber[4] &= ".........11..." & @CRLF
    $aNumber[4] &= ".............." & @CRLF
    $aNumber[4] &= ".........11..." & @CRLF
    $aNumber[4] &= ".........11..." & @CRLF


    $aNumber[5] = "" ; Pattern for '5'
    $aNumber[5] &= "11.11.11.11.11" & @CRLF
    $aNumber[5] &= "11.11.11.11.11" & @CRLF
    $aNumber[5] &= ".............." & @CRLF
    $aNumber[5] &= "11............" & @CRLF
    $aNumber[5] &= "11............" & @CRLF
    $aNumber[5] &= ".............." & @CRLF
    $aNumber[5] &= "11.11.11.11..." & @CRLF
    $aNumber[5] &= "11.11.11.11..." & @CRLF
    $aNumber[5] &= ".............." & @CRLF
    $aNumber[5] &= "............11" & @CRLF
    $aNumber[5] &= "............11" & @CRLF
    $aNumber[5] &= ".............." & @CRLF
    $aNumber[5] &= "............11" & @CRLF
    $aNumber[5] &= "............11" & @CRLF
    $aNumber[5] &= ".............." & @CRLF
    $aNumber[5] &= "11..........11" & @CRLF
    $aNumber[5] &= "11..........11" & @CRLF
    $aNumber[5] &= ".............." & @CRLF
    $aNumber[5] &= "...11.11.11..." & @CRLF
    $aNumber[5] &= "...11.11.11..." & @CRLF


    $aNumber[6] = "" ; Pattern for '6'
    $aNumber[6] &= "......11.11..." & @CRLF
    $aNumber[6] &= "......11.11..." & @CRLF
    $aNumber[6] &= ".............." & @CRLF
    $aNumber[6] &= "...11........." & @CRLF
    $aNumber[6] &= "...11........." & @CRLF
    $aNumber[6] &= ".............." & @CRLF
    $aNumber[6] &= "11............" & @CRLF
    $aNumber[6] &= "11............" & @CRLF
    $aNumber[6] &= ".............." & @CRLF
    $aNumber[6] &= "11.11.11.11..." & @CRLF
    $aNumber[6] &= "11.11.11.11..." & @CRLF
    $aNumber[6] &= ".............." & @CRLF
    $aNumber[6] &= "11..........11" & @CRLF
    $aNumber[6] &= "11..........11" & @CRLF
    $aNumber[6] &= ".............." & @CRLF
    $aNumber[6] &= "11..........11" & @CRLF
    $aNumber[6] &= "11..........11" & @CRLF
    $aNumber[6] &= ".............." & @CRLF
    $aNumber[6] &= "...11.11.11..." & @CRLF
    $aNumber[6] &= "...11.11.11..." & @CRLF

    $aNumber[7] = "" ; Pattern for '7'
    $aNumber[7] &= "11.11.11.11.11" & @CRLF
    $aNumber[7] &= "11.11.11.11.11" & @CRLF
    $aNumber[7] &= ".............." & @CRLF
    $aNumber[7] &= "............11" & @CRLF
    $aNumber[7] &= "............11" & @CRLF
    $aNumber[7] &= ".............." & @CRLF
    $aNumber[7] &= ".........11..." & @CRLF
    $aNumber[7] &= ".........11..." & @CRLF
    $aNumber[7] &= ".............." & @CRLF
    $aNumber[7] &= "......11......" & @CRLF
    $aNumber[7] &= "......11......" & @CRLF
    $aNumber[7] &= ".............." & @CRLF
    $aNumber[7] &= "...11........." & @CRLF
    $aNumber[7] &= "...11........." & @CRLF
    $aNumber[7] &= ".............." & @CRLF
    $aNumber[7] &= "...11........." & @CRLF
    $aNumber[7] &= "...11........." & @CRLF
    $aNumber[7] &= ".............." & @CRLF
    $aNumber[7] &= "...11........." & @CRLF
    $aNumber[7] &= "...11........." & @CRLF

    $aNumber[8] = "" ; Pattern for '8'
    $aNumber[8] &= "...11.11.11..." & @CRLF
    $aNumber[8] &= "...11.11.11..." & @CRLF
    $aNumber[8] &= ".............." & @CRLF
    $aNumber[8] &= "11..........11" & @CRLF
    $aNumber[8] &= "11..........11" & @CRLF
    $aNumber[8] &= ".............." & @CRLF
    $aNumber[8] &= "11..........11" & @CRLF
    $aNumber[8] &= "11..........11" & @CRLF
    $aNumber[8] &= ".............." & @CRLF
    $aNumber[8] &= "...11.11.11..." & @CRLF
    $aNumber[8] &= "...11.11.11..." & @CRLF
    $aNumber[8] &= ".............." & @CRLF
    $aNumber[8] &= "11..........11" & @CRLF
    $aNumber[8] &= "11..........11" & @CRLF
    $aNumber[8] &= ".............." & @CRLF
    $aNumber[8] &= "11..........11" & @CRLF
    $aNumber[8] &= "11..........11" & @CRLF
    $aNumber[8] &= ".............." & @CRLF
    $aNumber[8] &= "...11.11.11..." & @CRLF
    $aNumber[8] &= "...11.11.11..." & @CRLF

    $aNumber[9] = "" ; Pattern for '9'
    $aNumber[9] &= "...11.11.11..." & @CRLF
    $aNumber[9] &= "...11.11.11..." & @CRLF
    $aNumber[9] &= ".............." & @CRLF
    $aNumber[9] &= "11..........11" & @CRLF
    $aNumber[9] &= "11..........11" & @CRLF
    $aNumber[9] &= ".............." & @CRLF
    $aNumber[9] &= "11..........11" & @CRLF
    $aNumber[9] &= "11..........11" & @CRLF
    $aNumber[9] &= ".............." & @CRLF
    $aNumber[9] &= "...11.11.11.11" & @CRLF
    $aNumber[9] &= "...11.11.11.11" & @CRLF
    $aNumber[9] &= ".............." & @CRLF
    $aNumber[9] &= "............11" & @CRLF
    $aNumber[9] &= "............11" & @CRLF
    $aNumber[9] &= ".............." & @CRLF
    $aNumber[9] &= ".........11..." & @CRLF
    $aNumber[9] &= ".........11..." & @CRLF
    $aNumber[9] &= ".............." & @CRLF
    $aNumber[9] &= "...11.11......" & @CRLF
    $aNumber[9] &= "...11.11......" & @CRLF


    Switch $sPattern
        Case $aNumber[0]
            Return 0
        Case $aNumber[1]
            Return 1
        Case $aNumber[2]
            Return 2
        Case $aNumber[3]
            Return 3
        Case $aNumber[4]
            Return 4
        Case $aNumber[5]
            Return 5
        Case $aNumber[6]
            Return 6
        Case $aNumber[7]
            Return 7
        Case $aNumber[8]
            Return 8
        Case $aNumber[9]
            Return 9
        Case Else
            Return SetError(1, 0, "")
    EndSwitch
EndFunc   ;==>_GetPattern
;--------------------------------------------------------------------------------------------------------------------------------
Func Test($sFilePath)   ; _GetNumber for all the *.png files in $sFilePath directory
    ; List all the *.png files in $sFilePath directory
    Local $aFileList = _FileListToArray($sFilePath, "*.png", $FLTA_FILES)
    If @error = 1 Then
        MsgBox($MB_SYSTEMMODAL, "LineNumber:" & @ScriptLineNumber, "Path was invalid.")
        Exit
    EndIf
    If @error = 4 Then
        MsgBox($MB_SYSTEMMODAL, "LineNumber:" & @ScriptLineNumber, "No file(s) were found.")
        Exit
    EndIf

    _ArrayColInsert($aFileList, 1) ; add 1 column to hold the numbers
    For $i = 1 To $aFileList[0][0]
        $aFileList[$i][1] = _GetNumber($sFilePath & "\" & $aFileList[$i][0])

        ; Rename a file using FileMove and overwrite the new file if it exists.
;~      FileMove($sFilePath & "\" & $aFileList[$i][0], $sFilePath & "\" & $aFileList[$i][1] & ".png", $FC_OVERWRITE)
    Next

    _ArrayDisplay($aFileList, "$aFileList")
EndFunc   ;==>Test
;--------------------------------------------------------------------------------------------------------------------------------

 

Edited by ioa747
Update to Version: 4.0

I know that I know nothing

Link to comment
Share on other sites

26 minutes ago, ioa747 said:

this is for small numbers like 000000.png

I simplified the process as much as possible by removing the unnecessary stuff like the area selector.

; https://www.autoitscript.com/forum/topic/211521-ocr-from-a-small-area/?do=findComment&comment=1538057
; Version: 1.0

#include <GDIPlus.au3>
#include <Array.au3>

_Main(@ScriptDir & "\100num\152.png")

;--------------------------------------------------------------------------------------------------------------------------------
Func _Main($sFileName, $hColor = 0x00FF00)   ; Main Program

    ; Capture the color map for the specified area
    Local $aColorMap = CaptureAreaColorMap($sFileName)
;~  _ArrayDisplay($aColorMap)

    Local $Result = FindNumberUsingColorMap($aColorMap, $hColor)
    MsgBox($MB_SYSTEMMODAL, "$Result", $Result)
EndFunc   ;==>_Main
;--------------------------------------------------------------------------------------------------------------------------------
Func CaptureAreaColorMap($sFileName)
    ; Initialize GDI+ to work with bitmaps
    _GDIPlus_Startup()

    ; Capture the screen area as a bitmap
    Local $hBitmap = _GDIPlus_BitmapCreateFromFile($sFileName)

    ; Get the width and height of the captured area
    Local $width = _GDIPlus_ImageGetWidth($hBitmap)
    Local $height = _GDIPlus_ImageGetHeight($hBitmap)
    ConsoleWrite("Image: $width=" & $width & ", $height=" & $height & @CRLF)

    ; Create an array to store color values
    Local $aColorMap[$width][$height]

    ; Loop through each pixel in the bitmap and retrieve its color
    For $y = 0 To $height - 1
        For $x = 0 To $width - 1
            ; Get the pixel color from the bitmap in ARGB format
            Local $argbColor = _GDIPlus_BitmapGetPixel($hBitmap, $x, $y)
            ; Convert ARGB to BGR for comparison (ignore the alpha channel)
            Local $bgrColor = BitAND($argbColor, 0x00FFFFFF)
            $aColorMap[$x][$y] = $bgrColor
        Next
    Next

    ; Cleanup resources
    _GDIPlus_BitmapDispose($hBitmap)
    _GDIPlus_Shutdown()

    Return $aColorMap
EndFunc   ;==>CaptureAreaColorMap
;--------------------------------------------------------------------------------------------------------------------------------
Func FindNumberUsingColorMap($aColorMap, $hColor = 0x00FF00)
    Local $width = UBound($aColorMap, 1)
    Local $height = UBound($aColorMap, 2)

    Local $firstRow = -1, $lastRow = -1, $firstCol = -1, $lastCol = -1, $blockWidth = 0

    ; Scan for the first and last rows and columns with green pixels
    For $y = 0 To $height - 1
        For $x = 0 To $width - 1
            If $aColorMap[$x][$y] = $hColor Then
                If $firstRow = -1 Then $firstRow = $y
                $lastRow = $y
                If $firstCol = -1 Or $x < $firstCol Then $firstCol = $x
                If $lastCol = -1 Or $x > $lastCol Then $lastCol = $x
            EndIf
        Next
    Next

    If $firstRow = -1 Or $lastRow = -1 Or $firstCol = -1 Or $lastCol = -1 Then
        MsgBox($MB_SYSTEMMODAL, "LineNumber:" & @ScriptLineNumber, "No color found" & @TAB & @TAB)
        Exit
    EndIf

    ; Calculate block size for one digit
    For $x = $firstCol To $width - 1
        For $y = $firstRow To $height - 1
            If $aColorMap[$x][$y] = $hColor Then
                For $w = $x To $width - 1
                    If $aColorMap[$w][$y] = $hColor Then
                        $blockWidth += 1
                    Else
                        ExitLoop 3
                    EndIf
                Next
            EndIf
        Next
    Next

    Local $blockSize = $blockWidth / 2 ; Adjust based on actual digit width
    Local $numberWidth = 14 * $blockSize ; Adjust based on number of columns per digit
    Local $numberSpace = 2 * $blockSize ; Space between digits

    Local $Empty = 0, $Corection = 0
    For $x = $firstCol To $lastCol - 1
        If $aColorMap[$x][$firstRow] = 0x000000 Then
            $Empty += 1
            If $Empty = 3 * $blockSize Then
                ;found 1st Space between digits
                $Corection =  $firstCol - 1 - Abs($x - $numberWidth - $numberSpace)
                ConsoleWrite("$Corection=" & $Corection & @CRLF)
                ExitLoop
            EndIf
        Else
            $Empty = 0
        EndIf
    Next

    Local $numberStart = $firstCol - $Corection
    ConsoleWrite("$numberStart=" & $numberStart & @CRLF)
    Local $aNum[11][3]

    ; Define boundaries for each number position
    For $i = 1 To 10
        $aNum[$i][0] = $numberStart
        $aNum[$i][1] = $numberStart + $numberWidth
        If $numberStart + $numberWidth + $numberSpace > $lastCol Then ExitLoop
        $numberStart += $numberWidth + $numberSpace
        $aNum[0][0] = $i + 1
    Next

    Local $sNumber

    ; Generate patterns for each found number
    For $i = 1 To $aNum[0][0]
        Local $sPattern = ""
        For $y = $firstRow To $lastRow
            For $x = $aNum[$i][0] To $aNum[$i][1] - 1
                If $aColorMap[$x][$y] = $hColor Then
                    $sPattern &= "1"
                Else
                    $sPattern &= "."
                EndIf
            Next
            $sPattern &= @CRLF
        Next
        $sNumber &= _GetNumber($sPattern)
    Next

    ; each number Display is a matrix of 14x20 Vpoint

    ConsoleWrite("$blockSize=" & $blockSize & @CRLF)
    ConsoleWrite("Display_boundaries firstRow:" & $firstRow & " lastRow:" & $lastRow & " firstCol:" & $firstCol & " lastCol:" & $lastCol & @CRLF)

    Return $sNumber
EndFunc   ;==>FindNumberUsingColorMap
;--------------------------------------------------------------------------------------------------------------------------------
Func _GetNumber($sPattern)
    ConsoleWrite("***************" & @CRLF & $sPattern & @CRLF)
    Local $aNumber[10]

    ; Define simplified patterns for each digit

    $aNumber[0] = "" ; Pattern for '0'
    $aNumber[0] &= "...11.11.11..." & @CRLF
    $aNumber[0] &= "...11.11.11..." & @CRLF
    $aNumber[0] &= ".............." & @CRLF
    $aNumber[0] &= "11..........11" & @CRLF
    $aNumber[0] &= "11..........11" & @CRLF
    $aNumber[0] &= ".............." & @CRLF
    $aNumber[0] &= "11.......11.11" & @CRLF
    $aNumber[0] &= "11.......11.11" & @CRLF
    $aNumber[0] &= ".............." & @CRLF
    $aNumber[0] &= "11....11....11" & @CRLF
    $aNumber[0] &= "11....11....11" & @CRLF
    $aNumber[0] &= ".............." & @CRLF
    $aNumber[0] &= "11.11.......11" & @CRLF
    $aNumber[0] &= "11.11.......11" & @CRLF
    $aNumber[0] &= ".............." & @CRLF
    $aNumber[0] &= "11..........11" & @CRLF
    $aNumber[0] &= "11..........11" & @CRLF
    $aNumber[0] &= ".............." & @CRLF
    $aNumber[0] &= "...11.11.11..." & @CRLF
    $aNumber[0] &= "...11.11.11..." & @CRLF


    $aNumber[1] = "" ; Pattern for '1'
    $aNumber[1] &= "......11......" & @CRLF
    $aNumber[1] &= "......11......" & @CRLF
    $aNumber[1] &= ".............." & @CRLF
    $aNumber[1] &= "...11.11......" & @CRLF
    $aNumber[1] &= "...11.11......" & @CRLF
    $aNumber[1] &= ".............." & @CRLF
    $aNumber[1] &= "......11......" & @CRLF
    $aNumber[1] &= "......11......" & @CRLF
    $aNumber[1] &= ".............." & @CRLF
    $aNumber[1] &= "......11......" & @CRLF
    $aNumber[1] &= "......11......" & @CRLF
    $aNumber[1] &= ".............." & @CRLF
    $aNumber[1] &= "......11......" & @CRLF
    $aNumber[1] &= "......11......" & @CRLF
    $aNumber[1] &= ".............." & @CRLF
    $aNumber[1] &= "......11......" & @CRLF
    $aNumber[1] &= "......11......" & @CRLF
    $aNumber[1] &= ".............." & @CRLF
    $aNumber[1] &= "...11.11.11..." & @CRLF
    $aNumber[1] &= "...11.11.11..." & @CRLF


    $aNumber[2] = "" ; Pattern for '2'
    $aNumber[2] &= "...11.11.11..." & @CRLF
    $aNumber[2] &= "...11.11.11..." & @CRLF
    $aNumber[2] &= ".............." & @CRLF
    $aNumber[2] &= "11..........11" & @CRLF
    $aNumber[2] &= "11..........11" & @CRLF
    $aNumber[2] &= ".............." & @CRLF
    $aNumber[2] &= "............11" & @CRLF
    $aNumber[2] &= "............11" & @CRLF
    $aNumber[2] &= ".............." & @CRLF
    $aNumber[2] &= "......11.11..." & @CRLF
    $aNumber[2] &= "......11.11..." & @CRLF
    $aNumber[2] &= ".............." & @CRLF
    $aNumber[2] &= "...11........." & @CRLF
    $aNumber[2] &= "...11........." & @CRLF
    $aNumber[2] &= ".............." & @CRLF
    $aNumber[2] &= "11............" & @CRLF
    $aNumber[2] &= "11............" & @CRLF
    $aNumber[2] &= ".............." & @CRLF
    $aNumber[2] &= "11.11.11.11.11" & @CRLF
    $aNumber[2] &= "11.11.11.11.11" & @CRLF


    $aNumber[3] = "" ; Pattern for '3'
    $aNumber[3] &= "...11.11.11..." & @CRLF
    $aNumber[3] &= "...11.11.11..." & @CRLF
    $aNumber[3] &= ".............." & @CRLF
    $aNumber[3] &= "11..........11" & @CRLF
    $aNumber[3] &= "11..........11" & @CRLF
    $aNumber[3] &= ".............." & @CRLF
    $aNumber[3] &= "............11" & @CRLF
    $aNumber[3] &= "............11" & @CRLF
    $aNumber[3] &= ".............." & @CRLF
    $aNumber[3] &= "......11.11..." & @CRLF
    $aNumber[3] &= "......11.11..." & @CRLF
    $aNumber[3] &= ".............." & @CRLF
    $aNumber[3] &= "............11" & @CRLF
    $aNumber[3] &= "............11" & @CRLF
    $aNumber[3] &= ".............." & @CRLF
    $aNumber[3] &= "11..........11" & @CRLF
    $aNumber[3] &= "11..........11" & @CRLF
    $aNumber[3] &= ".............." & @CRLF
    $aNumber[3] &= "...11.11.11..." & @CRLF
    $aNumber[3] &= "...11.11.11..." & @CRLF


    $aNumber[4] = "" ; Pattern for '4'
    $aNumber[4] &= ".........11..." & @CRLF
    $aNumber[4] &= ".........11..." & @CRLF
    $aNumber[4] &= ".............." & @CRLF
    $aNumber[4] &= "......11.11..." & @CRLF
    $aNumber[4] &= "......11.11..." & @CRLF
    $aNumber[4] &= ".............." & @CRLF
    $aNumber[4] &= "...11....11..." & @CRLF
    $aNumber[4] &= "...11....11..." & @CRLF
    $aNumber[4] &= ".............." & @CRLF
    $aNumber[4] &= "11.......11..." & @CRLF
    $aNumber[4] &= "11.......11..." & @CRLF
    $aNumber[4] &= ".............." & @CRLF
    $aNumber[4] &= "11.11.11.11.11" & @CRLF
    $aNumber[4] &= "11.11.11.11.11" & @CRLF
    $aNumber[4] &= ".............." & @CRLF
    $aNumber[4] &= ".........11..." & @CRLF
    $aNumber[4] &= ".........11..." & @CRLF
    $aNumber[4] &= ".............." & @CRLF
    $aNumber[4] &= ".........11..." & @CRLF
    $aNumber[4] &= ".........11..." & @CRLF


    $aNumber[5] = "" ; Pattern for '5'
    $aNumber[5] &= "11.11.11.11.11" & @CRLF
    $aNumber[5] &= "11.11.11.11.11" & @CRLF
    $aNumber[5] &= ".............." & @CRLF
    $aNumber[5] &= "11............" & @CRLF
    $aNumber[5] &= "11............" & @CRLF
    $aNumber[5] &= ".............." & @CRLF
    $aNumber[5] &= "11.11.11.11..." & @CRLF
    $aNumber[5] &= "11.11.11.11..." & @CRLF
    $aNumber[5] &= ".............." & @CRLF
    $aNumber[5] &= "............11" & @CRLF
    $aNumber[5] &= "............11" & @CRLF
    $aNumber[5] &= ".............." & @CRLF
    $aNumber[5] &= "............11" & @CRLF
    $aNumber[5] &= "............11" & @CRLF
    $aNumber[5] &= ".............." & @CRLF
    $aNumber[5] &= "11..........11" & @CRLF
    $aNumber[5] &= "11..........11" & @CRLF
    $aNumber[5] &= ".............." & @CRLF
    $aNumber[5] &= "...11.11.11..." & @CRLF
    $aNumber[5] &= "...11.11.11..." & @CRLF


    $aNumber[6] = "" ; Pattern for '6'
    $aNumber[6] &= "......11.11..." & @CRLF
    $aNumber[6] &= "......11.11..." & @CRLF
    $aNumber[6] &= ".............." & @CRLF
    $aNumber[6] &= "...11........." & @CRLF
    $aNumber[6] &= "...11........." & @CRLF
    $aNumber[6] &= ".............." & @CRLF
    $aNumber[6] &= "11............" & @CRLF
    $aNumber[6] &= "11............" & @CRLF
    $aNumber[6] &= ".............." & @CRLF
    $aNumber[6] &= "11.11.11.11..." & @CRLF
    $aNumber[6] &= "11.11.11.11..." & @CRLF
    $aNumber[6] &= ".............." & @CRLF
    $aNumber[6] &= "11..........11" & @CRLF
    $aNumber[6] &= "11..........11" & @CRLF
    $aNumber[6] &= ".............." & @CRLF
    $aNumber[6] &= "11..........11" & @CRLF
    $aNumber[6] &= "11..........11" & @CRLF
    $aNumber[6] &= ".............." & @CRLF
    $aNumber[6] &= "...11.11.11..." & @CRLF
    $aNumber[6] &= "...11.11.11..." & @CRLF

    $aNumber[7] = "" ; Pattern for '7'
    $aNumber[7] &= "11.11.11.11.11" & @CRLF
    $aNumber[7] &= "11.11.11.11.11" & @CRLF
    $aNumber[7] &= ".............." & @CRLF
    $aNumber[7] &= "............11" & @CRLF
    $aNumber[7] &= "............11" & @CRLF
    $aNumber[7] &= ".............." & @CRLF
    $aNumber[7] &= ".........11..." & @CRLF
    $aNumber[7] &= ".........11..." & @CRLF
    $aNumber[7] &= ".............." & @CRLF
    $aNumber[7] &= "......11......" & @CRLF
    $aNumber[7] &= "......11......" & @CRLF
    $aNumber[7] &= ".............." & @CRLF
    $aNumber[7] &= "...11........." & @CRLF
    $aNumber[7] &= "...11........." & @CRLF
    $aNumber[7] &= ".............." & @CRLF
    $aNumber[7] &= "...11........." & @CRLF
    $aNumber[7] &= "...11........." & @CRLF
    $aNumber[7] &= ".............." & @CRLF
    $aNumber[7] &= "...11........." & @CRLF
    $aNumber[7] &= "...11........." & @CRLF

    $aNumber[8] = "" ; Pattern for '8'
    $aNumber[8] &= "...11.11.11..." & @CRLF
    $aNumber[8] &= "...11.11.11..." & @CRLF
    $aNumber[8] &= ".............." & @CRLF
    $aNumber[8] &= "11..........11" & @CRLF
    $aNumber[8] &= "11..........11" & @CRLF
    $aNumber[8] &= ".............." & @CRLF
    $aNumber[8] &= "11..........11" & @CRLF
    $aNumber[8] &= "11..........11" & @CRLF
    $aNumber[8] &= ".............." & @CRLF
    $aNumber[8] &= "...11.11.11..." & @CRLF
    $aNumber[8] &= "...11.11.11..." & @CRLF
    $aNumber[8] &= ".............." & @CRLF
    $aNumber[8] &= "11..........11" & @CRLF
    $aNumber[8] &= "11..........11" & @CRLF
    $aNumber[8] &= ".............." & @CRLF
    $aNumber[8] &= "11..........11" & @CRLF
    $aNumber[8] &= "11..........11" & @CRLF
    $aNumber[8] &= ".............." & @CRLF
    $aNumber[8] &= "...11.11.11..." & @CRLF
    $aNumber[8] &= "...11.11.11..." & @CRLF

    $aNumber[9] = "" ; Pattern for '9'
    $aNumber[9] &= "...11.11.11..." & @CRLF
    $aNumber[9] &= "...11.11.11..." & @CRLF
    $aNumber[9] &= ".............." & @CRLF
    $aNumber[9] &= "11..........11" & @CRLF
    $aNumber[9] &= "11..........11" & @CRLF
    $aNumber[9] &= ".............." & @CRLF
    $aNumber[9] &= "11..........11" & @CRLF
    $aNumber[9] &= "11..........11" & @CRLF
    $aNumber[9] &= ".............." & @CRLF
    $aNumber[9] &= "...11.11.11.11" & @CRLF
    $aNumber[9] &= "...11.11.11.11" & @CRLF
    $aNumber[9] &= ".............." & @CRLF
    $aNumber[9] &= "............11" & @CRLF
    $aNumber[9] &= "............11" & @CRLF
    $aNumber[9] &= ".............." & @CRLF
    $aNumber[9] &= ".........11..." & @CRLF
    $aNumber[9] &= ".........11..." & @CRLF
    $aNumber[9] &= ".............." & @CRLF
    $aNumber[9] &= "...11.11......" & @CRLF
    $aNumber[9] &= "...11.11......" & @CRLF


    Switch $sPattern
        Case $aNumber[0]
            Return 0
        Case $aNumber[1]
            Return 1
        Case $aNumber[2]
            Return 2
        Case $aNumber[3]
            Return 3
        Case $aNumber[4]
            Return 4
        Case $aNumber[5]
            Return 5
        Case $aNumber[6]
            Return 6
        Case $aNumber[7]
            Return 7
        Case $aNumber[8]
            Return 8
        Case $aNumber[9]
            Return 9
        Case Else
            Return SetError(1, 0, "")
    EndSwitch
EndFunc   ;==>_GetNumber
;--------------------------------------------------------------------------------------------------------------------------------

 

 

Lightning fast as always! Unfortunately I still get an error, this time on line 33: No variable given for Dim, Local, Global Static or Const. Maybe related to this: 

Looks like a version-related syntax error but I'm not sure of the best way to fix, if it helps I'm using version 3.3.16.1 of AutoIt since I only installed it for this issue.

Edited by Hashim
Link to comment
Share on other sites

check the output of SciTEConfig ->  "Other Tools" -> "Run SutoIt3/SciTE check"
, so you can see what the active config is and your environment settings.

maybe you can draw a conclusion

I know that I know nothing

Link to comment
Share on other sites

make a test
 

#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7
#include <GDIPlus.au3>
#include <Array.au3>

CaptureAreaColorMap(@ScriptDir & "\100num\152.png")

Func CaptureAreaColorMap($sFileName)
    ; Initialize GDI+ to work with bitmaps
    _GDIPlus_Startup()

    ; Display a message of whether the file exists or not.
    Local $iFileExists = FileExists($sFileName)
    If $iFileExists Then
        MsgBox($MB_SYSTEMMODAL, "", "The file exists." & @CRLF & "FileExist returned: " & $iFileExists)
    Else
        MsgBox($MB_SYSTEMMODAL, "", "The file doesn't exist." & @CRLF & "FileExist returned: " & $iFileExists)
    EndIf

    ; Capture the screen area as a bitmap
    Local $hBitmap = _GDIPlus_BitmapCreateFromFile($sFileName)

    ; Get the width and height of the captured area
    Local $width = _GDIPlus_ImageGetWidth($hBitmap)
    Local $height = _GDIPlus_ImageGetHeight($hBitmap)
    ConsoleWrite("Image: $width=" & $width & ", $height=" & $height & @CRLF)

    MsgBox($MB_SYSTEMMODAL, "LineNumber:" & @ScriptLineNumber, "Image: $width=" & $width & ", $height=" & $height)

    ; Create an array to store color values
    Local $aColorMap[$width][$height]

    ; Loop through each pixel in the bitmap and retrieve its color
    For $y = 0 To $height - 1
        For $x = 0 To $width - 1
            ; Get the pixel color from the bitmap in ARGB format
            Local $argbColor = _GDIPlus_BitmapGetPixel($hBitmap, $x, $y)
            ; Convert ARGB to BGR for comparison (ignore the alpha channel)
            Local $bgrColor = BitAND($argbColor, 0x00FFFFFF)
            $aColorMap[$x][$y] = $bgrColor
        Next
    Next

    ; Cleanup resources
    _GDIPlus_BitmapDispose($hBitmap)
    _GDIPlus_Shutdown()

    _ArrayDisplay( $aColorMap)
EndFunc   ;==>CaptureAreaColorMap

 

I know that I know nothing

Link to comment
Share on other sites

Quote

...

Apologies my friend, it was my bad, I forgot the leading \ in the path to the image. The script now perfectly identifies almost all the digits/test images now (!), with the exception of 5. I tried having a look at the 5 pattern but it looks right to me unless I'm missing something. Once this 5 issue has been sorted, would it be safe to assume this will be 100% effective on all similar images to the test images?

Edited by Hashim
Link to comment
Share on other sites

in which 5? upload it.
the numbers you uploaded, whenever I checked them, they were successful
Now if you ask for guarantees, only you can give them after checking it for a while :)

I know that I know nothing

Link to comment
Share on other sites

Okay, on testing again it seems to be only those where the 5 is in the beginning - I generated some more examples below where the 5 is never recognised for me.

 

39 minutes ago, ioa747 said:

in which 5? upload it.
the numbers you uploaded, whenever I checked them, they were successful
Now if you ask for guarantees, only you can give them after checking it for a while :)

Fair enough, I assumed that because this was a bitmap solution rather than OCR it would be almost always accurate, I'll have to test and see, but at least it won't give false positives and I can easily check them as long as it's not more than 1% of the database (cause checking more than 10,000 inputs would take too long). Also please give me a PayPal link or other form of payment, let me buy you a few drinks for your patience and the time you've spent on this.

code_000068.png

code_000078.png

code_000088.png

code_000098.png

code_000008.png

code_000018.png

code_000028.png

code_000038.png

code_000048.png

code_000058.png

Edited by Hashim
Link to comment
Share on other sites

29 minutes ago, ioa747 said:


Update the script above to Version: 3.0 

 

Absolute legend, the update works perfectly on all the test images. I diffed the change you made and would never have even thought to make it. Come to think of it, how most of this program works is way over my head and I tip my hat off to the geniuses that contributed to it. As you wish, I have now made a donation to Jonathan Bennett as per the AutoIT donation link.

Link to comment
Share on other sites

ioa, I have a  question about your custom _GetText function (in the OP), specifically the parameter bUseOcrLine - what does it do and is it intended specifically for use with UWPOCR?

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...