Bildauswertung und Mauszeiger hinbewegen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
MikaH
User
Beiträge: 5
Registriert: Mittwoch 14. Juli 2021, 18:59

Hallo Liebe Leser,
Da ich recht unerfahren in diesem Gebiet von Python bin, habe ich leider keine Ahnung mehr wie es weiter geht. Mein Code macht ein Screenshot von einem Teil des Bildes und legt filtert Helligkeiten heraus. Nun möchte ich, dass sich der Mauszeiger auf (am besten die größte), grüne Fläche bewegt, die auf dem Bild erkennbar ist. Dafür verwende ich die win32api. Vielen Dank im Voraus!

Hier die Problemstelle, bzw zum einbauen:

Code: Alles auswählen

import win32api, win32con
import time
from PIL import Image, ImageGrab
import os
import time
from PIL import ImageOps
from numpy import *


#Gobal Cords
x_pad = 0
y_pad = 0
c_Mitte = 960, 540 

def screenGrab():
    box = ()
    im = ImageGrab.grab()
    return im
def grab():
    box = (0,0,1535,993)
    screenGrab()
    im = ImageOps.colorize(ImageOps.grayscale(ImageGrab.grab(box)), black="black", white="black", mid="green", blackpoint=105, whitepoint=130, midpoint=125)
    im.save("C:/Users/m/BotPython/Bilder" + '\\full_snap__' + str(int(time.time())) + '.png', 'PNG')
Hier mein ganzer Code:

Code: Alles auswählen

import win32api, win32con
import time
from PIL import Image, ImageGrab
import os
import time
from PIL import ImageOps
from numpy import *


#Gobal Cords
x_pad = 0
y_pad = 0
c_Mitte = 960, 540 

def screenGrab():
    box = ()
    im = ImageGrab.grab()
    #im.save("C:/Users/hahnm/BotPython/Bilder" + '\\full_snap__' + str(int(time.time())) + '.png', 'PNG')
    return im
def grab():
    box = (0,0,1535,993)
    screenGrab()
    im = ImageOps.colorize(ImageOps.grayscale(ImageGrab.grab(box)), black="black", white="black", mid="green", blackpoint=105, whitepoint=130, midpoint=125)
    im.save("C:/Users/hahnm/BotPython/Bilder" + '\\full_snap__' + str(int(time.time())) + '.png', 'PNG')
    
    
# ----------------


def leftClick():
    win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN,0,0)
    time.sleep(.1)
    win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP,0,0)
    print("Click.")
def leftDown():
    win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN,0,0)
    time.sleep(.1)
    print("left Down")
         
def leftUp():
    win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP,0,0)
    time.sleep(.1)
    print("left release")
def mousePos(cord):
    win32api.SetCursorPos((x_pad + cord[0], y_pad + cord[1]))
def get_cords():
    x,y = win32api.GetCursorPos()
    x = x - x_pad
    y = y - y_pad
    print(x,y)
def StartGame():
     win32api.SetCursorPos((963, 645))
     leftClick()
     time.sleep(12)
     win32api.SetCursorPos((593, 907))
     leftClick()
     time.sleep(.1)
     win32api.SetCursorPos((965, 907))
     leftClick()
     time.sleep(.1)
     win32api.SetCursorPos((1359, 907))
     leftClick()
     time.sleep(.1)
#def StartOver():

#time.sleep(5)
#StartOver()
#for i in range(6):
#    print(get_cords())
#    time.sleep(5)
#grab()

StartGame()

def main():
       pass

if __name__ == '__main__':
    main()
MikaH
User
Beiträge: 5
Registriert: Mittwoch 14. Juli 2021, 18:59

Sorry für die ppar Rechtschreibfehler. Es geht prinzipiell darum, dass praktisch eine gewisse Helligkeit als Maske heraus geht, welche grün angezeigt wird. Sieht ungefähr so aus: https://pythonprogramming.net/static/im ... xample.png
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Sowas macht man mit der OpenCV. Und mehr kann man ohne das Bild zu sehen auch nicht sagen. Bei Computer Vision Themen helfen vage Beschreibungen oder andere Bilder nicht.
MikaH
User
Beiträge: 5
Registriert: Mittwoch 14. Juli 2021, 18:59

__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Und was soll da jetzt genau passieren? Wo soll da was angeklickt werden? Da sind ja ganz viele grüne Zonen.
MikaH
User
Beiträge: 5
Registriert: Mittwoch 14. Juli 2021, 18:59

am besten die größte.. dort dann den durschnitt der Koordinaten ermitteln und dort die Maus positionieren.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Alles deutlich zu spaerlich, nicht vom Ausgangsproblem her gedacht, sondern schon halb geglaubt eine Loesung zu haben. Ich denke nicht, dass es so was wird.

Aber fuer die gegebene Situation: benutz morphologische Operationen, um den ganzen "Dreck" weg zu nehmen, und dann das contour-finding mit dem du die Zonen erkennst. Die groesste kannst du mit contourArea ermitteln, und mit den image moments kann man den "centroid" ermitteln, und da eben hinklicken. Siehe https://docs.opencv.org/3.4/dd/d49/tuto ... tures.html
MikaH
User
Beiträge: 5
Registriert: Mittwoch 14. Juli 2021, 18:59

Ich werde mir das Projekt nochmal vornehmen. Danke für die Hilfe
Benutzeravatar
__blackjack__
User
Beiträge: 14056
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@MikaH: Anmerkungen zum Quelltext:

Eingerückt wird per Konvention vier Leerzeichen pro Ebene.

`time` wird unnötigerweise zweimal importiert. Die Importe aus `PIL` sind auf zwei Anweisungen verteilt, wobei `Image` nirgends verwendet wird. `os` und *alles* aus `numpy` wird importiert und auch nicht verwendet.

Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (PascalCase).

`StartGame()` sollte nicht auf Modulebene aufgerufen werden, sondern in der `main()`-Funktion die momentan nichts macht.

Die `screenGrab()`-Funktion macht so keinen Sinn. Die wird zwar in `grab()` aufgerufen, der Rückgabewert wird aber einfach verworfen und die `grab()`-Funktion enthält dann selbst noch mal Code der das gleiche wie der Code in der `screenGrab()`-Funktion macht.

Namen sollten nicht kryptisch abgekürzt werden. Nicht `im` wenn man `image` meint. Wobei in dem speziellen Fall auch gar kein Name nötig ist wenn man das Zwischenergebnis nicht an einen Namen binden möchte.

Das zusammenstückeln von Zeichenketten und Werten mittels ``+`` und `str()` ist eher BASIC als Python. Dafür gibt es die `format()`-Methode auf Zeichenketten und f-Zeichenkettenliterale.

Pfade/Pfadteile setzt man auch nicht mit Zeichenkettenoperationen zusammen. Dafür gibt es das `pathlib`-Modul.

In `StartGame()` wiederholen sie die gleichen drei Codezeilen vier mal, nur mit anderen Werten. Da kann man die Werte herausziehen und eine ``for``-Schleife schreiben.

Code: Alles auswählen

#!/usr/bin/env python3
import time
from pathlib import Path

import win32api
import win32con
from PIL import ImageGrab, ImageOps


def save_screenshot():
    ImageOps.colorize(
        ImageOps.grayscale(ImageGrab.grab((0, 0, 1535, 993))),
        black="black",
        white="black",
        mid="green",
        blackpoint=105,
        whitepoint=130,
        midpoint=125,
    ).save(
        Path("C:/Users/hahnm/BotPython/Bilder")
        / f"full_snap__{int(time.time())}.png",
        "PNG",
    )


def left_click():
    win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0, 0)
    time.sleep(0.1)
    win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0)
    print("Click.")


def start_game():
    for position, delay in [
        ((963, 645), 12),
        ((593, 907), 0.1),
        ((965, 907), 0.1),
        ((1359, 907), 0.1),
    ]:
        win32api.SetCursorPos(position)
        left_click()
        time.sleep(delay)


def main():
    start_game()


if __name__ == "__main__":
    main()
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Antworten