hendrikhe Posted May 2, 2009 Share Posted May 2, 2009 (edited) I am using a OCR to capture text and numbers (tesseract). Well since the background disturb a good result I would like to changethe background in the picture.I took a look around and found that script interesting for me: http://www.autoitscript.com/forum/index.ph...ap+color+change.I modificated a bit but somehow the background keeps only black or white, whatever I do, I cant create a "blue" background for example.The idea is that the font has always the same color, so I change all pixel that not accords to the font color in black or white or blue, w.e.. so I get a very nice background color for the OCR programm.I had some success with white fonts, but with a kind of red font failed total.CODE#include-once#Include <Array.au3>#Include <File.au3>#include <GDIPlus.au3>#include <ScreenCapture.au3>#include <WinAPI.au3>#include <ScrollBarConstants.au3>#include <WindowsConstants.au3>#Include <GuiComboBox.au3>#Include <GuiListBox.au3>#include <GuiConstants.au3>#EndRegion Header#Region Global Variables and ConstantsGlobal $last_captureGlobal $tesseract_temp_path = "C:\"#EndRegion Global Variables and Constants#Region Core functions; #FUNCTION# ;===============================================================================;; Name...........: _TesseractTempPathSet(); Description ...: Sets the location where Tesseract functions temporary store their files.; You must have read and write access to this location.; The default location is "C:\".; Syntax.........: _TesseractTempPathSet($temp_path); Parameters ....: $temp_path - The path to use for temporary file storage.; This path must not contain any spaces (see "Remarks" below).; Return values .: On Success - Returns 1. ; On Failure - Returns 0.; Author ........: seangriffin; Modified.......: ; Remarks .......: The current version of Tesseract doesn't support paths with spaces.; Related .......: ; Link ..........: ; Example .......: No;; ;==========================================================================================func _TesseractTempPathSet($temp_path) $tesseract_temp_path = $temp_path Return 1EndFunc; #FUNCTION# ;===============================================================================;; Name...........: _TesseractScreenCapture(); Description ...: Captures text from the screen.; Syntax.........: _TesseractScreenCapture($get_last_capture = 0, $delimiter = "", $cleanup = 1, $scale = 2, $left_indent = 0, $top_indent = 0, $right_indent = 0, $bottom_indent = 0, $show_capture = 0); Parameters ....: $get_last_capture - Retrieve the text of the last capture, rather than; performing another capture. Useful if the text in; the window or control hasn't changed since the last capture.; 0 = do not retrieve the last capture (default); 1 = retrieve the last capture; $delimiter - Optional: The string that delimits elements in the text.; A string of text will be returned if this isn't provided.; An array of delimited text will be returned if this is provided.; Eg. Use @CRLF to return the items of a listbox as an array.; $cleanup - Optional: Remove invalid text recognised; 0 = do not remove invalid text; 1 = remove invalid text (default); $scale - Optional: The scaling factor of the screenshot prior to text recognition.; Increase this number to improve accuracy.; The default is 2.; $iLeft - x-Left coordinate; $iTop - y-Top coordinate; $iRight - x-Right coordinate; $iBottom - y-Bottom coordinate; $show_capture - Display screenshot and text captures; (for debugging purposes).; 0 = do not display the screenshot taken (default); 1 = display the screenshot taken and exit; Return values .: On Success - Returns an array of text that was captured. ; On Failure - Returns an empty array.; Author ........: seangriffin; Modified.......: ; Remarks .......: Use the default values for first time use. If the text recognition accuracy is low,; I suggest setting $show_capture to 1 and rerunning. If the screenshot of the; window or control includes borders or erroneous pixels that may interfere with; the text recognition process, then use $left_indent, $top_indent, $right_indent and; $bottom_indent to adjust the portion of the screen being captured, to; exclude these non-textural elements.; If text accuracy is still low, increase the $scale parameter. In general, the higher; the scale the clearer the font and the more accurate the text recognition.; Related .......: ; Link ..........: ; Example .......: No;; ;==========================================================================================func _TesseractScreenCapture($get_last_capture = 0, $delimiter = "", $cleanup = 1, $scale = 2, $iLeft = 0, $iTop = 0, $iRight = 1, $iBottom = 1, $show_capture = 0, $BackgroundColor = "", $fontColor = "" ) Local $tInfo dim $aArray, $final_ocr[1], $xyPos_old = -1, $capture_scale = 3 Local $tSCROLLINFO = DllStructCreate($tagSCROLLINFO) DllStructSetData($tSCROLLINFO, "cbSize", DllStructGetSize($tSCROLLINFO)) DllStructSetData($tSCROLLINFO, "fMask", $SIF_ALL) if $last_capture = "" Then $last_capture = ObjCreate("Scripting.Dictionary") EndIf ; if last capture is requested, and one exists. if $get_last_capture = 1 and $last_capture.item(0) <> "" Then return $last_capture.item(0) EndIf $capture_filename = _TempFile($tesseract_temp_path, "~", ".tif") $ocr_filename = StringLeft($capture_filename, StringLen($capture_filename) - 4) $ocr_filename_and_ext = $ocr_filename & ".txt" CaptureToTIFF("", "", "", $capture_filename, $scale, $iLeft , $iTop , $iRight , $iBottom, $BackgroundColor, $fontColor) ShellExecuteWait(@ProgramFilesDir & "\tesseract\tesseract.exe", $capture_filename & " " & $ocr_filename) ; If no delimter specified, then return a string if StringCompare($delimiter, "") = 0 Then $final_ocr = FileRead($ocr_filename_and_ext) Else _FileReadToArray($ocr_filename_and_ext, $aArray) _ArrayDelete($aArray, 0) ; Append the recognised text to a final array _ArrayConcatenate($final_ocr, $aArray) EndIf ; If the captures are to be displayed if $show_capture = 1 Then GUICreate("Tesseract Screen Capture. Note: image displayed is not to scale", 640, 480, 0, 0, $WS_SIZEBOX + $WS_SYSMENU) ; will create a dialog box that when displayed is centered GUISetBkColor(0xE0FFFF) $Obj1 = ObjCreate("Preview.Preview.1") $Obj1_ctrl = GUICtrlCreateObj($Obj1, 0, 0, 640, 480) $Obj1.ShowFile ($capture_filename, 1) GUISetState() if IsArray($final_ocr) Then _ArrayDisplay($aArray, "Tesseract Text Capture") Else MsgBox(0, "Tesseract Text Capture", $final_ocr) EndIf GUIDelete() EndIf FileDelete($ocr_filename & ".*") ; Cleanup if IsArray($final_ocr) And $cleanup = 1 Then ; Cleanup the items for $final_ocr_num = 1 to (UBound($final_ocr)-1) ; Remove erroneous characters $final_ocr[$final_ocr_num] = StringReplace($final_ocr[$final_ocr_num], ".", "") $final_ocr[$final_ocr_num] = StringReplace($final_ocr[$final_ocr_num], "'", "") $final_ocr[$final_ocr_num] = StringReplace($final_ocr[$final_ocr_num], ",", "") $final_ocr[$final_ocr_num] = StringStripWS($final_ocr[$final_ocr_num], 3) Next ; Remove duplicate and blank items for $each in $final_ocr $found_item = _ArrayFindAll($final_ocr, $each) ; Remove blank items if IsArray($found_item) Then if StringCompare($final_ocr[$found_item[0]], "") = 0 Then _ArrayDelete($final_ocr, $found_item[0]) EndIf EndIf ; Remove duplicate items for $found_item_num = 2 to UBound($found_item) _ArrayDelete($final_ocr, $found_item[$found_item_num-1]) Next Next EndIf ; Store a copy of the capture if $last_capture.item(0) = "" Then $last_capture.item(0) = $final_ocr EndIf Return $final_ocrEndFunc; #FUNCTION# ;===============================================================================;; Name...........: CaptureToTIFF(); Description ...: Captures an image of the screen, a window or a control, and saves it to a TIFF file.; Syntax.........: CaptureToTIFF($win_title = "", $win_text = "", $ctrl_id = "", $sOutImage = "", $scale = 1, $left_indent = 0, $top_indent = 0, $right_indent = 0, $bottom_indent = 0); Parameters ....: $win_title - The title of the window to capture an image of.; $win_text - Optional: The text of the window to capture an image of.; $ctrl_id - Optional: The ID of the control to capture an image of.; An image of the window will be returned if one isn't provided.; $sOutImage - The filename to store the image in.; $scale - Optional: The scaling factor of the capture.; $iLeft - x-Left coordinate; $iTop - y-Top coordinate; $iRight - x-Right coordinate; $iBottom - y-Bottom coordinate; $bottom_indent - A number of pixels to indent the screen capture from the; bottom of the window or control.; Return values .: None; Author ........: seangriffin; Modified.......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No;; ;==========================================================================================Func CaptureToTIFF($win_title = "", $win_text = "", $ctrl_id = "", $sOutImage = "", $scale = 1, $iLeft = 0, $iTop = 0, $iRight = 1, $iBottom = 1, $BackgroundColor = "", $fontColor = "" ) Local $hWnd, $hwnd2, $hDC, $hBMP, $hImage1, $hGraphic, $CLSID, $tParams, $pParams, $tData, $i = 0, $hImage2, $pos[4] Local $Ext = StringUpper(StringMid($sOutImage, StringInStr($sOutImage, ".", 0, -1) + 1)) Local $giTIFColorDepth = 24 Local $giTIFCompression = $GDIP_EVTCOMPRESSIONNONE ; If capturing a control if StringCompare($ctrl_id, "") <> 0 Then $hwnd2 = ControlGetHandle($win_title, $win_text, $ctrl_id) $pos[0] = 0 $pos[1] = 0 $pos[2] = $iRight - $iLeft $pos[3] = $iBottom - $iTop Else ; If capturing a window if StringCompare($win_title, "") <> 0 Then $hwnd2 = WinGetHandle($win_title, $win_text) $pos[0] = 0 $pos[1] = 0 $pos[2] = $iRight - $iLeft $pos[3] = $iBottom - $iTop Else ; If capturing the desktop $hwnd2 = "" $pos[0] = 0 $pos[1] = 0 $pos[2] = $iRight - $iLeft $pos[3] = $iBottom - $iTop EndIf EndIf ; Capture an image of the window / control if IsHWnd($hwnd2) Then WinActivate($win_title, $win_text) $hBitmap2 = _ScreenCapture_CaptureWnd("", $hwnd2, $iLeft, $iTop, $iRight, $iBottom, False) Else $hBitmap2 = _ScreenCapture_Capture("", $iLeft, $iTop, $iRight, $iBottom, False) EndIf _GDIPlus_Startup () ; Convert the image to a bitmap $hImage2 = _GDIPlus_BitmapCreateFromHBITMAP ($hBitmap2) if StringCompare($BackgroundColor, "") <> 0 And StringCompare($fontColor, "") <> 0 Then $hImage2 = ChangeColors($hImage2, 0, 0, $iRight - $iLeft, $iBottom - $iTop, $BackgroundColor, $fontColor) EndIf $hWnd = _WinAPI_GetDesktopWindow() $hDC = _WinAPI_GetDC($hWnd) $hBMP = _WinAPI_CreateCompatibleBitmap($hDC, $pos[2] * $scale , $pos[3] * $scale) _WinAPI_ReleaseDC($hWnd, $hDC) $hImage1 = _GDIPlus_BitmapCreateFromHBITMAP ($hBMP) $hGraphic = _GDIPlus_ImageGetGraphicsContext($hImage1) _GDIPLus_GraphicsDrawImageRect($hGraphic, $hImage2, 0 , 0 , $pos[2] * $scale, $pos[3] * $scale) $CLSID = _GDIPlus_EncodersGetCLSID($Ext) ; Set TIFF parameters $tParams = _GDIPlus_ParamInit(2) $tData = DllStructCreate("int ColorDepth;int Compression") DllStructSetData($tData, "ColorDepth", $giTIFColorDepth) DllStructSetData($tData, "Compression", $giTIFCompression) _GDIPlus_ParamAdd($tParams, $GDIP_EPGCOLORDEPTH, 1, $GDIP_EPTLONG, DllStructGetPtr($tData, "ColorDepth")) _GDIPlus_ParamAdd($tParams, $GDIP_EPGCOMPRESSION, 1, $GDIP_EPTLONG, DllStructGetPtr($tData, "Compression")) If IsDllStruct($tParams) Then $pParams = DllStructGetPtr($tParams) ; Save TIFF and cleanup _GDIPlus_ImageSaveToFileEx($hImage1, $sOutImage, $CLSID, $pParams) _GDIPlus_ImageDispose($hImage1) _GDIPlus_ImageDispose($hImage2) _GDIPlus_GraphicsDispose ($hGraphic) _WinAPI_DeleteObject($hBMP) _GDIPlus_Shutdown()EndFunc;--- Change Background ColorFunc ChangeColors($hImage2, $iStartPosX = 0, $iStartPosY = 0, $GuiSizeX = Default, $GuiSizeY = Default, $iColor1 = Default, $iColor2 = Default) Local $hBitmap1, $Reslt, $width, $height, $stride, $format, $Scan0, $v_Buffer, $v_Value, $iIW, $iIH $iIW = _GDIPlus_ImageGetWidth($hImage2) $iIH = _GDIPlus_ImageGetHeight($hImage2) If $GuiSizeX = Default Or $GuiSizeX > $iIW - $iStartPosX Then $GuiSizeX = $iIW - $iStartPosX If $GuiSizeY = Default Or $GuiSizeY > $iIH - $iStartPosY Then $GuiSizeY = $iIH - $iStartPosY $hBitmap1 = _GDIPlus_BitmapCloneArea($hImage2, $iStartPosX, $iStartPosY, $GuiSizeX, $GuiSizeY, $GDIP_PXF32ARGB) ProgressOn("Making a color Transparent", "The image is being processed.", "0 percent", -1, -1, 16) $Reslt = _GDIPlus_BitmapLockBits($hBitmap1, 0, 0, $GuiSizeX, $GuiSizeY, BitOR($GDIP_ILMREAD, $GDIP_ILMWRITE), $GDIP_PXF32ARGB) ;Get the returned values of _GDIPlus_BitmapLockBits () $width = DllStructGetData($Reslt, "width") $height = DllStructGetData($Reslt, "height") $stride = DllStructGetData($Reslt, "stride") $format = DllStructGetData($Reslt, "format") $Scan0 = DllStructGetData($Reslt, "Scan0") For $i = 0 To $GuiSizeX - 1 For $j = 0 To $GuiSizeY - 1 $v_Buffer = DllStructCreate("dword", $Scan0 + ($j * $stride) + ($i * 4)) $v_Value = DllStructGetData($v_Buffer, 1) If (Hex($v_Value, 6) = Hex($iColor2, 6)) Then ; font color Else DllStructSetData($v_Buffer, 1, Hex($iColor1, 6)) ; Sets to $BackgroundColor EndIf Next ProgressSet(Int(100 * $i / ($GuiSizeX)), Int(100 * $i / ($GuiSizeX)) & " percent") Next _GDIPlus_BitmapUnlockBits($hBitmap1, $Reslt) ProgressOff() Return $hBitmap1EndFunc ;==>OtherColorsToWhiteThe Function ChangeColors is my modificated function from the link above (OtherColorsToWhite, it works fine on original script).The only time that the function ChangeColors is used is on the function CaptureToTIFFif StringCompare($BackgroundColor, "") <> 0 And StringCompare($fontColor, "") <> 0 Then $hImage2 = ChangeColors($hImage2, 0, 0, $iRight - $iLeft, $iBottom - $iTop, $BackgroundColor, $fontColor)EndIfMy goal is to change the background color to any color I want with any font color (red/yellow/blue,etc..)like:#include <SimpleTesseract.au3>$test = _TesseractScreenCapture(0,"",1,2,322,593,420,616,1,16751103,13434828);pink background, font is light greenMsgBox(1, "Test:", $test)The first blue picture is before editing with script. Tesseract couldnt scan the numbers very well, so I need to change backgroundSimpleTesseract.au3 Edited May 2, 2009 by hendrikhe Link to comment Share on other sites More sharing options...
hendrikhe Posted May 4, 2009 Author Share Posted May 4, 2009 *bump* since my codebox is bugged SimpleTesseract.au3 is easier to understand Link to comment Share on other sites More sharing options...
Moderators Melba23 Posted May 4, 2009 Moderators Share Posted May 4, 2009 hendrikhe,I have been playing with Malkey's code and have developed a function to change a .bmp into black and white. The function looks at each pixel and then sets it to black or white depending on the luminosity - this is determined by factoring the RGB components: Luminosity = (Red * 0.3) + (Green * 0.59) + (Blue * 0.11) (the constants are industry standard values according to Google!). The default setting is 127, but this will not work if the background is light (as in your blue/white "150"). So you can alter the luminosity value if the default result is not good enough - I found a value of 185 gave pretty good results on your image.Have a look and see what you think:expandcollapse popup#include <GDIPlus.au3> #include <WinAPI.au3> #include <GuiConstantsEx.au3> #include <WindowsConstants.au3> #Include <Color.au3> _GDIPlus_Startup() $hImage = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\150.bmp");<-- Enter Image file here If @error Then MsgBox(0,"","File not loaded") Exit EndIf Global $GuiSizeX = _GDIPlus_ImageGetWidth($hImage) Global $GuiSizeY = _GDIPlus_ImageGetHeight($hImage) $hGui = GUICreate("Change Colours", $GuiSizeX, $GuiSizeY, 100, 100) GUISetState() ; Create Double Buffer, so the doesn't need to be repainted on PAINT-Event $hGraphicGUI = _GDIPlus_GraphicsCreateFromHWND($hGui) $hBMPBuff = _GDIPlus_BitmapCreateFromGraphics($GuiSizeX, $GuiSizeY, $hGraphicGUI) $hGraphic = _GDIPlus_ImageGetGraphicsContext($hBMPBuff) ;End Double Buffer add-in 1 of 3 _GDIPlus_GraphicsDrawImageRect($hGraphic, $hImage, 0, 0, $GuiSizeX, $GuiSizeY) ; Create Double Buffer, so the doesn't need to be repainted on PAINT-Event GUIRegisterMsg(0xF, "MY_PAINT"); Register PAINT-Event 0x000F = $WM_PAINT (WindowsConstants.au3) GUIRegisterMsg(0x85, "MY_PAINT"); $WM_NCPAINT = 0x0085 (WindowsConstants.au3)Restore after Minimize. _GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0) ;End Double Buffer add-in 2 of 3 Local $hBitmap = Image_BandW($hBMPBuff, 0, 0, $GuiSizeX, $GuiSizeY, 185) ; <<<<<<<<<<<<<<<<<<< The luminosity value is set here - default is 127 If _GDIPlus_ImageSaveToFile($hBitmap, @ScriptDir & "\TestWrite1.bmp") = True Then; Transparency file ShellExecute(@ScriptDir & "\TestWrite1.bmp") Else MsgBox(0,"","File not created") EndIf WinActivate($hGui) While 1 $msg = GUIGetMsg() Switch $msg Case $GUI_EVENT_CLOSE close() EndSwitch WEnd ;Func to redraw on PAINT MSG Func MY_PAINT($hWnd, $msg, $wParam, $lParam) ; Check, if the GUI with the Graphic should be repainted ; The sequencial order of these two commands is important. _GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0) _WinAPI_RedrawWindow($hGui, "", "", BitOR($RDW_INVALIDATE, $RDW_UPDATENOW, $RDW_FRAME)); , $RDW_ALLCHILDREN Return $GUI_RUNDEFMSG EndFunc ;==>MY_PAINT Func close() _GDIPlus_GraphicsDispose($hGraphic) _GDIPlus_Shutdown() Exit EndFunc ;==>close Func Image_BandW($hImage2, $iStartPosX = 0, $iStartPosY = 0, $GuiSizeX = Default, $GuiSizeY = Default, $iLumin = 127) Local $hBitmap1, $Reslt, $width, $height, $stride, $format, $Scan0, $v_Buffer, $v_Value, $iIW, $iIH $iIW = _GDIPlus_ImageGetWidth($hImage2) $iIH = _GDIPlus_ImageGetHeight($hImage2) If $GuiSizeX = Default Or $GuiSizeX > $iIW - $iStartPosX Then $GuiSizeX = $iIW - $iStartPosX If $GuiSizeY = Default Or $GuiSizeY > $iIH - $iStartPosY Then $GuiSizeY = $iIH - $iStartPosY $hBitmap1 = _GDIPlus_BitmapCloneArea($hImage2, $iStartPosX, $iStartPosY, $GuiSizeX, $GuiSizeY, $GDIP_PXF32ARGB) ProgressOn("Making a color Transparent", "The image is being processed.", "0 percent", -1, -1, 16) $Reslt = _GDIPlus_BitmapLockBits($hBitmap1, 0, 0, $GuiSizeX, $GuiSizeY, BitOR($GDIP_ILMREAD, $GDIP_ILMWRITE), $GDIP_PXF32ARGB) ;Get the returned values of _GDIPlus_BitmapLockBits () $width = DllStructGetData($Reslt, "width") $height = DllStructGetData($Reslt, "height") $stride = DllStructGetData($Reslt, "stride") $format = DllStructGetData($Reslt, "format") $Scan0 = DllStructGetData($Reslt, "Scan0") For $i = 0 To $GuiSizeX - 1 For $j = 0 To $GuiSizeY - 1 $v_Buffer = DllStructCreate("dword", $Scan0 + ($j * $stride) + ($i * 4)) $v_Value = DllStructGetData($v_Buffer, 1) Local $nLumin = (_ColorGetRed($v_Value) * 0.3) + (_ColorGetGreen($v_Value) * 0.59) + (_ColorGetBlue($v_Value) * 0.11) If $nLumin > $iLumin Then DllStructSetData($v_Buffer, 1, 0xFFFFFFFF); Sets to white Else DllStructSetData($v_Buffer, 1, 0xFF000000); Sets to black EndIf Next ProgressSet(Int(100 * $i / ($GuiSizeX)), Int(100 * $i / ($GuiSizeX)) & " percent") Next _GDIPlus_BitmapUnlockBits($hBitmap1, $Reslt) ProgressOff() Return $hBitmap1 EndFunc ;==>Image_BandWThe file I used (150.bmp) was your uploaded blue/white .jpg changed to a 24-bit .bmp in Paint. M23  Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind Open spoiler to see my UDFs: Spoiler ArrayMultiColSort ---- Sort arrays on multiple columnsChooseFileFolder ---- Single and multiple selections from specified path treeview listingDate_Time_Convert -- Easily convert date/time formats, including the language usedExtMsgBox --------- A highly customisable replacement for MsgBoxGUIExtender -------- Extend and retract multiple sections within a GUIGUIFrame ---------- Subdivide GUIs into many adjustable framesGUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView itemsGUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeViewMarquee ----------- Scrolling tickertape GUIsNoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxesNotify ------------- Small notifications on the edge of the displayScrollbars ----------Automatically sized scrollbars with a single commandStringSize ---------- Automatically size controls to fit textToast -------------- Small GUIs which pop out of the notification area  Link to comment Share on other sites More sharing options...
hendrikhe Posted May 4, 2009 Author Share Posted May 4, 2009 Sounds good, I will test it asap but I need to fix my Vista Problem (http://www.autoitscript.com/forum/index.php?showtopic=92795), since any Tesseract scripts arent working on Vista Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now