OpenCV ile nesne algılama hakkında

Merhaba Arkadaşlar. Benim sorum şu:
Çalışan kodlarım var. Benim eklemek istediğim şey ekrana bir resim çıkınca benim kod çalışmayı durduracak bu resim içinde 6 adet daha resim var. Benim tanıttığım resime tıklayacak eğer yanlış resime tıklarsa tekrar aynı işlemi yapacak doğru resime tıklayana kadar. Doğru resime tıklayınca o büyük resim ekrandan kayboluyor zaten. Onu göremeyince de tekrar benim ilk kodlarımı çalıştıracak.

Daha türkçe haliyle anlatabilirsem:
Eğer ekrana resim çıkarsa kod dur tanıttığım resime tıkla(eğer yanlış resim ise tekrar et) ilk kodları başlat.

Umarım anlatabilmişimdir. Şimdiden teşekkürler.

Atar mısın? Baştan yazmak zor olacak bizim için.

1 Beğeni

Tabiki hocam.

from tkinter import * 
from tkinter import ttk, messagebox
from tkinter import font
import pydirectinput , pyautogui
import keyboard, threading, os, webbrowser, ctypes
import win32gui
from cv2 import cv2
from pynput import keyboard
from vision import Vision
from ekranyakala import ekranYakala
from time import time, sleep


class Window(Frame):
    def __init__(self, master=None, saniye=0):
        Frame.__init__(self, master)
        self.master = master
        self.saniye = saniye

        F1 = Frame(self.master)
        F1.place(x=235,y=110)

        self.start = Button(F1,text="Başla",command=self.thread, font="bold", cursor="hand2", fg="red", width = 10, height=1)
        self.start.grid(row=0, pady=5)
        self.start.config(state=NORMAL,cursor="hand2", bg="red", fg="white")
        self.stop = Button(F1,text="Durdur | F3", command=self.durdur, font="bold", cursor="hand2", fg="green", width = 10, height=1)
        self.stop.grid(row=1)
        self.stop.config(state=DISABLED,cursor="arrow",bg="white", disabledforeground="red")

        F2 = LabelFrame(self.master,
                            text="Durum",
                            font="bold",
                            fg="red")
        F2.place(x=225, y=25)
        F3 = LabelFrame(self.master,
                            text="Ayarlar",
                            font="bold",
                            fg="red")
        F3.place(x=20, y=25)

        # Durum
        self.metinSayisi = 0
        self.durum = Label(F2, text="Pasif", font="bold", fg="red")
        self.durum.grid()
        self.bulunanMetin = Label(F2, text="Bulunan Metin: 0", fg="blue")
        self.bulunanMetin.grid(row=1, sticky=W)
        self.zaman = Label(F2, text="Geçen Zaman: 00:00:00", fg="green")
        self.zaman.grid(row=2,sticky=W)

        # Ayarlar
        self.ara = Button(F3, text="Ara", width=5, cursor="hand2", command=self.ara)
        self.ara.grid(row=0, column=1, sticky=W, pady=10)
        v1 = StringVar()
        self.windowName = ttk.Combobox(F3, width=17,textvariable=v1, state="readonly")
        self.windowName.grid(row=0, sticky=W, padx=2)
        Label(F3,text="Metin Taşı Kesme Süresi").grid(row=2, sticky=W)
        self.kesimsuresi = Spinbox(F3, from_=3, to = 999, width=5)
        self.kesimsuresi.grid(row=2, sticky=W, column=1)

        self.var1 = IntVar(value=0)
        self.var2 = IntVar(value=0)
        self.kilitle = Checkbutton(F3, text="Kilitle",command=self.userKilit, variable=self.var1, onvalue = 1, offvalue = 0)
        self.kilitle.grid(row=3, column=1,pady=5, sticky=W)

    def ara(self):
        liste = []
        def winEnumHandler(hwnd, ctx):  #açık pencere isimlerini listeler
            if win32gui.IsWindowVisible(hwnd):
                if win32gui.GetWindowText(hwnd) == "":
                    return
                liste.append(win32gui.GetWindowText(hwnd))
                self.windowName.config(values=(liste))
        win32gui.EnumWindows(winEnumHandler, None)

    def userKilit(self):
        if self.var1.get() == 1:
            self.kesimsuresi.config(state="disabled")
            self.windowName.config(state="disabled")
            self.ara.config(state="disabled")
        else:
            self.kesimsuresi.config(state="normal")
            self.windowName.config(state="normal")
            self.windowName.config(state="readonly")
            self.ara.config(state="normal")

    def zamanlayici(self):
        if self.sureBaslat == True:
            self.saniye += 1
            seconds = self.saniye % (24 * 3600)
            hour = seconds // 3600
            seconds %= 3600
            minutes = seconds // 60
            seconds %= 60
            self.master.after(1000, self.zamanlayici)
            return self.zaman.configure(text="Geçen Zaman: %02d:%02d:%02d" % (hour, minutes, seconds))

    def thread(self):
        threading.Thread(target=self.basla).start()

    def basla(self):
        try:
            if self.windowName.get() == "":
                messagebox.showwarning("Hata","Başlamadan Önce Oyun Ekranını Seç")
                return

            wincap = ekranYakala(self.windowName.get())
            # Model dosya yolu
            self.cascade = cv2.CascadeClassifier(r"C:/Users/Halil/Downloads/metin2bot/cascade/cascade.xml")

            self.vision = Vision(None)
            self.loop_time = time()

            self.metine_vur = False
            self.s = 1
            self.s1 = 0
            self.kontrol = 0
            self.saniye = 0
            
            self.start.config(state=DISABLED, cursor="arrow", bg="white", disabledforeground="red")
            self.kesimsuresi.config(state="disabled")
            self.windowName.config(state="disabled")
            self.ara.config(state="disabled", cursor="arrow")
            self.kilitle.config(state="disabled")

            anons = Label(self.master, fg="red", font=("Comic Sans MS", 13, "bold"))
            anons.place(x=75, y=150)
            don = 4
            for _ in range(1,4):
                don -= 1
                sleep(1)
                print("Başlıyor:", don)
                anons["text"] = ("Başlıyor",don)
            anons.after(1000, anons.destroy)

            self.sureBaslat = True
            self.zamanlayici()
            self.durum["text"] = "Aktif"
            self.bulunanMetin["text"] = "Bulunan Metin: 0"
            threading.Thread(target=self.saldir(self.kesimsuresi.get(), wincap)).start()
        except Exception as e:
            print("wincap hatası", e)
            messagebox.showerror("Hata: Ekran Bulunamadı", f"Seçilen isimde ekran bulunamadı.\n{e}")
    def durdur(self):
        self.sureBaslat = False
        self.durum["text"] = "Pasif"
        self.start.config(state=NORMAL,cursor="hand2", bg="red", fg="white")
        self.kilitle.config(state="normal")

    def dur(self, key):
        if key == keyboard.Key.f3:
            print("Tuşa Basıldı", key)
            self.durdur()
            return False

    def saldir(self, saniye, wincap):
        try:
            self.metine_vur = False
            self.s1 = 0
            self.kontrol = 0
            with keyboard.Listener(on_press=self.dur) as dur:   
                while True:
                    if not dur.running:
                        print("Çıkıldı")
                        break
                    else:
                        ss = wincap.get_screenshot()
                        rectangles = self.cascade.detectMultiScale(ss)

                        if not self.metine_vur:
                            self.metine_vur = True
                            thrd = threading.Thread(target=self.metinevur, args=(rectangles,saniye, wincap))
                            thrd.start()

        except Exception as e:
            self.durdur()
            print("Func: saldir - ",e)
            messagebox.showerror("Hata: saldir", f"Hata Oluştu.\n{e}")
        
    def metinevur(self,rectangles, metinKesmeSuresi, wincap):
        if len(rectangles) > 0:
            targets = self.vision.get_click_points(rectangles)
            target = wincap.get_screen_position(targets[0])
            pyautogui.moveTo(x=target[0], y=target[1]+5)
            sleep(0.1)
            pyautogui.click(button='right')
            print(self.s,"      Metin Bulundu")
            self.bulunanMetin["text"] = (f"Bulunan Metin: {self.s}")
            sleep(0.8)    # Metine gitme süresi. Metin taşına yetişemiyorsa bu süreyi arttırın.
            start = time()
            while ((time() - start) < float(metinKesmeSuresi)):
                pydirectinput.press("space")
            sleep(0.1)
            self.s += 1
            
        else:
            self.s1 += 1
            # print(self.s1, "Bulunamadı")
            pydirectinput.press("e", presses=6)
            pydirectinput.press("f", presses=6)
            self.kontrol += 1
            if self.kontrol >= 3:
                # print("Kontrol", self.kontrol)
                self.kontrol = 0

        self.metine_vur = False

root = Tk()
app = Window(root)
root.wm_title("Metin2 Metin Botu | 14.12.2021")

windowWidth = root.winfo_reqwidth()
windowHeight = root.winfo_reqheight()
positionRight = int(root.winfo_screenwidth()/3 - windowWidth/2)
positionDown = int(root.winfo_screenheight()/3 - windowHeight/2)
root.geometry(f"390x210+{positionRight}+{positionDown}")
root.resizable(width=False, height=False)
def callback(url):
    webbrowser.open_new(url)
me = Label(root, text="Developer: yazilimfuryasi.com | @yazilimfuryasi", fg="#6E7371",cursor="hand2",font="Verdana 7 bold")
me.pack(side=BOTTOM)
adres = "https://www.instagram.com/yazilimfuryasi/"
me.bind("<Button-1>", lambda e: callback(adres))

root.mainloop()

Bu arada yeni cascade model dosyasi olusturarak denedim. Oyle de sürekli arıyor ekran da onu. Eski cascade dosyasinin icine ekledim bot defteri ile hata aldim o zaman. İcine ekledim ama hepsi yerli yerindeydi yine de hata aldim.

Sorunuma yardımcı olur musunuz ?

Yardımcı olmaya Türkçem yetmedi. Genelde birden çok dil bilen insanların dil bilgileri de düzgün olur. Ona güveniyordum ama olmadı.

“Benim eklemek istediğim şey ekrana bir resim çıkınca benim kod çalışmayı durduracak”

Senin resim neden çıkacak durup dururken? Resim çıkınca dur kodu yaz o zaman.

“Bu resmin içinde 6 tane daha resim var”

Senin resmin içinde 6 tane resim mi var? Toplam 7 resim mi oldu şimdi?

“Benim tanıttığım resime tıklayacak”

Resmi ne zaman tanıttın? Senin resmin, içindeki 6 tane resim ve şimdi tanıttığın resimle beraber 8 resim mi oldu?

“eğer yanlış resme tıklarsa tekrar aynı işlemi yapacak”

Senin çıkan resme mi, içindeki 6 resme mi sonra tanıttığın resme mi tıklarsa doğru kabul edeceksin?

“aynı işlemi yapacak doğru resme tıklayana kadar”

Aynı işlem? Resim çıkarmak mı? Resmin içine 6 resim mi? Resim tanıtmak mı? Durmak mı?

Hangi aynı işlem?

“Doğru resme tıklayınca o büyük resim ekrandan kayboluyor zaten”

Doğru resim hangisi? Ekrandan kayboluyorsa tıklayyınca neyi tekrarlayacak?

“Onu görmeyince de tekrar benim ilk kodlarımı çalıştıracak”

Neyi görmeyince? İlk resmi mi? Altı resim olanı mı? Tanıttığın resmi mi? Doğru olan resmi mi?

Hangi ilk kodlar?

“eğer ekrana resim çıkarsa kod dur tanıttığım resme tıkla”

Ekrana resim neden durduk yere çıksın?

Zaten sen ekrana çıkarırsın, çıkarsa da tıklayana kadar kod durur zaten?

Ne zaman tanıttın resmi?

Tanıttığın resime tıklatacaksan neden tanıtıyorsun? Tanıtmaktan kastın nedir?

“Umarım anlatabilmişimdir”

Hiç umduğun gibi değil.

Hiç anlamadım.

Ne amaçladığını neden yapmaya çalıştığını biraz örneklemen gerekir. Bir de Türkçe anlamıyorum, ingilizce anlatmayı dener misin?

Şu robot değilim resimleri gibi bir şey istiyorsun gibi geldi ama emin olamadım.

Korkarım iyi bir programcı değilsin ve ne yaptığını bilmiyorsun, yapmak istediğini nasıl yapacağının bu şekilde yanından bile geçmen mümkün değil.

Bu kadar bilinmezin içinden yardımcı olabilir miyiz ben de emin olamadım.

2 Beğeni

Hocam öncelikle yazınız için teşekkür ederim.
“Senin resim neden çıkacak durup dururken? Resim çıkınca dur kodu yaz o zaman.”
Kodlar bir oyun botu olduğu için bot kontrol maksatlı saatte bir ekrana bot kontrol resmi çıkar.
“Senin resim neden çıkacak durup dururken? Resim çıkınca dur kodu yaz o zaman.”
Bot kullanmadığını kanıtlamak için saatte bir çıkar. Resim çıkınca dur kodunu bilmiyorum onu sordum zaten aynı zaman.
“Senin resmin içinde 6 tane resim mi var? Toplam 7 resim mi oldu şimdi?”
Ekrana gelen bir bot kontrol resmi. Resimde tarif edilen resme tıklayın gibi bir ibare var. Tıklayacağımız resim de 6 taneden 1’i.
“Resmi ne zaman tanıttın? Senin resmin, içindeki 6 tane resim ve şimdi tanıttığın resimle beraber 8 resim mi oldu?”
Resmi daha tanıtamadım bilmediğim için bunu sordum. Hayır sadece bot kontrol ekranını ve içinde doğru olan resmi tanıtacağım. Yani 2 resim.
“Senin çıkan resme mi, içindeki 6 resme mi sonra tanıttığın resme mi tıklarsa doğru kabul edeceksin?”
Yanlış resime tıkladığında bot kontrol ekrandan gitmiyor sadece ekranda yeri değişiyor. Yanlışa tıklarsa tekrar tarayıp tekrar tıklasın.
“Aynı işlem? Resim çıkarmak mı? Resmin içine 6 resim mi? Resim tanıtmak mı? Durmak mı?”
Aynı işlemden kastım Oyun botunu başlatmak.
“Doğru resim hangisi? Ekrandan kayboluyorsa tıklayyınca neyi tekrarlayacak?”
Doğru resim benim tanıtacağım 2.resim.
“Neyi görmeyince? İlk resmi mi? Altı resim olanı mı? Tanıttığın resmi mi? Doğru olan resmi mi?”
Ekrana gelen bot kontrol resmini.
“Hangi ilk kodlar?”
Oyun botumu.
“Ekrana resim neden durduk yere çıksın?”
Oyunda bot olmadığını kanıtlamak için bir süre sonra çıkıyor.
“Zaten sen ekrana çıkarırsın, çıkarsa da tıklayana kadar kod durur zaten?”
Bunu anlamadım.
"Hiç umduğun gibi değil.

Hiç anlamadım."
Umarım şimdi daha anlamlandırıcı olmuştur. Bi alt cevapta kısaca bahsedicem tekrar.
“Ne amaçladığını neden yapmaya çalıştığını biraz örneklemen gerekir. Bir de Türkçe anlamıyorum, ingilizce anlatmayı dener misin?”
İngilizcem yok maalesef.
“Şu robot değilim resimleri gibi bir şey istiyorsun gibi geldi ama emin olamadım.”
Hemen hemen.
“Korkarım iyi bir programcı değilsin ve ne yaptığını bilmiyorsun, yapmak istediğini nasıl yapacağının bu şekilde yanından bile geçmen mümkün değil.”
Evet olmadığımı biliyorum. daha yeni başlamış biriyim. Belki sizden daha uzun süre çalımam gerekecek sizin seviyenize gelmem için.
“Bu kadar bilinmezin içinden yardımcı olabilir miyiz ben de emin olamadım.”
Bi alt cevapta kısaca daha anlamlı bahsedicem.

Hocam Öncelikle anlatamadığım için kusura bakmayın.
Bir oyun botu kullanıyorum. Oyunda bot olmadığına dair bazen saat başı bazen 30 dakika da bir Bot kontrol için ekranda bir resim belirir. Bot doğrulama benzeri birşey. O resim içerisinde 6 adet resim olur. Ve bot kontrol için şu resmi seçiniz ibaresi bulunur. O resmi seçince 30dakika yada 1 saat kadar gelmez o bot kontrol bir daha ekrana. Yani Anlattığım şey kısaca ekranda bir resim var o resme tıkla. Taramayı 20 saniye de 1 de yapabilir. Botu durdurmayadabilir. Sadece imagesearch ile de yapılabilir. Ben daha detaylı yapmak istedim fakat baya zorlandım. O yüzden şu anda sadece imageSearch kullanarak yapıcam. Ekrana çıkan bot kontrol içindeki doğru resmi taratıcam daha farkedince tıklamasını sağlıycam. Oyun botunu vs durdurmasını istemiyorum artık. Umarım daha açıklayıcı olmuştur. Şimdiden teşekkürler.

Şöyle yapsak olur mu?

Öncelikle 6 resmi bir araya getirmeyi öğrensek?

Şu linkt gösterdiğim gibi, resimleri birleştirmeyi öğrenseniz.

Concatenate images with Python, OpenCV (hconcat, vconcat, np.tile) | note.nkmk.me

3 resim yan yana

Sonra bunlardan iki tanesini de alt alta birleştirsek.

Sonra doğru resim için son oluşan resimdeki koordinatları alsak.

Doğru alana tıkladıysa devam etse.

Python get mouse x, y position on click - Stack Overflow

Yani aslında sadece resimleri tanımak gerekmez.

Resimin bulunduğu alana tıkladıysa doğru resimdir diyebiliriz.

30 dakikada bir ana ekranı disable edersin, resim ekranını enable edersin.

Resimleri rastgele birleştirdikten sonra. Doğru varsaydığın mouse alanına tıklanırsa tekrar resmi disable edip, ana ekranı çalıştırırsın.

Biraz uğraş içindne çıkamazsan koda beraber bakarız.

Hocam 6 resmi yanyana neden koyalım ? Ben pek anlatamadım galiba kusura bakmayın. Hocam 6 fotoğraflı bir Bot kontrol ekranı çıkıyor ve ekran da 1 fotoğraf doğru olan. Tek o fotoğrafı tanıtmak yeterli değil mi?

Bot kontrol yazılımı mı yapıyorsun?

Bot kontrolünü mü aşmaya çalışıyorsun?

Asıl soru bu.

Bot kontrolünü aşmaya çalışıyorum hocam.

Şimdi anlaştık.

Baştan şöyle sorsa idin bu kadar yazışmazdık.

Ben bir bot yazdım, bir oyunda bot kontrolü için 6 resim içerisinden doğru olanı seçerek aşmam gerekiyor.

Çıkan resim içerisinde benim seçtiğim resme tıklacak. Böylece bot kontolünü geçmiş olacağım

Nasıl yapabilirim?

Ben ancak bu şekilde anlayabilirim, kusuruma bakma.

Ben olsam şöyle bir yol izlerdim.

Ekran resmi alırdım (screenshot) sonra bu ekran resmi datası içinde, seçtiğim resmin datasını aratır ve koordinatını belirler, sonra click event yollardım.

Anlatması kolay hadi yap bakalım dersen, zaman ayırır mıyım bilmem.

python - How to find a transparent icon in a picture? - Stack Overflow

Bir alan içinde resim bulmak.

Daha üstte de klicklemek için link vermiştim.

Bunlara rağmen yapamazsan fırsat bulursam beraber bakarız.

Hocam bende Aynısını söylemiştim zaten :smiley:
Tıklatmayı nasıl yaptıracağız hocam ?
Verdiğiniz kodlar koordinat bulma var sadece

Eminim söylemişsindir. Ama ben anlayamamışımdır.

İletişimi düzelttik sorun değil.

Anladığıma göre çözüm önermeye çalışabilirim.

python - How to Click a Button with PyWinAuto - Stack Overflow

Windows’ta Programları Otomatikleştirmek için pywinauto kullanın (ichi.pro)

Buradan sonra ya masa üstü koordinatı olarak yada uygulama handle ı yakalayarak yapman gerekecek.

Ben olsam Pywinauto kütüphanesini okumaya başlardım.

bunun için pyautogui kullanmak çok daha mantıklı ve kolay gibi geldi.

1 Beğeni

Hocam 1.uygulama mouse kontrol icin 2. uygulama da windows uygulama ekranını yakalamk için sanırsam.

Kullandığım botda zaten pyautogui kullanıyorum. Yukarıda kodlar var. Yine onu kullanırım muhtemelen.

Sanırım her şeyi en başından başlayarak anlatmam gerekecek.

Aslında bot oluşturmakla ilgili kitaplar falan var ama ben onların yaklaşımıyla değil kendi bakış açımla yazmaya çalışacağım.

Hayatta iki tür insan vardır, biri hemen sonucu alıp işine gücüne devam edenler, diğeri ise sonuca giderken arkasında ne olup bittiğini anlamak için zaman ayıran insanlar.

İlk tür insanlara kızmam, saygı duyarım. Hadi işimi gör bende kodumu alıp gideyim demeleri normal. İnsanların aceleleri var. Ama maalesef ben o insan türüne hitap edemiyorum.

Bunun arka planında neler dönüyor diye düşünecekler varsa karaladıklarımı okumaya devam edebilirler.

Öncelikle bir işi yapmanın birden çok yolu vardır. Yol tektir diyemeyeceğim. Bu nedenler birden çok yoldan bir kaçına bakmak gerekir. Tercihler ilerlenecek yolu belirler.

Genelde bu aralar şuraya buraya tıklayan makrolar vs tarzında talepler çok görmeye başladım. Sanırım online oyunlarda sıkılanlar buna çözümler arıyor.

Bu durumda ilk basamak. Bu sıkıntıyı aşan bir bot programlayan kesin biri vardır. Onların hazır kodu yada programı doğrudan kullanılabilir.

Ama bu işin arka planı nedir nasıl yaklaşabiliriz dersek iş bu durumda farklı yürüyecektir.

Neden gaz ve toz bulutu dedim?

Basit.

İlk kural, işletim sistemini tanı kuralı.

İşletim sistemini tanımadan bilgisayara asla tam olarak hakim olamazsınız.

Üzerinde koşturduğunuz tüm programlar döner dolarış, işletim sisteminin istediği şekilde çalışır.

Ve işletim sistemlerinin kurallarına uyarlar.

Bunları anlamadan, yapmak yada yaptırmak istediğinizi yapmaya çalışırsanız, ya anlamadığınız hazır kodları yada hazır kütüphaneleri kullanırsınız.

Bu durumda, kodu değiştirdiğinizde beklediğiniz sonuçlara ulaşamayabilirsiniz.

Bu sefer kendiniz o kütüphaneyi öğrenmeye çalışırken yada bu şekilde çözemiyorum deyip vazgeçme noktasında bulabilirsiniz.

Konunun başına yani ilk soruya bağlayacağım.

Ama öncesinde şurada anlaşalım.

Windows işletim sistemi konuştuğumuzu varsayalım.

Anlatacaklarım antroid ve linux türevlerini kapsamayacaktır fakan onlarda da benzer yaklaşımlar vardır.

Windows klasiğidir çoklu çalıştırma desteği sunan, bir işletim sistemidir denir.

Yani birden fazla programı aynı anda çalıştırırsınız.

Bu bir not defteri, bir oyun, bir video bir web sayfası yada başka bir program olabilir.

Konumuz bir bot tasarımı,

Ve bir şeylere tıklamak bir şeyleri sürüklemek, bir şeyleri öne getirmek yada arka plana itmek isteyebilirsiniz.

Peki nasıl yaparız?

Daha doğrusu önce windows bunu nasıl yapar?

Windows bir program çalıştırdığınızda ona bir processID ( işlem numarası) atar ve bir listede tutar, ve bu process in bir geri çağrılarılabilir fonksiyonunun da adresini kaydettirmenizi ister. (aslında bir kaç callback fonksiyon vardır ama örnek bir olsun.)

Bu listedeki id leri kullanarak sıra ile işlemci zamanı tahsis ederek programları yürütür, durdurur, sonra diğerine de aynısını liste boyunca devam eder.

Bu liste üzerindeki hızlı göngü paralel çalışma/ çoklu çalışma yanılgısını yaratır.

Bu process lerin bazılarının pencereleri olabilir, hatta birden fazla penceresi olabilir ve hatta hiç penceresi olmadan da çalışan process ler olabilir.

Her bir process in idsi olduğu gibi her bir pencereninde windows handle adında bir id numarası olur.

Siz, tıklamak sürüklemek, çift tıklamak gibi bir eylem gerçekleştirdiğinizde, mouse imlecinizin altında aktif hangi pencere varsa, o pencerenin idsine ait callback fonksiyon çağırılır ve ona tıklama mesajı gönderilir.

Eğer id ile ayrılmamış olsa idi, bir tıkladığınızda tüm pencereler tıklamaya cevap vermek zorunda kalırdı, oysaki sadece ilgili pencere bu mesajı işler diğer pencereler bu mesaj ile ilgilenmez.

Bunu neden anlattım.

Bir bot yazdığınızda, eğer doğru programı tespit etmedi iseniz, doğru pencereye ulaşamadıysanız, doğru pencerenin button idsine ulaşmadı iseniz, gönderdiğiniz tıklama mesajı anlamlı olmayacak ve istediğiniz gibi çalışmayacaktır.

Aynısını, online web browser üzerinde de söyleyebiliriz, sekme, frame ve butan kimliklerine ulaşmada ilgili tıklama mesajlarını ulaştıramazsınız.

Bu anlattığım ileri seviye bir teknik olup, window enumeration olarak adlandırılan, pencere listelerine ulaşmayı ve doğru pencereye komutlar yada mause yada buton mesajları hatta klavye mesajları da göndermeyi sağlayan bir yoldur.

Sonuç adı üstünde bot, programa özel çalışır. Programı inceleyip, hangi pencereleri, alt pencereleri açtığını tespit edip doğrudan bunlara mesaj yollayabilirsiniz.

Python Examples of win32gui.EnumWindows (programcreek.com)

Kodları denemedim, genelde c ve c++ ile kodlamayı tercih ederim ama buradan da deneyerek pencereleri nasıl listeleyeceğinizi görebilirsiniz.

Mesela bir programı kapatmak isteyebilirsiniz.

automation - How to close two windows of the same application using python? - Stack Overflow

Kullanacağınız programın pencere ve alt pencerelerini inceler, ne zaman hangi hallerde tıklayacağınızı yada ne zaman ön plana getirip ne zaman arka plana iteceğinizi tespit edersiniz.

Ardından ilgili buton yada pencereye mouse mesajını doğrudan gönderirsiniz.

Bu kadar karmaşaya girmem ben sadece mouse tıklasın istiyorum derseniz.

Dikkat etmeniz gereken ikinci bir husus ortaya çıkacak.

Ekran çözünürlüğünüz önemli.

Çünkü mousa bir koordinata git ve tıkla diyeceksiniz.

Ama o koordinat o çözünürlük değerlerine göre geçerlidir.

Eğer çözünürlük farklı ve pencere de farklı bir yerde duruyorsa tıkladığınızda altında buton olmayacak sonuçta butona tıklanmadığı için de iş doğru yapılmamış olacak.

Burada yine işletim sisteminin önemi devreye giriyor.

İki tip koordinat var. Aslında daha çok da şu an girmeyeyeim.

Bir çalıştırdığınız pencerenin koordinatları içerisinde geçerli, diğer ise tüm masa üstü koordinatlarına göre imlecinizi konumlayacak olan.

Bu ikisinin farkını ikisi arasında nasıl geçiş yapacağınızı iyi bilmelisiniz.

Bunun için aslında windows basit bir yol sunar.

Açılan pencerenizin köşe koordinatı ile masa üstü koordinatınızın köşe koordinatını deplase ederek iki şekilde de kullanmanızı sağlar.

Ama bunu tam kavramadan bir butona tıklamaya çalıştığınızda buton yerine çalıştırdığınız pencereyi sıfır koordinatı sayan bir noktadan ötelenerek yanlış yere tıklayabilirsiniz.

Laf kalabalığını özetleyim.

Birinci yöntem, programın bileşenlerine dokunarak id ler üzerinden yönetmek

İkinci yöntem, imleç koordinatları ile tıklamayı simüle etmek.

Simüle edilen tıklama koordinatı doğru değilse çuvallarsınız.

Pencere en üstte değilse çuvallarsınız vs. vs.

İşletim sistemini tanıyın, pencere buton enümerasyonlarını öğrenin.

Gelelim.

Yukarıdaki ilk mesaja dair hususa.

Uzun iletişim sonunda bir altılı resim gurubu içinde doğru resme tıklamak için bir bottan bahsediyoruz.

Masa üstü ekran resmi alırım.

Masa üstü ekran resmi üzerinde tanımladığım resim koordinatlarını eşleştiririm.

Bu koordinatlardan tıklayacağım resimi bulurum.

x+Resim eni/2, y+resim boyu/2 gibi tam göbeğinden bir resim koordinatı belirlerim.

Arkasından bu koordinatın resimin pixel koordinatı olduğunu hatırlar masa üstü mouse koordinatına çeviririm.

Sonra bu koordinata bir tıklama mesajı gönderirim.

İşlem basamakları bu kadar.

Ama gerçe oyunu görse idim. ID lerini tespit eder, buton id sine doğrudan tıklama mesajı gönderir koordinatlarla da uğraşmazdım.

Biri işletim sistemi mantığı, diğeri ise bir nevi mouse makrosu tanımlamak.

Burada ayırt edici tek husus var.

OpenCV ile resim içinde belirli bir resmi yada deseni mi aramak mı gerek, yada özellikli resmimizdeki ayırt edici bir renk pixelini tespit edip.

O pixel varsa doğru resim budur deyip geçmek mi?

Bence opencv ile tüm resim sürekl yüz yada plaka tanır gibi resim kontrolü yapmaktansa, doğru resim içinde ayırt edici pixelleri tespit edip onu karşılaştırara koordinat ve doğru resmi de bulabiliriz.

Tabi illaki resim içinde resim aramak da bir çözüm.

Ama bana hep KISS presibi öğretildi. Keep it Simple and Stupid…

Şimdi yol ayrımı.

Kırmızı hap mı mavi hap mı?

Mavi hapı alın mutlu mesut kodunuzla devam edin…

Yada kırmızı hapı alıp işletim sisteminin olay yakalama (event handlig), pencere kulpları (window handle), process id ( işlem kimlikleri) gibi konulara boğulun…

Sonrasında zaten mause tıklaması göndermek dışında, metin kutularını bulup içlerini otomatik doldurmaya başladığınızı bile göreceksiniz.

Bu kadar laf salatası ve tek satır kod yok.

Üzgünüm.

Balık tutmayı anlatmak benim işim balık verecek hiç zamanım yok, yine uykumdan eksiltip bu saatte yazıyorum.

4 Beğeni

Anladığım kadarıyla oyun oynarken belirli saat aralıklarında senin bot kullanıp kullanmadığını kontrol etmek için ekranda belirli fotoğraflar beliriyor ve doğru fotoğrafı seçmeni istiyor. Eğer cevap vermezsen oyun duruyor sen de kontrol ekranı çıkınca fotoğrafları işleyen ve doğru olanı seçen bu sayede oyun oynamaya devam etmesini istiyorsun.
Eğer doğru anlamışsam öncelikle fotoğraflar arasında doğru olanı bulmamız gerekecek. Fotoğraf örneklerini bize atarsan bunun çözümü üzerine kafa yorabiliriz.
Ve sanırsam bunu yapmışsın ve bizden istediğin yalnızca ekrana tıklatmak. Bunu basit şekilde pyAutogui modülü ile click methodunu kullanarak yapabilirsin.
Ekranda fotoğrafları yakalamak ve istediğin koordinata tıklamak işin kolay kısmı asıl zor olan fotoğraflar arasından doğru olanını nasıl seçeceksin.
Bana kalırsa 30 dakikada bir oyunu baştan başlatıp oyunu oynatan bot yazman daha kolay olacak. Bu sayede bot sistemine de takılmamış olursun.

2 Beğeni