Hallo, ich versuche bei dem angefügten Bild, das Bild nach den Sitzplätzen zu filtern und immer eine MsgBox zu öffnen, wenn 2 Plätze nebeneinander weiß sind. Mit diesem Bild müsste also einfach nur angezeigt werden, dass keine Plätze gefunden wurden. Habe überlegt, das Bild in diesen Hexcode umzuwandeln und dann immer Pixelreihe für Pixelreihe zu überprüfen, ob eine gewisse Spanne weißer Pixel vorhanden ist (2 freie Plätze nebeneinander), aber dann müsste man die Bilder vorher beschneiden?! Ich hoffe jmd hat eine Idee für mich, LG Kai
Bild filtern/ strukturiert absuchen
-
DDiSoEsT -
29. März 2019 um 16:16 -
Erledigt
-
-
Es lohnt sich nicht das Bild in einen Hex-Code umzuwandeln und dann daraus zu versuchen Informationen zu beziehen.
AutoIt3 kommt mit einer GDI+ UDF daher mit der du sehr einfach das ganze prüfen könntest.
_GDIPlus_BitmapGetPixel gibt dir den Farbwert eines Pixels innerhalb einer Bitmap wieder, also musst du nur einfach Zeile für Zeile dein Bild durchgehen und schauen ob du irgendwo einen weißen Pixel findest.
Da alle Plätze geordnet und mit dem selben Abstand zueinander aufgebaut sind nimmst du die obere linke Kante eines Sitzplatzvierecks und addierst dann X Pixel drauf um zum nächsten zu kommen.
Findest du einen weißen Sitzplatz musst du nur noch die umliegenden prüfen (links, oben, rechts, unten, und nicht vergessen: prüfst du einen Sitzplatz am Rand?) und fertig.
-
Danke super Idee schonmal! Ich überprüfe so etwa 127 Bilder, in dessen die Sitzplätze immer verschoben angeordnet sind.. Es wäre also etwas umständlich für jedes Bild die Koordinaten anzuordnen. Ich habe herausgefunden, dass freie Sitzplätze blau umrandet sind. Ich kenne mich leider mit GUI und co. noch sehr wenig aus, gobt es eine Möglichkeit, alle Bilder nach blauen Pixeln zu durchsuchen ohne diese zu öffnen? Wenn ja, müsste man ja nur noch eine Bedingung schreiben, die guckt ob die x-Koordinaten maximal zB 20 Pixel auseinander sind, um 2 Plätze nebeneinander zu haben.
-
gobt es eine Möglichkeit, alle Bilder nach blauen Pixeln zu durchsuchen ohne diese zu öffnen?
Dir habe ich dir gerade genannt, GDI+.
-
Habe gerade mal eifirg danach gegooglet und muss sagen, dass ist etwas neuland für mich.. Gibt es da einen einfachen Befehl, der alle Pixel nach blauen Pixeln überprüft und die Koordinaten ausgibt? LG
-
Hier mal ein kleines Beispiel welches blaue Punkte auf einem Bild ausliest.
-
Hi,
ich würde, um das Problem schnell zu lösen, zunächst die Breite und Höhe in Pixeln eines (des oberen linken) "Sitzplatzes" bestimmen. Es wird im Bild ein Rechteck gesucht. Dieses ist dadurch bestimmt, dass die obere linke "Ecke" schwarz (oder wenn besetzt blau), und deren beiden Nachbarpixel unten und rechts auch schwarz ist. Das Pixel links und oben ist nicht schwarz.
Jetzt hangelt man sich Pixel für Pixel nach rechts und unten, bis die rechte untere "Ecke" gefunden wurde.
Somit ist das oberste linke Rechteck gefunden, incl. Koordinaten seiner 4 "Ecken".
Von der Ecke unten rechts läuft man nun nach unten und nach rechts, so erhält man den Abstand zum nächsten Rechteck in der Reihe und Spalte.
Und somit den Abstand zum nächsten Sitzplatz waagrecht und senkrecht. Die Sitzplatznummer erhält man "nebenbei" auch noch...
Jetzt sind die Koordinaten des ersten Sitzplatzes und der Abstand zum nächsten Platz rechts und unten bekannt.
Somit reduziert sich die weitere "Suche" auf Ablaufen von einer Handvoll Koordinaten.
Wenn alle Bilder "gleiche" Auflösung bzw. gleichen Reihen- und Spaltenabstand haben, reicht es, die "Suche" genau ein mal durchzuführen und die Koordinaten/Abstände des ersten Sitzplatzes je Bild abzuspeichern.
Dann reduziert sich die Frage nach benachbarten Sitzplätzen auf eine Abfrage von (im Beispielbild) ca. 30x15, also 450 Pixeln.
Das schafft selbst AutoIt per GDI in einigen Millisekunden, bei 127 Bildern also in etwa 2-3 Sekunden.
Ich frage mich nur gerade, wozu man ein Script schreiben will, um in 127 Kinos/Theatern nebeneinander liegende Sitzplätze herauszufinden...
-
xD Die Vermutung ist lustig, geht aber um ein Stadion..:D Also Danke schonmal für eure Ideen, zu Alpines testdatei: Ich habs versucht in meinen Code zu implementieren, jedoch ergibt das Array jedes mal nichts.. Hab das Gefühl ich hab die Farbe falsch angegeben, mit der 0 und dem FF. Meine rgb werte sind der Reihe nach 4, 206, 252. Magste mir da vielleicht nochmal helfen?
Andys Idee ist auch Klasse, meine dass wir das früher im Informatikunterricht am Gym mal hatten mit Robotern und Feldern, wo dann die nächsten Felder abgefragt werden.. Ich denke mal das wichtigste was ich benötige ist eine Pixelabfrage, die keine Fenster öffnet, also im hintergrund arbeitet, bin also erstmal auf alpines Hilfe angewiesen, denke ich mal, werd derweil auch mal fleißig weiterrecherchieren, vielen Dank euch beiden nochmal!
-
Hinzu kommt, dass einige 'Blöcke' leider nicht ganz symmetrisch sind..
-
C
Alles anzeigen#include <GDIPlus.au3> #include <Array.au3> Global $aPos[0][2] Global Const $I_COLOR = 0x0FF000066 ;0 (vor dem FF) wird benötigt, da die Zahl sonst negativ ist) _GDIPlus_Startup() $hBitmap = _GDIPlus_BitmapCreateFromFile("Bilder\Block6.png") For $y = 0 To _GDIPlus_ImageGetHeight($hBitmap) - 1 For $x = 0 To _GDIPlus_ImageGetWidth($hBitmap) - 1 If _GDIPlus_BitmapGetPixel($hBitmap, $x, $y) = $I_COLOR Then ReDim $aPos[UBound($aPos) + 1][2] $aPos[UBound($aPos) - 1][0] = $x $aPos[UBound($aPos) - 1][1] = $y EndIf Next Next _GDIPlus_BitmapDispose($hBitmap) _GDIPlus_Shutdown() _ArrayDisplay($aPos)
egal welche farbe ich eintrage, es lädt jedes mal kurz und die infobox wird dann leer angezeigt. Dabei wird angefügtes Bild verwendet.
-
Die Farben werden je nach Anwendung komischerweise anders dargestellt. AutoItWinInfo liefert bei dem Fotoviewer von Windows ganz andere Werte als Paint.
Mit 0x0FF04CEFC als Farbcode (2, 206, 252 wie du es angegeben hast) klappt es.
-
Oke, ja stimmt, das funktionier, hatte nur einen Tippfehler in der Pfadangabe..
Nun bekomme ich ja nach und nach die Koordinaten ausgespuckt. Wäre es möglich, aus diesen Koordinaten eine Gruppe zu machen?
Muss irgendwie aus diesen Daten, die ich ausgespuckt bekomme erschließen können ob diese gefundenen Pixel zwei Sitzplätze nebeneinander darstellen.. LG
-
Du kannst dir doch einen Algorithmus überlegen wie du eine Gruppe von blauen Punkten erkennen kannst.
Ich kann dir nicht alles vormachen, sonst lernst du ja nichts draus.
-
ja, das stimmt natürlich, glaube nur mir fehlt da der ansatz, bin etwas eingerostet mit meinen Programmierkenntnissen.. hab mch heute ziemlich schwergetan, sitz seit 9Uhr dran gngn
-
könntest du mir sonst dabei helfen, wie ich diese pixelsuppe extrahiere? hatte an xml gedacht..
-
Was hat denn XML damit zu tun? Schau dir doch mal an wie die Form aussieht die du finden möchtest.
Wenn du nun von oben links nach rechts Zeile für Zeile durchscannst und auf einen blauen Pixel triffst hast du immer den oberen linken Pixel von einem Rechteck.
Jetzt musst du nur noch die Form ausfindig machen, wenn du verschiedene Formen hast (Rechtecke, Quadrate) kannst du keine fixen Werte nehmen.
Taste dich von dem 1. Punkt durch das Rechteck und schon hast du alle Punkte für das Quadrat, danach machst du mit dem nächsten Fund weiter.
-
ok, die lösung wirkt so simpel, dennoch bin ich nicht darauf gekommen, danke erstmal, ich werds versuchen!
-
C
Alles anzeigen#include <GDIPlus.au3> #include <Array.au3> #include <File.au3> Local $Array = 'C:\Users\Kai\Dektop\Werder Tickets\123.txt' Global $aPos[0][2] Global $arr[0][2] Global Const $I_COLORa = 0x0FF04CEFC ;0 (vor dem FF) wird benötigt, da die Zahl sonst negativ ist) Global Const $I_COLORb = 0x0FF046AFC Global Const $I_COLORc = 0x0FF04AAFC Global Const $I_COLORd = 0x0FF0CFE04 _GDIPlus_Startup() $hBitmap = _GDIPlus_BitmapCreateFromFile("C:\Users\Kai\Desktop\Werder Tickets\Bilder\Block6.png") For $y = 0 To _GDIPlus_ImageGetHeight($hBitmap) - 1 For $x = 0 To _GDIPlus_ImageGetWidth($hBitmap) - 1 If _GDIPlus_BitmapGetPixel($hBitmap, $x, $y) = $I_COLORa Then ReDim $aPos[UBound($aPos) + 1][2] $aPos[UBound($aPos) - 1][0] = $x $aPos[UBound($aPos) - 1][1] = $y EndIf Next Next _GDIPlus_BitmapDispose($hBitmap) _GDIPlus_Shutdown() _ArrayDisplay($aPos) $si = $aPos[0][0] MsgBox(1, 'hi', $si) Local $a=0 Local $b=0 Local $c=0 Local $d=0 While true If $aPos[$a][$b] = $aPos[$a+1][$b] Then $a = $a+1 $b = $b+1 Else ReDim $arr[UBound($arr) + 1][2] $arr[UBound($arr) - 1][0] = $aPos[$a][$b] $arr[UBound($arr) - 1][1] = $aPos[$c][$d] MsgBox(1, 'hi', $a) $a = $a+1 $b = $b+1 EndIf WEnd
okey, das ist mein aktueller stand, jetzt geht er unten in den 2. Durchlauf der Schleife und gibt dann einen Fehler, out of dimension oder soetwas. Finde meinen Fehler nicht, könntest du mir helfen?
-
Mit 0x0FF04CEFC als Farbcode (2, 206, 252 wie du es angegeben hast) klappt es.
0x0FF04CEFC ?
Hier mal eine kleine Starthilfe... damit bekommst du allerdings nur die Koordinaten angezeigt, an denen sich zwei freie Plätze nebeneinander befinden, nicht aber die Reihen und Spalten. Das musst du selbst erledigen... die Vorgehensweise ist ähnlich wie beim Auffinden der freien Plätze.
C
Alles anzeigenOpt('MustDeclareVars', 1) #include <MsgBoxConstants.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <Array.au3> #include <GDIPlus.au3> Example1() ; mit Schnickschnack Example2() ; ohne Schnickschnack Func Example1() ConsoleWrite(@CRLF & '> ------------------------------------------------------------------------------' & @CRLF) ConsoleWrite('> Example1()' & @CRLF) ConsoleWrite('> ------------------------------------------------------------------------------' & @CRLF & @CRLF) Local $aCoords[0][2], $aDim, $hBitmap, $aColor[3], $sFile = @ScriptDir & "\Block7.png" _GDIPlus_Startup() $hBitmap = _GDIPlus_BitmapCreateFromFile($sFile) If @error Or Not $hBitmap Then MsgBox(BitOR($MB_TOPMOST, $MB_ICONERROR), "Error", "This file isn't supported by GDIPlus!") Exit Else $aDim = _GDIPlus_ImageGetDimension($hBitmap) ConsoleWrite("- Image dimension of " & $sFile & ": Width = " & $aDim[0] & " pixel " & " Height = " & $aDim[1] & " pixel" & @CRLF & @CRLF) EndIf Local $hGUI = GUICreate("GDI+ Example (" & @ScriptName & ")", $aDim[0], $aDim[1]) ;create a test GUI GUISetState(@SW_SHOW) Local $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI) ;create a graphics object from a window handle _GDIPlus_GraphicsDrawImage($hGraphics, $hBitmap, 0, 0) ;copy bitmap to graphics object (GUI) _GDIPlus_GraphicsDispose($hGraphics) ; Block7.png ; 9/13 = 0xFF04CEFC (blau) ; 9/12 = 0xFF04CEFC (blau) ; 28/1 = 0xFF046AFC (blau) - auch blau, aber nicht derselbe Farbwert wie bei 13/12!!! ; Linke obere Ecken der freien Plätze ermitteln For $iY = 0 To $aDim[1] - 2 For $iX = 0 To $aDim[0] - 2 $aColor[0] = '0x' & Hex(_GDIPlus_BitmapGetPixel($hBitmap, $iX, $iY), 8) If $aColor[0] = '0xFF04CEFC' Or $aColor[0] = '0xFF046AFC' Then $aColor[1] = '0x' & Hex(_GDIPlus_BitmapGetPixel($hBitmap, $iX + 1, $iY), 8) $aColor[2] = '0x' & Hex(_GDIPlus_BitmapGetPixel($hBitmap, $iX, $iY +1), 8) If ($aColor[1] = '0xFF04CEFC' And $aColor[2] = '0xFF04CEFC') Or ($aColor[1] = '0xFF046AFC' And $aColor[2] = '0xFF046AFC') Then ConsoleWrite(StringFormat('> Match: $aColor[0] = %s $aColor[1] = %s $aColor[2] = %s\n', $aColor[0], $aColor[1], $aColor[2])) _GDIPlus_BitmapSetPixel($hBitmap, $iX, $iY, BitXOR(0x00FFFFFF, $aColor[0])) ;invert RGB pixel color only _ArrayAdd($aCoords, $iX & '|' & $iY) EndIf EndIf Next Next ConsoleWrite(@CRLF & '> $aCoords: ' & _ArrayToString($aCoords, ', ', -1, -1, '|') & @CRLF) Local $iColor, $iSpace, $iBkColor = '0xFFFCFEFC' For $iX = $aCoords[0][0] To $aDim[0] -1 $iColor = '0x' & Hex(_GDIPlus_BitmapGetPixel($hBitmap, $iX, $aCoords[0][1]), 8) If $iColor <> $iBkColor Then ContinueLoop For $iX = $iX To $aDim[0] -1 $iColor = '0x' & Hex(_GDIPlus_BitmapGetPixel($hBitmap, $iX, $aCoords[0][1]), 8) If $iColor = $iBkColor Then $iSpace += 1 Else ExitLoop 2 EndIf Next Next ConsoleWrite('! $iSpace = ' & $iSpace & @CRLF) ;~ _ArrayDisplay($aCoords, '$aCoords') Local $iBlockSize = 11, $aAll = _ArrayFindAll($aCoords, $aCoords[0][1], 0, 0, 0, 0, 1) ;~ _ArrayDisplay($aAll, '$aAll') While UBound($aAll) > 1 For $i = 0 To UBound($aAll) -2 Step 1 If $aCoords[$aAll[$i]][0] + $iBlockSize + $iSpace = $aCoords[$aAll[$i +1]][0] Then ConsoleWrite('+ Zwei Plätze nebeneinander sind frei!' & @CRLF & _ '--> $aCoords Platz 1: ' & $aCoords[$aAll[$i]][0] & ', ' & $aCoords[$aAll[$i]][1] & ' $aCoords Platz 2: ' & $aCoords[$aAll[$i +1]][0] & ', ' & $aCoords[$aAll[$i +1]][1] & @CRLF) Local $iMouseCoordMode = Opt('MouseCoordMode', 2) MouseMove($aCoords[$aAll[$i]][0], $aCoords[$aAll[$i]][1], 30) ToolTip('1. freier Platz') Sleep(1000) MouseMove($aCoords[$aAll[$i +1]][0], $aCoords[$aAll[$i +1]][1], 30) ToolTip('2. freier Platz') Sleep(1000) ToolTip('') Opt('MouseCoordMode', $iMouseCoordMode) EndIf Next $aAll = _ArrayFindAll($aCoords, $aCoords[$aAll[UBound($aAll) -1] + 1][1], $aAll[UBound($aAll) -1] + 1, 0, 0, 0, 1) WEnd ConsoleWrite('! Done!' & @CRLF) $hGraphics = _GDIPlus_GraphicsCreateFromHWND($hGUI) ;create a graphics object from a window handle _GDIPlus_GraphicsDrawImage($hGraphics, $hBitmap, 0, 0) ;copy negative bitmap to graphics object (GUI) ;~ Do ;~ Until GUIGetMsg() = $GUI_EVENT_CLOSE Sleep(1000) ; cleanup GDI+ resources _GDIPlus_BitmapDispose($hBitmap) _GDIPlus_GraphicsDispose($hGraphics) _GDIPlus_Shutdown() GUIDelete($hGUI) EndFunc ;==>Example1 Func Example2() ConsoleWrite(@CRLF & '> ------------------------------------------------------------------------------' & @CRLF) ConsoleWrite('> Example2()' & @CRLF) ConsoleWrite('> ------------------------------------------------------------------------------' & @CRLF & @CRLF) Local $aCoords[0][2], $aDim, $hBitmap, $aColor[3], $sFile = @ScriptDir & "\Block7.png" _GDIPlus_Startup() $hBitmap = _GDIPlus_BitmapCreateFromFile($sFile) If @error Or Not $hBitmap Then MsgBox(BitOR($MB_TOPMOST, $MB_ICONERROR), "Error", "This file isn't supported by GDIPlus!") Exit Else $aDim = _GDIPlus_ImageGetDimension($hBitmap) ConsoleWrite("- Image dimension of " & $sFile & ": Width = " & $aDim[0] & " pixel " & " Height = " & $aDim[1] & " pixel" & @CRLF & @CRLF) EndIf ; Block7.png ; 9/13 = 0xFF04CEFC (blau) ; 9/12 = 0xFF04CEFC (blau) ; 28/1 = 0xFF046AFC (blau) - auch blau, aber nicht derselbe Farbwert wie bei 13/12!!! ; Linke obere Ecken der freien Plätze ermitteln For $iY = 0 To $aDim[1] - 2 For $iX = 0 To $aDim[0] - 2 $aColor[0] = '0x' & Hex(_GDIPlus_BitmapGetPixel($hBitmap, $iX, $iY), 8) If $aColor[0] = '0xFF04CEFC' Or $aColor[0] = '0xFF046AFC' Then $aColor[1] = '0x' & Hex(_GDIPlus_BitmapGetPixel($hBitmap, $iX + 1, $iY), 8) $aColor[2] = '0x' & Hex(_GDIPlus_BitmapGetPixel($hBitmap, $iX, $iY +1), 8) If ($aColor[1] = '0xFF04CEFC' And $aColor[2] = '0xFF04CEFC') Or ($aColor[1] = '0xFF046AFC' And $aColor[2] = '0xFF046AFC') Then ConsoleWrite(StringFormat('> Match: $aColor[0] = %s $aColor[1] = %s $aColor[2] = %s\n', $aColor[0], $aColor[1], $aColor[2])) _ArrayAdd($aCoords, $iX & '|' & $iY) EndIf EndIf Next Next ConsoleWrite(@CRLF & '> $aCoords: ' & _ArrayToString($aCoords, ', ', -1, -1, '|') & @CRLF) Local $iColor, $iSpace, $iBkColor = '0xFFFCFEFC' For $iX = $aCoords[0][0] To $aDim[0] -1 $iColor = '0x' & Hex(_GDIPlus_BitmapGetPixel($hBitmap, $iX, $aCoords[0][1]), 8) If $iColor <> $iBkColor Then ContinueLoop For $iX = $iX To $aDim[0] -1 $iColor = '0x' & Hex(_GDIPlus_BitmapGetPixel($hBitmap, $iX, $aCoords[0][1]), 8) If $iColor = $iBkColor Then $iSpace += 1 Else ExitLoop 2 EndIf Next Next ConsoleWrite('! $iSpace = ' & $iSpace & @CRLF) ;~ _ArrayDisplay($aCoords, '$aCoords') Local $iBlockSize = 11, $aAll = _ArrayFindAll($aCoords, $aCoords[0][1], 0, 0, 0, 0, 1) ;~ _ArrayDisplay($aAll, '$aAll') While UBound($aAll) > 1 For $i = 0 To UBound($aAll) -2 Step 1 If $aCoords[$aAll[$i]][0] + $iBlockSize + $iSpace = $aCoords[$aAll[$i +1]][0] Then ConsoleWrite('+ Zwei Plätze nebeneinander sind frei!' & @CRLF & _ '--> $aCoords Platz 1: ' & $aCoords[$aAll[$i]][0] & ', ' & $aCoords[$aAll[$i]][1] & ' $aCoords Platz 2: ' & $aCoords[$aAll[$i +1]][0] & ', ' & $aCoords[$aAll[$i +1]][1] & @CRLF) EndIf Next $aAll = _ArrayFindAll($aCoords, $aCoords[$aAll[UBound($aAll) -1] + 1][1], $aAll[UBound($aAll) -1] + 1, 0, 0, 0, 1) WEnd ConsoleWrite('! Done!' & @CRLF) ; cleanup GDI+ resources _GDIPlus_BitmapDispose($hBitmap) _GDIPlus_Shutdown() EndFunc ;==>Example2
-
Bildanalyse mag ja vielleicht eine Möglichkeit sein um das Problem zu lösen, aber ist das wirklich die beste und einzigste Möglichkeit? Woher stammen die Bilder? Vermutlich von einer Webseite. Es sollte also grundsätzlich die Möglichkeit geben den Sitzplatzstatus direkt live abzufragen. Jenachdem ob du dort beschäftigt bist oder quasi extern auf die Daten zugreifst hast du vielleicht sogar die Möglichkeit direkt oder indirekt via API auf die zugrundeliegende DB zuzugreifen.
-