OpenCV meets AutoIt

  • Nimm mal ein anderes Bild, bzw. verkleinere (vergrößere) dein Bild mal auf eine durch 4 teilbare Breite! Teste div. Bit-Formate
    Wenn das nicht funktioniert, erzwinge Padding durch eine durch 3 teilbare Breite.

    Wenn das dann immer noch nicht funktioniert, lese das Bild pixelweise aus (struct? ) und schaue nach, was da "schief" läuft ^^

  • Ich hab nun mal durch 4 geteilt. Bei xxx,25 war es noch in Ordnung, aber immer bei Werten mit ,5 und ,75 war wieder dieses Verhalten.

  • Hi,
    habe mal einen schnellen workaround gebastelt.

    Spoiler anzeigen
    [autoit]

    Func _Resize()
    Local $_iValue = GUICtrlRead($cSlider)
    If $_iValue = 0 Then
    $_iValue = 1
    GUICtrlSetData($cSlider, $_iValue)
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    GUICtrlSetData($cSliderVal, $_iValue & " %")
    $tImage = _OpenCV_LoadImage($testimage)
    Local $_iWidth = DllStructGetData($tImage, "width")
    Local $_iChannels = DllStructGetData($tImage, "nChannels")
    $b=int($_ivalue*$_iWidth/100) ;breite
    $padding=mod($b,4);padding-Pixel zu durch 4 teilbare breite

    [/autoit] [autoit][/autoit] [autoit]

    if $padding=2 or $padding =3 Then
    $_iValue=($b+4-$padding)*100/$_iWidth
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    _OpenCV_Resize($tImage, $_iValue)
    $hBitmap = _CreateBitmapFromIplImage($tImage)
    _WinAPI_DeleteObject(GUICtrlSendMsg($cPic, 0x0172, 0, $hBitmap))
    EndFunc

    [/autoit]


    Du musst beim ersten Laden des Bildes schon auf die Breite achten....
    Kann gut sein, dass diese geschwindigkeitsoptimierte Bibliothek nur Bilder mit einer durch 4 teilbaren Breite verarbeitet, alles andere wäre imho auch Quatsch (man würde wg fehlender SIMD nur auf 25% der möglichen Geschwindigkeit rechnen)

  • Funktioniert perfekt, danke :thumbup:
    Hier nun die finale Resize-Funktion.

    Spoiler anzeigen
    [autoit]

    Func _OpenCV_Resize(ByRef $_tImage, $_iPercent = 50, $_iInterpolation = $CV_INTER_LINEAR)
    Local $_iWidth1 = DllStructGetData($_tImage, "width")
    Local $_iChannels = DllStructGetData($_tImage, "nChannels")
    Local $_iWidth2 = Int(($_iPercent * $_iWidth1) / 100)
    Local $_iPadding = Mod($_iWidth2, 4)
    If $_iPadding = 2 Or $_iPadding = 3 Then $_iPercent = ($_iWidth2 + 4 - $_iPadding) * (100 / $_iWidth1)

    [/autoit] [autoit][/autoit] [autoit]

    Local $_tImageResize = _OpenCV_CreateImage(Int(DllStructGetData($_tImage, "width") / (100 / $_iPercent)), Int(DllStructGetData($_tImage, "height") / (100 / $_iPercent)), DllStructGetData($_tImage, "depth"), DllStructGetData($_tImage, "nChannels"))
    DllCall($__ghOCVDll_3, "none:cdecl", "cvResize", "ptr", DllStructGetPtr($_tImage), "ptr", DllStructGetPtr($_tImageResize), "int", $_iInterpolation)
    If @error Then
    Local $_iError = @error
    _OpenCV_ReleaseImage($_tImageResize)
    Return SetError($_iError, 0, False)
    EndIf
    _OpenCV_ReleaseImage($_tImage)
    $_tImage = _OpenCV_CloneImage($_tImageResize)
    _OpenCV_ReleaseImage($_tImageResize)
    Return True
    EndFunc

    [/autoit]
  • So...da ich nun auch schon die Funktion cvThreshold richtig gewrapped hab, hab ich schonmal nen kleines Mini-Tool damit geschrieben. Einfach um die Funktion ein bisschen auszuprobieren.

    Spoiler anzeigen
    [autoit]

    #include "OpenCV.au3"
    #include <WinAPIEx.au3>
    #include <GUIConstantsEx.au3>
    #include <WindowsConstants.au3>
    #include <ComboConstants.au3>
    #include <EditConstants.au3>
    #include <GuiSlider.au3>

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Opt("GUIOnEventMode", 1)

    [/autoit] [autoit][/autoit] [autoit]

    Global $hGui, $cLoad, $cPic1, $cCombo, $cSlider, $cInput, $cPic2
    Global $tImage1, $tImage2, $hBitmap

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    _OpenCV_Startup()

    [/autoit] [autoit][/autoit] [autoit]

    $hGui = GUICreate("Threshold", 1200, 500, -1, -1, BitOR($WS_MINIMIZEBOX, $WS_CAPTION, $WS_POPUP, $WS_MAXIMIZEBOX))
    $cLoad = GUICtrlCreateButton("Bild laden", 60, 10, 140, 35)
    GUICtrlSetFont(-1, 12, 400)
    $cPic1 = GUICtrlCreatePic("", 20, 60)
    GUICtrlCreateLabel("Thresholdtyp:", 450, 80, 100, 17)
    $cCombo = GUICtrlCreateCombo("", 460, 100, 160, 20, $CBS_DROPDOWNLIST)
    GUICtrlSetData(-1, "CV_THRESH_BINARY|CV_THRESH_BINARY_INV|CV_THRESH_TRUNC|CV_THRESH_TOZERO|CV_THRESH_TOZERO_INV|CV_THRESH_OTSU", "CV_THRESH_BINARY")
    GUICtrlCreateLabel("Schwellwert:", 450, 160, 100, 17)
    $cSlider = GUICtrlCreateSlider(450, 180, 230, 30)
    _GUICtrlSlider_SetTicFreq($cSlider, 10)
    GUICtrlSetLimit(-1, 255, 0)
    GUICtrlSetData(-1, 100)
    $cInput = GUICtrlCreateInput("100", 690, 185, 35, 20, $ES_CENTER + $ES_NUMBER)
    $cPic2 = GUICtrlCreatePic("", 750, 60)
    GUISetState()

    [/autoit] [autoit][/autoit] [autoit]

    GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
    GUICtrlSetOnEvent($cLoad, "_Load")
    GUICtrlSetOnEvent($cCombo, "_Change")
    GUICtrlSetOnEvent($cSlider, "_Change")
    GUICtrlSetOnEvent($cInput, "_Change")

    [/autoit] [autoit][/autoit] [autoit]

    _Load()

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    While 1
    Sleep(10)
    WEnd

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _Exit()
    _OpenCV_ReleaseImage($tImage1)
    _OpenCV_Shutdown()
    _WinAPI_DeleteObject($hBitmap)
    Exit
    EndFunc

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _Load()
    Local $_sFile = FileOpenDialog("Bild laden", @DesktopDir, "Bilder (*.jpg;*.bmp)", 1, "", $hGui)
    If @error Then Return
    _OpenCV_ReleaseImage($tImage1)
    $tImage1 = _OpenCV_LoadImage($_sFile)
    _OpenCV_ResizeToWidth($tImage1, 400)
    $hBitmap = _CreateBitmapFromIplImage($tImage1)
    _WinAPI_DeleteObject(GUICtrlSendMsg($cPic1, 0x0172, 0, $hBitmap))
    $tImage2 = _OpenCV_CloneImage($tImage1)
    _OpenCV_CvtColor1($tImage2, $CV_BGR2GRAY)
    _OpenCV_Threshold($tImage2, GUICtrlRead($cSlider), 255, Eval(GUICtrlRead($cCombo)))
    _OpenCV_CvtColor1($tImage2, $CV_GRAY2RGBA)
    $hBitmap = _CreateBitmapFromIplImage($tImage2)
    _OpenCV_ReleaseImage($tImage2)
    _WinAPI_DeleteObject(GUICtrlSendMsg($cPic2, 0x0172, 0, $hBitmap))
    EndFunc

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _Change()
    Switch @GUI_CtrlId
    Case $cSlider
    GUICtrlSetData($cInput, GUICtrlRead($cSlider))
    Case $cInput
    If Int(GUICtrlRead($cInput)) > 255 Then GUICtrlSetData($cInput, "255")
    GUICtrlSetData($cSlider, GUICtrlRead($cInput))
    EndSwitch
    $tImage2 = _OpenCV_CloneImage($tImage1)
    _OpenCV_CvtColor1($tImage2, $CV_BGR2GRAY)
    _OpenCV_Threshold($tImage2, GUICtrlRead($cSlider), 255, Eval(GUICtrlRead($cCombo)))
    _OpenCV_CvtColor1($tImage2, $CV_GRAY2RGBA)
    $hBitmap = _CreateBitmapFromIplImage($tImage2)
    _OpenCV_ReleaseImage($tImage2)
    _WinAPI_DeleteObject(GUICtrlSendMsg($cPic2, 0x0172, 0, $hBitmap))
    EndFunc

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func _CreateBitmapFromIplImage($_tIplImage)
    Local $_iWidth = DllStructGetData($_tIplImage, "width")
    Local $_iHeight = DllStructGetData($_tIplImage, "height")
    Local $_iDepth = DllStructGetData($_tIplImage, "depth")
    Local $_iChannels = DllStructGetData($_tIplImage, "nChannels")
    Local $_pData = DllStructGetData($_tIplImage, "imageData")

    [/autoit] [autoit][/autoit] [autoit]

    Local $_hBitmap = _WinAPI_CreateDIB($_iWidth, $_iHeight, $_iDepth * $_iChannels)
    _WinAPI_SetBitmapBits($_hBitmap, $_iWidth * $_iHeight * $_iChannels, $_pData)
    Return $_hBitmap
    EndFunc

    [/autoit]
  • Nach und nach wird es was :D
    Hab nun die Funktion cvFindContours umgesetzt. Sie funktioniert auch soweit, nur kann ich nicht die Kontouren auslesen. Evtl. liegt es am Struct was übergeben wird. Es geht um das Struct CvSeq.

    In C++ sieht das Struct so aus:

    Spoiler anzeigen


    Hab es dann so in AutoIt geschrieben:

    Spoiler anzeigen
    [autoit]

    Global Const $tagCvSeq = _
    "int flags;" & _
    "int header_size;" & _
    "ptr h_prev;" & _
    "ptr h_next;" & _
    "ptr v_prev;" & _
    "ptr v_next;" & _
    "int total;" & _
    "int elem_size;" & _
    "ptr block_max;" & _
    "ptr ptr;" & _
    "int delta_elems;" & _
    "ptr storage;" & _
    "ptr free_blocks;" & _
    "ptr first"

    [/autoit]

    Kommt das so hin?