Jump to content

Removing background from a picture

Recommended Posts

Hey fellas,

alright, I have to confess, I'm in over my head :).

I'm trying to remove background from a captcha like image to further use for OCR. I tried using ImageMagick (through ShellExecute) but unfortunately that didn't get me the result I need. I did some googling and it seems the best way to compare colors is CIELAB. I was trying to find anything similar done in AutoIt but could not find anything so I'm not even sure it is possible.

I did find this from Mr. @Jchd. But again, not sure how precise this is compared to the CIELAB calculations.

then the "simple" colorimetric distance separing them is:
Local $ColorDist = Sqrt(($r2 - $r1) ^ 2 + ($g2 - $g1) ^ 2 + ($b2 - $b1) ^ 2)

I also found this from Mr. @Melba23 which compares Luminosity only. Apparently the Luminosity is calculated from RGB values.

#include <GDIPlus.au3>
#include <WinAPI.au3>
#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#Include <Color.au3>

$hImage = _GDIPlus_ImageLoadFromFile(@ScriptDir & "\150.bmp");<-- Enter Image file here

If @error Then
    MsgBox(0,"","File not loaded")

Global $GuiSizeX = _GDIPlus_ImageGetWidth($hImage)
Global $GuiSizeY = _GDIPlus_ImageGetHeight($hImage)

$hGui = GUICreate("Change Colours", $GuiSizeX, $GuiSizeY, 100, 100)

; 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")
    MsgBox(0,"","File not created")


While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case $GUI_EVENT_CLOSE

;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)
EndFunc  ;==>MY_PAINT

Func close()
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
                DllStructSetData($v_Buffer, 1, 0xFF000000); Sets to black
        ProgressSet(Int(100 * $i / ($GuiSizeX)), Int(100 * $i / ($GuiSizeX)) & " percent")
    _GDIPlus_BitmapUnlockBits($hBitmap1, $Reslt)
    Return $hBitmap1
EndFunc  ;==>Image_BandW

Now, my question is: what is the best way to compare colors to remove all other colors and for the result image to be usable for OCR? Can Melba's script be updated to what Mr. @jchd posted for it work reliably?

I'm not sure how to go about it so I figured I'd rather ask before I spend any unreasonable time on it without knowing if the outcome would be worth it.

Thanks for any help I can get!


Edited by Seminko
Link to post
Share on other sites
  • Moderators



I'm trying to remove background from a captcha like image to further use for OCR      (my bold)

So how does this not fall foul of the Forum rules?



Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png 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:


ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area


Link to post
Share on other sites
1 minute ago, Melba23 said:


So how does this not fall foul of the Forum rules?



Dang it... I guess I have to read those more often.

To clarify, I'm not doing anything malicious but I understand that the forum needs to cover their behinds.

So yea, sorry about that and the thread can be closed I guess.

Link to post
Share on other sites
This topic is now closed to further replies.
  • Recently Browsing   0 members

    No registered users viewing this page.

  • Create New...