Fortsetzung Versuchen Sie, mit Python (2) eine Erfassungssoftware zu erstellen, die so genau wie möglich ist. https://qiita.com/akaiteto/items/56bfd8d764d42b9ff508 Versuchen Sie, mit Python (1) eine Erfassungssoftware zu erstellen, die so genau wie möglich ist. https://qiita.com/akaiteto/items/b2119260d732bb189c87
Ich habe keine Lust mehr auf Bildschirm- und Audioaufnahmen, also mache ich noch einen Teil. Der folgende Prozess ist ein grober Prozess, der derzeit vorgesehen ist.
Dieses Mal werde ich den zweiten Teil machen. Ich möchte jede Struktur der Website flexibel unterstützen Ziel ist es, den Browser mit OpenCV-Bilderkennung zu betreiben, ohne HTML zu analysieren.
Ich habe den Grund für die Nachrüstung hinzugefügt, aber ... Da der Bildschirm zusammengedrückt ist, möchte ich nur das Bild verarbeiten.
1. 1. Übergang zum URL-Ziel
2. Drücken Sie die Wiedergabetaste
3. 3. Bereich der Wetterkarte erkennen
4. Notieren Sie den erkannten Bereich
Stellen Sie sich eine Site vor, die ein Video einer Wetterkarte liefert. Der gesamte Prozess wird wie oben angenommen. Diesmal wird es wahrscheinlich 1-3 sein.
OS : windows10 ver: python3.7 web: chrome
Selenium
Verwenden wir Selenium, eine Bibliothek, mit der Sie den Browser über Befehle bedienen können. https://qiita.com/hanzawak/items/2ab4d2a333d6be6ac760 https://rabbitfoot.xyz/selenium-chrome-profile/
Nebenbei benutze ich also Chrome + Pycharm Installieren Sie den Webtreiber bei der Installation in der virtuellen Umgebung Python.
#Installation in einer virtuellen Umgebung
cd D:~ Ausgelassen ~\venv\Scripts
bat activate.bat
pip install chromedriver-binary==(Die von Ihnen verwendete Chrome-Version)
Zeigen Sie die Wetterkarten-Site an. Speichern Sie auch das aufgenommene Bild des geöffneten Chroms für spätere Schritte. Wenn Sie die unten stehende Quelle verwenden, füllen Sie bitte den Abschnitt (Ihr Benutzername) aus. Einzelheiten zum Profilpfad finden Sie unter https://rabbitfoot.xyz/selenium-chrome-profile/
from selenium import webdriver
import chromedriver_binary #Wichtig
from selenium.webdriver.chrome.options import Options
import win32gui
import win32ui
import win32con
import numpy as np
import cv2
#Holen Sie sich den Bildschirm in voller Größe
hnd = win32gui.GetDesktopWindow()
x0, y0, x1, y1 = win32gui.GetWindowRect(hnd)
fullscreen_width = x1 - x0
fullscreen_height = y1 - y0
#Browsergröße
browse_width=300
browse_height=fullscreen_height
#Starten Sie den Browser
options = Options()
options.add_argument(r"--user-data-dir=C:\Users\(Dein Benutzername)\AppData\Local\Google\Chrome\User Data")
driver = webdriver.Chrome(chrome_options=options)
driver.get("url")
driver.set_window_size(browse_width,browse_height)
driver.set_window_position(0,0)
#Browser-Screenshot
windc = win32gui.GetWindowDC(hnd)
srcdc = win32ui.CreateDCFromHandle(windc)
memdc = srcdc.CreateCompatibleDC()
bmp = win32ui.CreateBitmap()
bmp.CreateCompatibleBitmap(srcdc, browse_width, browse_height)
memdc.SelectObject(bmp)
memdc.BitBlt((0, 0), (browse_width, browse_height), srcdc, (0, 0), win32con.SRCCOPY)
bmp.SaveBitmapFile(memdc, 'PointDetect.bmp')
# driver.close()
Beim Öffnen einer Site, für die eine Anmeldung erforderlich ist. Ich mag es nicht, Code mit meinem Passwort raw zu schreiben, also mache ich es nicht.
** Wenn für die Site eine Anmeldung erforderlich ist, melden Sie sich bitte vorab über Chrome an **
user data directory is already in use, please specify a unique value for --user-data-dir argument, or don't use --user-data-dir
Der obige Fehler tritt übrigens auf, wenn Chrome ausgeführt wird. Sie können Maßnahmen ergreifen, aber dieses Mal müssen nicht mehrere Chromteile gestartet werden, daher werde ich dies nicht tun.
Lassen Sie uns die Schaltfläche durch Bildverarbeitung erkennen und darauf klicken.
Als Überblick über den Prozess Holen Sie sich die Koordinaten der Wiedergabetaste und klicken Sie auf die Koordinaten in der Pyautogui-Bibliothek. Das Problem besteht darin, die Koordinaten der Wiedergabetaste abzurufen. Es gibt die folgenden zwei Vorschläge zur Prüfung.
1. 1. Erkennen Sie die Form und ermitteln Sie die Koordinaten
2. Suchen Sie den gleichen Teil wie das Bild der Wiedergabetaste
1. 1. Erkennen Sie die Form und ermitteln Sie die Koordinaten
Machen wir es einfach mit der opencv-Funktion.
DetectTriangle.py
import cv2
import numpy as np
def DetectTriangle(img, inputNm, outputNm):
image_obj = cv2.imread(inputNm)
img = cv2.adaptiveThreshold(img, 255, 1, 1, 11, 2)
cv2.imwrite("PointDetect_threshold" + outputNm, img)
contours, hierarchy = cv2.findContours(img,cv2.RETR_CCOMP,cv2.CHAIN_APPROX_NONE)
for cnt in contours:
approx = cv2.approxPolyDP(cnt, 0.1 * cv2.arcLength(cnt, True), True)
# approx = cv2.approxPolyDP(cnt, 0.07 * cv2.arcLength(cnt, True), True) #Parameter: Beeinflusst die Genauigkeit
# approx = cv2.approxPolyDP(cnt, .03 * cv2.arcLength(cnt, True), True) #Parameter: Beeinflusst die Genauigkeit
# approx = cv2.approxPolyDP(cnt, .009 * cv2.arcLength(cnt, True), True) #Parameter: Beeinflusst die Genauigkeit
if len(approx) == 3:
print("triangle")
cv2.drawContours(image_obj, [cnt], 0, (0, 0, 255), -1)
elif len(approx) == 4:
print("square")
cv2.drawContours(image_obj, [cnt], 0, (0, 255, 0), -1)
elif len(approx) == 8:
print("circle")
area = cv2.contourArea(cnt)
(cx, cy), radius = cv2.minEnclosingCircle(cnt)
circleArea = radius * radius * np.pi
if circleArea == area:
cv2.drawContours(image_obj, [cnt], 0, (255, 0, 0), -1)
cv2.imwrite(outputNm, image_obj)
inputNm = 'PointDetect2.bmp'
srcImage = cv2.imread(inputNm)
gray = cv2.cvtColor(srcImage, cv2.COLOR_BGR2GRAY)
cv2.imwrite("PointDetect_gray.png ", gray)
kernel = np.ones((4, 4), np.uint8)
dilation = cv2.dilate(gray, kernel, iterations=1)
cv2.imwrite("PointDetect_dilation.png ", dilation)
blur = cv2.GaussianBlur(dilation, (5, 5), 0)
cv2.imwrite("PointDetect_blur.png ", dilation)
DetectTriangle(blur,inputNm,"result_blur.png ") #Verwischen
DetectTriangle(gray,inputNm,"result_gray.png ") #Graustufen
DetectTriangle(dilation,inputNm,"result_dilation.png ") #Aufblasen (weil die Wiedergabetaste klein ist)
Die Verarbeitung, die Sie ausführen möchten, ist ungefähr wie folgt.
1. 1. Vorverarbeitung
2. Schwellenwertverarbeitung
3. 3. Konturextraktion
Ich werde es mit Google Image Search Sukusho versuchen.
Graustufen als Vorverarbeitung ↓ (Ich mache verschiedene andere Dinge in der Quelle)
Schwellenwertverarbeitung ↓
Konturextraktion ↓
Rot ist ein Dreieck, Grün ist ein Quadrat und Blau ist ein Kreis. Aus den Koordinaten des Umrisses der hier ermittelten Figur Es ist eine Berechnung, um die Position der Wiedergabetaste anzugeben, bei der es sich um eine Dreiecksform handelt.
・ ・ ・ ・ ・ ・
Also ging ich zur Wetterseite. Das Ergebnis war ... nicht gut. Ich habe versucht, etwas zu verwischen, zu erweitern, Parameter anzupassen usw., aber es hat nicht funktioniert.
Die Wiedergabetaste wurde ebenfalls erkannt, es gibt jedoch zu viele Fehlalarme. Erstens ist es nicht für Standorte mit vielen dreieckigen Figuren geeignet, Ein weiterer Nachteil ist, dass Sie möglicherweise die entsprechenden Parameter für jede Site anpassen müssen.
Es wäre möglich, diese Wetterstelle spezifisch zu erkennen, Ich möchte es zu einem Format machen, das auf verschiedenen Websites erstellt werden kann, daher wird Plan 1 abgelehnt.
2. Suchen Sie den gleichen Teil wie das Bild der Wiedergabetaste
Ich werde versuchen, es durch Template-Matching zu erkennen. Es ist ein Prozess, um festzustellen, ob dasselbe wie ein kleines Bild in einem anderen Bild enthalten ist. Um einen Vorlagenabgleich durchzuführen, muss das Bild der Wiedergabetaste die richtige Antwort sein.
Also, unter dem obigen Fluss, Fügen Sie eine Phase mit dem Namen "Bild der Wiedergabetaste abrufen (manuell)" hinzu. Ich wollte alles automatisch machen, aber es kann nicht geholfen werden.
Referenz: https://shizenkarasuzon.hatenablog.com/entry/2020/03/23/005440
Stellen Sie sich vor Ein kleines Fenster wie das obige wird angezeigt, und der Benutzer wählt die Schaltfläche aus, auf die er im quadratischen Auswahlfenster klicken möchte (hellblau). Speichern Sie das Bild für eine Vorlage, die mit dem Bild von ... Manueller Betrieb wird nur zum ersten Mal angenommen.
Also werde ich versuchen, Vorlagen abzugleichen.
http://labs.eecs.tottori-u.ac.jp/sd/Member/oyamada/OpenCV/html/py_tutorials/py_imgproc/py_template_matching/py_template_matching.html
Als ich es gemäß der openCV-Beispielquelle ausführte, funktionierte es sehr gut. Gehen wir mit der Politik von 2
Ich spiele mit opencvs Absdiff (Verschiedenes) Führt eine Bewegungserkennung für die Bilder vor und nach dem Drücken der Wiedergabetaste durch. Erkennt den Änderungsbereich.
Ich werde die bisherigen Quellen zusammenfassen.
Als Voraussetzung ist das Bild des Teils, auf das Sie klicken möchten, Angenommen, Sie haben hier bereits ein Bild der Wiedergabetaste. ↓ Bild wie unten ausschneiden
Installieren Sie vor dem Ausführen die folgenden Bibliotheken.
pip install PyAutoGUI
In meiner Umgebung ist der folgende Fehler aufgetreten und die Installation ist fehlgeschlagen.
SyntaxError: (unicode error) 'utf-8' codec can't decode byte 0x93 in position 0: invalid start byte (sitecustomize.py, line 7)
https://qiita.com/hisakichi95/items/41002333efa8f6371d40 Ich habe eine ältere Version von PyMsgBox unter Bezugnahme auf installiert.
Also die folgende Quelle. Ich organisiere es nicht
Detect.py
from selenium import webdriver
import chromedriver_binary #Wichtig
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys
import win32gui
import win32ui
import win32con
import numpy as np
import cv2
def DetectMotion(ImgNm1,ImgNm2):
img1 = cv2.imread(ImgNm1, 0)
img2 = cv2.imread(ImgNm2, 0)
img1 = img1.copy().astype("float")
cv2.accumulateWeighted(img2, img1, 0.6)
cv2.accumulateWeighted(img2, img1, 0.6)
frameDelta = cv2.absdiff(img2, cv2.convertScaleAbs(img1))
thresh = cv2.threshold(frameDelta, 3, 255, cv2.THRESH_BINARY)[1]
contours, hierarchy = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
img2 = cv2.imread(TEMP_AFTER_SCREENSHOT)
top_left_X = 9999999
top_left_Y = 9999999
bum_right_X = 0
bum_right_Y = 0
for i in range(0, len(contours)):
if len(contours[i]) > 0:
# remove small objects
if cv2.contourArea(contours[i]) < 500:
continue
rect = contours[i]
x, y, w, h = cv2.boundingRect(rect)
pos_top = (x, y)
pos_bum = (x + w, y + h)
print(x, y, x + w, y + h)
top_left_X = pos_top[0] if top_left_X > pos_top[0] else top_left_X
top_left_Y = pos_top[1] if top_left_Y > pos_top[1] else top_left_Y
bum_right_X = pos_bum[0] if bum_right_X < pos_bum[0] else bum_right_X
bum_right_Y = pos_bum[1] if bum_right_Y < pos_bum[1] else bum_right_Y
return (top_left_X, top_left_Y), (bum_right_X, bum_right_Y)
def DiffImage(img1,img2):
im_diff = img1.astype(int) - img2.astype(int)
im_diff_abs = np.abs(im_diff)
return im_diff_abs.max()
def DetectBtn(bmp,memdc,CapFIleNm,PatchNm,scrollY):
memdc.BitBlt((0, 0), (browse_width, browse_height), srcdc, (0, 0), win32con.SRCCOPY)
bmp.SaveBitmapFile(memdc, CapFIleNm)
#Schaltflächenkoordinaten abrufen
img = cv2.imread(CapFIleNm, 0)
img2 = img.copy()
template = cv2.imread(PatchNm, 0)
w, h = template.shape[::-1]
meth = 'cv2.TM_CCOEFF_NORMED'
img = img2.copy()
method = eval(meth)
res = cv2.matchTemplate(img, template, method)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:
top_left = min_loc
else:
top_left = max_loc
bottom_right = (top_left[0] + w, top_left[1] + h)
cv2.rectangle(img, top_left, bottom_right, 255, 2)
range = ((bottom_right[0] - top_left[0]) / 2, (bottom_right[1] - top_left[1]) / 2)
btn_center = (int(top_left[0] + range[0]), int(top_left[1] + range[1]))
print("Schaltfläche oben links Koordinaten", top_left)
print("Schaltfläche oben rechts Koordinaten", bottom_right)
print("Koordinaten der Schaltflächenmitte", btn_center)
#Schneiden Sie das erkannte Teil aus
img1 = img[top_left[1]: bottom_right[1], top_left[0]: bottom_right[0]]
if DiffImage(template,img1) > 180:
#Zu verschieden vom Schaltflächenbild-> False
cv2.imwrite("Detect_Fail" + str(scrollY) + ".jpg ", img1)
print("btn not exist")
return False,(0,0)
else:
#Erfolg-> True
cv2.imwrite("Detect_Success" + str(scrollY) + ".jpg ", img1)
print("btn exist")
return True,btn_center
TEMP_BEFORE_SCREENSHOT = 'PointDetect_before.bmp'
TEMP_AFTER_SCREENSHOT = 'PointDetect_after.bmp'
TEMP_PATCH = 'PointDetect_patch.jpg'
#Holen Sie sich den Bildschirm in voller Größe
hnd = win32gui.GetDesktopWindow()
x0, y0, x1, y1 = win32gui.GetWindowRect(hnd)
fullscreen_width = x1 - x0
fullscreen_height = y1 - y0
#Browsergröße
# browse_width=fullscreen_width
# browse_height=fullscreen_height
browse_width=1920
browse_height=1080
#Starten Sie den Browser
options = Options()
# options.add_argument(r"--user-data-dir=C:\Users\Dein Benutzername\AppData\Local\Google\Chrome\User Data")
driver = webdriver.Chrome(chrome_options=options)
driver.get("https://")
driver.set_window_size(browse_width,browse_height)
driver.set_window_position(0,0)
#Warten auf Browserverhalten
import time
time.sleep(3)
#Sukusho Vorbereitung
windc = win32gui.GetWindowDC(hnd)
srcdc = win32ui.CreateDCFromHandle(windc)
memdc = srcdc.CreateCompatibleDC()
bmp = win32ui.CreateBitmap()
bmp.CreateCompatibleBitmap(srcdc, browse_width, browse_height)
memdc.SelectObject(bmp)
#Scrollen Sie, bis Sie die Schaltfläche finden
Detectflg=False
isScrolButton=False
scrollY = 0
while Detectflg==False:
scrollY += int(fullscreen_height/4)
#Holen Sie sich die Aufnahme vor und nach dem Scrollen
memdc.BitBlt((0, 0), (browse_width, browse_height), srcdc, (0, 0), win32con.SRCCOPY)
bmp.SaveBitmapFile(memdc, TEMP_BEFORE_SCREENSHOT)
driver.execute_script("window.scrollTo(0, "+ str(scrollY) +")")
time.sleep(5)
memdc.BitBlt((0, 0), (browse_width, browse_height), srcdc, (0, 0), win32con.SRCCOPY)
bmp.SaveBitmapFile(memdc, TEMP_AFTER_SCREENSHOT)
img1 = cv2.imread(TEMP_BEFORE_SCREENSHOT, 0)
img2 = cv2.imread(TEMP_AFTER_SCREENSHOT, 0)
diff = DiffImage(img1,img2)
if diff < 100:
#Der Bildschirm ändert sich auch beim Scrollen nicht->Ich habe versagt, weil ich am Ende der Schriftrolle angekommen bin
print("scrollbutton")
flg=True,btn_pos
isScrolButton=True
flg,btn_pos = DetectBtn(bmp,memdc,TEMP_AFTER_SCREENSHOT,TEMP_PATCH,scrollY)
Detectflg = flg
#Klicken Sie auf die Schaltflächenkoordinaten
if isScrolButton:
print("Button nicht gefunden")
exit()
#Wiedergabe
import pyautogui
pyautogui.click(btn_pos[0],btn_pos[1])
#Vor dem Ändern speichern
memdc.BitBlt((0, 0), (browse_width, browse_height), srcdc, (0, 0), win32con.SRCCOPY)
bmp.SaveBitmapFile(memdc, TEMP_BEFORE_SCREENSHOT)
#Warten Sie, bis sich der Bildschirm ändert
time.sleep(5)
#Nach Änderung speichern
memdc.BitBlt((0, 0), (browse_width, browse_height), srcdc, (0, 0), win32con.SRCCOPY)
bmp.SaveBitmapFile(memdc, TEMP_AFTER_SCREENSHOT)
#Bewegungserkennung
top_left,bottom_right = DetectMotion(TEMP_BEFORE_SCREENSHOT,TEMP_AFTER_SCREENSHOT)
img = cv2.imread(TEMP_AFTER_SCREENSHOT)
img1 = img[top_left[1]: bottom_right[1], top_left[0]: bottom_right[0]]
cv2.imwrite("MotionArea.jpg ", img1)
# driver.close()
Bildlauffunktion, um eine Schaltfläche und zu finden Wir haben einen Prozess hinzugefügt, um die Differenz des Bildes für eine falsche Erkennung zu verwenden, wenn die Schaltfläche erkannt wird.
Das nächste Mal möchte ich es mit der Aufnahmefunktion kombinieren, die ich beim letzten Mal gemacht habe. Na dann
Recommended Posts