忍者ブログ
RoboCup Junior Japan Rescue Kanto OB

             2005~2013
[1011]  [1010]  [1009]  [1007]  [1006]  [1005]  [1003]  [1002]  [1001]  [1000]  [999
今までのブログの流れを完全に無視しています。ご了承ください。

昨日、唐突にOpenCVを使ったアプリケーションを作りました。

一体何がしたかったのかというと、

某ブラウザゲームの(ピーーーーー)がとてつもなく(ピーーーーーーー)ので

この際(ピーーー)を(ピーーーーーー)しようというのをふと思いつきまして、

手元にpythonがあったので、pythonを使ったOpenCVを使って実装できないかと思ってやってみました。


まず、OpenCVってなんじゃという人のための話ですが、

OpenCVとは簡単に言うと、コンピューター上で画像や動画の処置を行うためのライブラリです。

今回はこれのテンプレートマッチングを使って(ピーーー)を(ピーー)していきます。


まず最初にテンプレート画像となる(ピーーー)の画像をスクショします。

次にOpenCVに現在のPC画面のキャプチャをぶち込まないといけないのですが、

調べた限り、OpenCVには直接画面キャプチャをする方法はなかったので

今回はPILというライブラリをインストールします。今思えばOpenGL使えばよかったね!

ダウンロードはここから、Pillowを落としてきます。

今回はpython2.7を使用していくので Pillow‑2.7.0‑cp27‑none‑win32.whl をDLします。

whlファイルなので、インストールにはpipを使用しました。


pip install Pillow‑2.7.0‑cp27‑none‑win32.whl


pipがインストールされていればこんなかんじでインストールできますね。

今回はPILの中にあるImageGrabを使います。


次はOpenCVですが、これは公式サイトからDLします。

今回は、3.0はベータ版だったので2.4.10をDLしました。

これはexeファイルなので普通に起動してインストールします。特に環境変数の設定もせず入れるだけで使えました。

後はnumpyをインストールしました。これもここからDLします。

今回は面倒だったので最新版のexeファイルをDLしました。

以上で環境構築は終了です。ここからは簡単にプログラムについてです。


まずimportの部分です。


import cv2

import numpy as np

import time

import random

from PIL import ImageGrab

from ctypes import *



こんなかんじです。特記することもありませんね(´・ω・`)

次に画像キャプチャの部分です。

def ScreenCap(x1=0,y1=0,x2=0,y2=0):

       if x1==y1==x2==y2==0:

                img=ImageGrab.grab()

               img.save("cap.png")
        else:

               img=ImageGrab.grab((x1,y1,x2,y2))

               img.save("cap.png")


Javaのようにオーバーロードが使えればよかったのですが、残念ながらpythonにはないのでこうなっています。

呼び出すときに引数なしで画面全体を、引数ありで指定範囲[px]内の画像を取得してcap.pngに保存します。

次に保存した画像を呼び出します。ここではimreadメソッドを使っています。

temp = cv2.imread('img/temp.png',0)


今回はキャプチャ画像も一度保存してからimreadで再度呼び出しましたが、キャプチャした時点で保存せずに

def ScreenCap(x1=0,y1=0,x2=0,y2=0):
       
if x1==y1==x2==y2==0:

               img=ImageGrab.grab()

               cap = np.asarray(img) 

       else:

               img=ImageGrab.grab((x1,y1,x2,y2))

               cap = np.asarray(img) 
       return cap

       return cv2.cvtColor(cap, cv2.COLOR_BGR2GRAY)



とすることで、そのままOpenCVで使用することができるっぽいです。ぽいぽい言ってるのは試してないからですね。
2/25追記:グレースケールに変換する工程を忘れてました。てへぺろ
これで動作確認でました。一旦画像に保存して実行する場合とは類似度の結果が異なります。



次はテンプレートマッチングについてです。

テンプレートマッチングとは、簡単にいえば、

1つの大きな画像からある特定の箇所のある位置を検索するものです。

例えば与えられた画像がコレで
RCJ2013関東ブロックの被災者部屋です。 
探す対象であるテンプレート画像がコレであれば


このように探索画像のどの位置にテンプレート画像があるかを調べてくれます。



そしてテンプレートマッチングはプログラムにするとこんな感じになります。

def Temprate_matching(img,temp):
        res = cv2.matchTemplate(img,temp,cv2.TM_SQDIFF)
        w, h = temp.shape[::-1]
        min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
        top_left = min_loc
        bottom_right = (top_left[0] + w, top_left[1] + h)
        center=(top_left[0] + w/2,top_left[1] + h/2,min_val)
        return center


今回は輝度差の2乗誤差を使う方法でマッチングをしているので、

結果の最低値であるmin_valがマッチング結果となります。

今回はcenterというtupleを作って、マッチング中心点の座標及びmin_valの値をreturnするようにしています。

プログラムについては以上ですね。あとは魔法のクリック関数くらいでしょうか。

def click(posx,posy):
        windll.user32.SetCursorPos(random.randint(posx-5,posx+5),random.randint(posy-5,posy+5))
        time.sleep(random.uniform(0.05,0.1))
        windll.user32.mouse_event(0x2,0,0,0,0)
        time.sleep(random.uniform(0.1,0.2))
        windll.user32.mouse_event(0x4,0,0,0,0)


ノータイムで同じ場所に(ピーーーーーーーーー)と(ピーーーーーーーーーーーーー)ので

ここでその対策をしています。
以上OpenCVを用いた(ピーーーーーーーーーーー)の作成でした。徹頭徹尾アウトじゃねぇか(´・ω・`)

(^・ω・)ノ RadiumProduction at curonet
Comments
※コメントは内容確認後に手動で公開するようにしております。反映までしばらくお待ちください。
Your Name
Title
color
Comment
 

カレンダー
10 2024/11 12
S M T W T F S
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
最新CM
[05/09 ONE RoboCuper]
[05/07 HDD ほしいよー]
[04/21 ブラック3辛]
[12/26 bols-blue]
[06/08 ONE RoboCuper]
かうんた
カウンター カウンター
らじぷろ目次
らじぷろ検索機
プロフィール
HN:
Luz
性別:
男性

PR

忍者ブログ 2007-2021,Powered by Radium-Luz-Lα+-Rescatar in RadiumProduction [PR]


Related Posts Plugin for WordPress, Blogger...