質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Chainer

Chainerは、国産の深層学習フレームワークです。あらゆるニューラルネットワークをPythonで柔軟に書くことができ、学習させることが可能。GPUをサポートしており、複数のGPUを用いた学習も直感的に記述できます。

NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Processing

Processingは、オープンソースプロジェクトによるCGのためのプログラミング言語です。Javaをベースにしており、グラフィック機能に特化しています。イメージの生成やアニメーションなど、視覚的なフィードバックを簡単に得ることが可能です。

Q&A

解決済

1回答

2715閲覧

PyQtのQScreenクラスのエラーが解決できません。

退会済みユーザー

退会済みユーザー

総合スコア0

Chainer

Chainerは、国産の深層学習フレームワークです。あらゆるニューラルネットワークをPythonで柔軟に書くことができ、学習させることが可能。GPUをサポートしており、複数のGPUを用いた学習も直感的に記述できます。

NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Processing

Processingは、オープンソースプロジェクトによるCGのためのプログラミング言語です。Javaをベースにしており、グラフィック機能に特化しています。イメージの生成やアニメーションなど、視覚的なフィードバックを簡単に得ることが可能です。

0グッド

0クリップ

投稿2018/10/30 08:31

前提・実現したいこと

PyQtでProcessingで書かれた迷路探索を自動で実行したい。
ここに質問の内容を詳しく書いてください。
Processingで作った迷路プログラムをchainerを使って学習するプログラムを作りたいと思っています。その際、GUI上の自動処理としてpyautoguiを用いています。

processing 3.4
python anaconda3-4.4.0
numpy 1.15.1
chainer 5.0.0(ニューラルネットワーク動かすためのもの)
pyautogui 0.9.38(キーボード操作、ディスプレイ内の画像検索するため)

発生している問題・エラーメッセージ

エラーメッセージ

取得に0.41797sかかりました 1回目のゲーム開始 Traceback (most recent call last): File "dqn_shimura.py", line 525, in <module> main() File "dqn_shimura.py", line 130, in main state = get_state(window_id, left, top, learning_width, learning_height, interval_w, interval_h) File "dqn_shimura.py", line 244, in get_state pixmap = test(win_id, left, top, width, height) File "dqn_shimura.py", line 299, in __init__ q=classmethod(QScreen.grabWindow()) TypeError: grabWindow(self, sip.voidptr, x: int = 0, y: int = 0, width: int = -1, height: int = -1): first argument of unbound method must have type 'QScreen'

該当のソースコード

#-*- coding: utf-8 -*- #ver0.41 2016/11/22 #python全体で使うような奴の追加 import argparse #起動時の引数設定 import os #ファイルの削除 import sys #シス import copy #データコピーテム関連(ここではプログラムの強制終了とか) import time #時間取得 import random #ランダム import configparser #iniファイルいじる import threading #マルチスレッド import csv #csvファイルの扱い(出力用) from collections import deque #デック(deque)を扱えるようにする from tqdm import tqdm #プログレスバー #ニューラルネットワークに関する追加 import numpy as np #数値計算補助(CPU) import cupy as cp #数値計算補助(GPU) import chainer #ディープネットワークのフレームワーク import chainer.functions as F import chainer.links as L from chainer import cuda,Variable,optimizers#optimizerpipsを消した(自分) from chainer import links as L #画面操作に関する追加 import pyautogui as ag #ディスプレイ内の画像検索、キーボード操作など from PIL import Image #RGB調べる #from PyQt4.QtGui import QPixmap,QApplication from PyQt5.QtWidgets import QApplication, QWidget, QLabel from PyQt5.QtGui import * from PyQt5.QtGui import QScreen from PyQt5.QtWidgets import * #引数設定 parser = argparse.ArgumentParser(description='Learning game') #行動選択の間隔(ms) parser.add_argument('--interval', default=1000, type=int, help='interval of capturing (ms)') #ゲームを回す回数 parser.add_argument('--play_number','-p' , default=1000, type=int, help='play number of count') #学習方法(初期設定DQN)(まだ使ってない) #Q・・・Q-learning #PS・・・Profit Sharing parser.add_argument('--learning_type','-l' , default='Q', type=str, help='learning type') args = parser.parse_args() #起動時の時間を保存 start_time = time.time() #サーチ間隔(ms) interval = args.interval / 1000.0 #gpuがあればcupyなければnumpyを使う(cpu未確認) xp = cuda.cupy if cuda.available else np #ランダムシードの決定 np.random.seed(0) #pyautoguiのコード実行後の待ち時間(s) ag.PAUSE = 0 #画面の位置設定 #キャプチャするウィンドウの取得 app = QApplication(sys.argv) window_id = app.desktop().winId() #ゲーム画面(学習対象)の位置(左上からの)とサイズ learning_left = 0 learning_top = 0 learning_width = 800 learning_height = 600 #学習画面の縮小度(xピクセルに一つの値を使用) interval_w = 2 interval_h = 2 #メイン def main(): #ゲーム画面認識してあったら画面にフォーカス移動,なければ終了 search = Thread_search('./image/start.png', 5) #スレッドスタート search.start() #ここでは他に動かすものがないので終わるまで待つ(この先も使うことはなかった) search.join() #値が返って来ていてディスプレイ内に認識したい画面が全部入っていたら if search.left != -1 and ag.onScreen(search.left + learning_left + learning_width, search.top + learning_top +learning_height): #画面内の適当な位置にカーソルを持って行きクリック ag.moveTo(search.left+48, search.top+16) ag.click() #画面外にカーソルを外しておく time.sleep(1) ag.press('t') time.sleep(1) #迷路の生成 time.sleep(1) ag.press('r') time.sleep(1) #迷路の写真取る ag.press('m') time.sleep(1) ag.press('g') time.sleep(1) ag.press('m') ag.moveTo(search.left-48, search.top-16) #ダメならエラーはいて終了 else : print('\033[31mError01:認識失敗 ディスプレイ内に画面がすべて入っていない場合があります\033[0m')#error01 sys.exit() #学習したい画面左上の座標を保存しておく(状態取得に使う) left = search.left + learning_left top = search.top + learning_top #エージェント作成 agent = Agent(learning_width, learning_height, interval_w, interval_h) #調整エージェント作成 tmp_agent = Agent(learning_width, learning_height, interval_w, interval_h) #インターバル調整 #ゲームを回す回数を決めておきその中かを確認 for i in range(1,args.play_number+1) : #100回に1度インターバル調整(うまくいってない?) #if i % 100 == 1: #インターバル調整 # interval = interval_adjust(tmp_agent,window_id) #最後に保存したスコアとゲームの状態と行動価値の最大値を初期化 game_state = 2 print(('%d回目のゲーム開始'%i)) #get_reward内でgame_state更新してるからこっちではそのまま調べる while game_state < 3 and agent.step < 3000: #今の時間をとっておく now_time = time.time() #現在の状態を取得 state = get_state(window_id, left, top, learning_width, learning_height, interval_w, interval_h) action_state = set_state(agent, state, learning_width, learning_height, interval_w, interval_h) #取得した状態に応じて行動を選択 action_choice, q = agent.get_action(action_state) fw = open('Q_1zikoku.csv','a') fw.write('%d回目,%f,%d\n'% (i, q, action_choice)) fw.close() #選択された行動を実際に実行する set_action(action_choice) #報酬取得 reward, game_state, ep_end, g = get_reward() time.sleep(0.2) #一時メモリに保存 agent.stock_tmp(state, action_choice, reward, ep_end) #経験メモリに入れるだけの情報が集まったら if len(agent.tmp_memory) > agent.tmp_size: #経験をストックする agent.stock_experience(g) #ステップを1増やす agent.step += 1 agent.reduce_epsilon() #最初の状態取得から次の取得の間の時間 interval_time = time.time()-now_time #情報表示 print(('%d回目\tstep%d\ttime:%01.4fs\taction:%d\tQ:%01.4f\tepsilon:%01.4f'% (i,agent.step, time.time()-now_time, action_choice, q, agent.epsilon))) agent.total_step += 1 print(('%d回目のゲーム終了'%i)) print(('ここまでのステップ数%d'%agent.total_step)) f = open('keika_1zikoku.csv','a') f.write('%d,%01.4f\n'% (agent.step, agent.epsilon)) f.close() #開始からの時間を表示 time_tmp = time.time() - start_time print(('実行時間 : %02d:%02d:%02.2f' % (time_tmp//3600, time_tmp%3600//60, time_tmp%60))) #学習をゲーム終了時にする agent.train(i,state) agent.step = 0 agent.goal += 1 time.sleep(0.5) ag.press('i') time.sleep(0.5) #-----------------↓関数とクラス↓-------------------- #特定画像がディスプレイ内に存在するか検索をするマルチスレッド用クラス #マルチスレッドにして使うときは来なかったから意味はない #pic・・・探したい画像パス #timeout・・・タイムアウトまでの時間(秒)0のときタイムアウトを行わない #スレッド実行後使う値・・・見つけた座標x,y。タイムアウトもしくは見つかるまで(-1,-1) class Thread_search(threading.Thread): def __init__(self, pic, timeout): threading.Thread.__init__(self) self.pic = pic self.timeout = timeout #変数の初期化(特に必要なのはleft,top) self.left, self.top, self.width, self.height = [-1, -1, -1, -1] #startで実行される部分 def run(self): #探し始めた時間を記録 search_start_time = time.time() while True : #画像と同じ部分を探す(1箇所のみ) pos_search = ag.locateOnScreen(self.pic) #取得できた時 if pos_search is not None: #取得した位置を変数に入れる self.left, self.top, self.width, self.height = pos_search print(('取得に%01.5fsかかりました'% (time.time()-search_start_time))) #座標をかえせる状態になったからbreak break #取得できなかった時 else : #タイムアウトするかどうかの確認 if (time.time()-search_start_time) > self.timeout and self.timeout != 0: print(('%dsで取得できませんでした'% self.timeout)) print('タイムアウト') break #タイムアウトの時間でないときwhileにもどる #行動選択の数値を3種の動作に分けてからiniに保存 def set_action(action): #choice(0~2)をもとに3つの行動に分ける #0が前進、1が左に向く、2が右に向く if action == 0: ag.keyDown('w') time.sleep(0.1) ag.keyUp('w') elif action == 1: ag.keyDown('a') time.sleep(0.1) ag.keyUp('a') elif action == 2: ag.keyDown('d') time.sleep(0.1) ag.keyUp('d') #状態state(画面のRGB情報)を入手 #win_id・・・みるウィンドウ #left・・・学習する画面の左上のx座標 #top・・・学習する画面の左上のx座標 #width・・・学習する画面の横幅 #height・・・学習する画面の縦幅 #interval_w・・・横方向の情報入手間隔 #interval_h・・・縦方向の情報入手間隔 def get_state(win_id, left, top, width, height, interval_w, interval_h): pixmap = test(win_id, left, top, width, height) print(pixmap) #pixmapにウィンドウの情報を渡す pixmap = QScreen.grabWindow(win_id, left, top, width, height) #QImageへの変換 image = pixmap.toImage() bits= image.bits() bits.setsize(image.byteCount()) #数ピクセルに一つの割合でImage型RGBモードで保存しなおす screen = Image.fromarray(np.array(bits).reshape((height, width, 4))[::interval_w,::interval_h,2::-1]) state = np.asarray(screen) ##いらない部分(画像保存できるか試してみる) #png2 = './piclog/' + str(agent.step) + '.png' #保存 #screen.save(png2) #書き込み可能に state.flags.writeable = True #元画像の緑だけを取り出す state = state[:,:,1] #戻り値にstate(現在の状態)を返す return state #行動選択時に渡す入力を作成する def set_state(agent, state, learning_width, learning_height, interval_w, interval_h): #返り値用のリスト作成 tmp = [] #まず持ってるだけ一時メモリの情報をもらう for i in range(min(agent.tmp_size-1, len(agent.tmp_memory))): tmp.append(agent.tmp_memory[i][0]) #今の状態を追加 tmp.append(state) #足りない分0行列を付け足す while len(tmp) < agent.tmp_size: tmp.insert(0, state)#np.zeros( [learning_width//interval_w, learning_height//interval_h] )) return tmp #報酬の決定 #-1から1にクリッピングする #報酬とゲームの状態と今のスコアを返す def get_reward(): goal = ag.locateOnScreen('./image/GOAL.png') #if goal == None and np.array_equal(stat,sd) == True : # return -1,2 if goal == None: return 0,2,0,goal else : return 1,3,1,goal #インターバルの時間を調整する(インターバル以外の動作を行い時間を測る) class test: def __init__(self, win_id, left, top, width, height): q=classmethod(QScreen.grabWindow(self,win_id, left, top, width, height)) print(q) 注意:文字数制限のため、省略。

試したこと

QpixmapがPyQt5に対応していない模様だったため、QScreenによる解決を図った。

補足情報(FW/ツールのバージョンなど)

サイト利用が初めてなので、至らない点が多くあると思いますが足りないファイルなどありましたらあげさせていただきます。よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

直接のエラーの原因は grabWindow の第一引数は Window id なのに、self を渡しているからではないでしょうか?

QScreen.grabWindow(self,win_id, left, top, width, height)

QPixmap QScreen::grabWindow(WId window, int x = 0, int y = 0, int width = -1, int height = -1)

QScreen::grabWindow

追記

すいませんが、コードは長いので読んでいません。
QSCreen.grabWindow() の使い方ですが、指定した ID のスクリーンから指定した範囲の画像をキャプチャして返します。

QPixmap grabWindow(WId window, int x = 0, int y = 0, int width = -1, int height = -1)

渡している引数が正しければ、そのようなエラーはでないはずなので、引数を確認してみてください。

サンプルコード

以下はボタンをクリックすると、スクリーンを grabWindow() で取得して表示するサンプルコードです。

python

1import sys 2 3from PyQt5.QtCore import * 4from PyQt5.QtGui import * 5from PyQt5.QtWidgets import * 6 7 8class MainWindow(QMainWindow): 9 def __init__(self): 10 super().__init__() 11 self.initUI() 12 13 def initUI(self): 14 self.setGeometry(300, 300, 500, 500) 15 self.setWindowTitle('Test') 16 17 centralWidget = QWidget(self) 18 self.setCentralWidget(centralWidget) 19 20 # ラベルを作成 21 self.label = QLabel() 22 self.label.setFixedSize(400, 400) 23 # ボタンを作成 24 self.button = QPushButton("capture") 25 self.button.setFixedSize(400, 50) 26 self.button.clicked.connect(self.display) 27 # レイアウトを作成 28 vbox = QVBoxLayout() 29 vbox.addWidget(self.button) 30 vbox.addWidget(self.label) 31 centralWidget.setLayout(vbox) 32 33 self.show() 34 35 def display(self): 36 print('capture screen') 37 38 screen = QApplication.primaryScreen() 39 screenRect = QApplication.desktop().screenGeometry() 40 41 print("window id: ", QApplication.desktop().winId()) 42 pixmap = screen.grabWindow( 43 QApplication.desktop().winId(), 44 0, 0, screenRect.width(), screenRect.height()) 45 46 scaled = pixmap.scaled( 47 self.label.width(), self.label.height(), Qt.KeepAspectRatio) 48 self.label.setPixmap(scaled) 49 50 51if __name__ == '__main__': 52 app = QApplication(sys.argv) 53 w = MainWindow() 54 sys.exit(app.exec_()) 55

イメージ説明

投稿2018/10/30 08:56

編集2018/10/30 10:49
tiitoi

総合スコア21956

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/10/30 09:21

ご回答ありがとうございます。 お指摘の通りなのですが、selfを渡す仕様でなくても同じエラーが出てしまいます。
tiitoi

2018/10/30 10:51 編集

grabWindow() の引数は grabWindow(スクリーン番号, 左上のx座標, 左上のy座標, 幅, 高さ) です。 型はすべて int です。回答に使い方のサンプルコードを追記しました。 そのようになっているか確認してみてください。
退会済みユーザー

退会済みユーザー

2018/10/31 07:09

ご回答ありがとうございます。 返答遅れてしまいました。申し訳ありません。 grabWindowの仕様などを調べて、引数の型なども確認しましたが解決には直結しませんでした。 しかし、Qscreenの仕様に当てはめるために試行錯誤していく過程で、 pixmap = Qscreen.grabWindowをpixmap = screen.grabWindowにしたところ、実行に成功し学習もできました。 サンプルコードの追記までしていただいて、大変感謝しています。 ご回答ありがとうございました。
tiitoi

2018/10/31 07:29 編集

今気づきましたが、QSCreen.grabWindow() は static メソッドではないので、 QScreen オブジェクトの grabWindow() というメソッドを呼ばないとおかしいと思います。 C++ のドキュメント http://doc.qt.io/qt-5/qscreen.html を見て、static メンバー関数になっていないものは、オブジェクトのインスタンスのメソッドとして呼ばないといけません。 回答のコードも screen.grabWindow() となっています。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問