ポク太郎です。
UWSCでは“画像認識”が使えます。画像認識とは「ポク太郎を探せ!」と命令をすると「この座標にあります!」「画面上にありません!」などと判定してくれる機能です。
やり方としては、画像ファイルを用意してそのファイルのパスを指定してやることで画像認識の関数に伝えます。
UWSCでの主な画像認識の目的は“画像のクリック”と思われるので、目的の画像の中心座標を返す関数を作成します。
UWSCの画像認識
// 指定画像が画面上にあるかチェック、あればその情報を返す
戻値 = CHKIMG( [画像名, 透過色/色無視, x1, y1, x2, y2, 番号, 色幅] )
引数
画像名: 画像ファイル名(BMP形式のみ) (画像名を省略した場合はクリップボードから)
透過色/色無視:
0: 指定なし (デフォルト)
1: 左上、2:右上、3:左下、4:右下 の1ピクセルの色を透過色として処理
-1: 色を無視して形でチェックする
x1, y1, x2, y2: サーチ範囲
番号: 複数ある場合に順番を指定 (左上から)
-1: -1が指定された場合はヒットした数を戻値として返し、座標情報は ALL_IMG_X[], ALL_IMG_Y[] に格納
(G_IMG_X、 G_IMG_Y には最後にヒットした位置が入る)
色幅: チェックに色幅を持たせる (色無視指定時もしくは 16bitカラー以下の場合は無効)
IMG_MSK_BGR1 // 各色(BGR)に対し 2/256の色幅を許す
IMG_MSK_BGR2 // 各色(BGR)に対し 4/256の色幅を許す
IMG_MSK_BGR3 // 各色(BGR)に対し 8/256の色幅を許す
IMG_MSK_BGR4 // 各色(BGR)に対し 16/256の色幅を許す
IMG_MSK_B1, 2, 3, 4 // 青に対し 2/256, 4/256, 8/256, 16/256の色幅を許す
IMG_MSK_G1, 2, 3, 4 // 緑に対し 2/256, 4/256, 8/256, 16/256の色幅を許す
IMG_MSK_R1, 2, 3, 4 // 赤に対し 2/256, 4/256, 8/256, 16/256の色幅を許す
※ 演算可 例:IMG_MSK_B1 or IMG_MSK_R3(青に対し 2/256の色幅を許す + 赤に対し 8/256の色幅を許す)
戻値
有ればTRUE、無ければFALSE
TRUE の場合は見つかった座標を特殊変数 G_IMG_X、 G_IMG_Y に格納
番号にて -1指定時はヒットした数を返し、座標情報は配列変数 ALL_IMG_X[], ALL_IMG_Y[] に格納(配列はゼロから)引用:UWSCリファレンスより
うーん。CHKIMG()関数の引数が多すぎて覚えるの嫌です。というわけで、使いそうな機能だけに絞って翻訳関数作成。
“翻訳関数”とは、単に関数名の文字数を少なくしたり、引き渡すパラメータを一部固定にし簡単に呼び出せるようにするポク太郎の造語。
見つけた画像の中心座標を返す関数imgxyc()関数
同じ画像でもグラフィックカードにより表示が変化なんてことも→認識に多少幅を持たせた方がよさそう。でもIMG_MSK_BGRなんて特殊暗号を覚えたくないので数値指定に。
また、画像の中心座標を得るため、前回のBMP画像の幅と高さを得る関数を使用します。
wh=bmp(pic)
として、前回の関数に画像のパス渡し→wh[0]に幅、 wh[1]に高さが入るので、それぞれ1/2したものを画像が見つかった座標に足し算。
FUNCTION imgxyc(m,pic)//m:色幅指定、pic:ビットマップファイルのパス
DIM xy[1]
find=0
wh=bmp(pic)
SELECT m
CASE 1
IF CHKIMG(pic,,SX1,SY1,SX2,SY2,,IMG_MSK_BGR1)
xy[0]=G_IMG_X+wh[0]/2
xy[1]=G_IMG_Y+wh[1]/2
find=1
ENDIF
CASE 2
IF CHKIMG(pic,,SX1,SY1,SX2,SY2,,IMG_MSK_BGR2)
xy[0]=G_IMG_X+wh[0]/2
xy[1]=G_IMG_Y+wh[1]/2
find=1
ENDIF
CASE 3
IF CHKIMG(pic,,SX1,SY1,SX2,SY2,,IMG_MSK_BGR3)
xy[0]=G_IMG_X+wh[0]/2
xy[1]=G_IMG_Y+wh[1]/2
find=1
ENDIF
CASE 4
IF CHKIMG(pic,,SX1,SY1,SX2,SY2,,IMG_MSK_BGR4)
xy[0]=G_IMG_X+wh[0]/2
xy[1]=G_IMG_Y+wh[1]/2
find=1
ENDIF
SELEND
IF find=0
xy[0]=0
xy[1]=0
ENDIF
RESULT=SLICE(xy,0,LENGTH(xy)-1)
FEND
1,36行目 | 1 36 |
FUNCTION imgxyc(m,pic)//m:色幅指定、pic:ビットマップファイルのパス FEND |
imgxyc()関数宣言:見つけた画像の中心のx座標とy座標を返す関数。戻り値は配列として返します。引数mで色幅を指定、引数picは画像ファイルのパスです。 | ||
2~4行目 | 2 3 4 |
DIM xy[1] find=0 wh=bmp(pic) |
見つけた画像のx座標とy座標を代入するための配列変数xy[]を宣言。 画像が見つかったかどうかを記憶する変数findを初期化します。 また、目的のBMP画像の幅と高さを取得。bmp()関数はこちら(BMP画像の幅と高さを得る関数)で作成した自作関数。 |
||
5~6,12,18,24,30行目 | 5 6 12 18 24 30 |
SELECT m CASE 1 CASE 2 CASE 3 CASE 4 SELEND |
引数m(色幅)によって分岐します。 ※m=1のとき(7~11行目)のみ説明。色幅を指定する特殊変数が異なるだけなので。 |
||
7~11行目 | 7 8 9 10 11 |
IF CHKIMG(pic,,SX1,SY1,SX2,SY2,,IMG_MSK_BGR1) xy[0]=G_IMG_X+wh[0]/2 xy[1]=G_IMG_Y+wh[1]/2 find=1 ENDIF |
(引数mが1だった場合)CHKIMG()関数の色幅指定をIMG_MSK_BGR1として画像検索します。
変数SX1、SY1、SX2、SY2は、こちら(よく使う記号をグローバル宣言)で宣言した画像の検索範囲を指定するための座標で、ポク太郎が勝手に宣言した変数。(SX1,SY1)~(SX2,SY2)の範囲を探しに行きます。 使用しない場合は、SX1とSY1を0、SX2をG_SCREEN_W、SY2をG_SCREEN_Hに変えれば画面全体を探します。 G_SCREEN_W、G_SCREEN_H:表示画面の幅と高さが代入されてるUWSCの特殊変数。 画像が見つかった場合、xy[0]、xy[1]、findに値を記憶します。 探し当てた座標にそれぞれwh[0]/2、wh[1]/2(4行目で取得したBMP画像の幅と高さ)を加算し中心座標に直してxy[0]、xy[1]に代入。 |
||
31~35行目 | 31 32 33 34 35 |
IF find=0 xy[0]=0 xy[1]=0 ENDIF RESULT=SLICE(xy,0,LENGTH(xy)–1) |
もし画像が見つからなかった場合は、xy[0]=0、xy[1]=0とし、関数の戻り値として配列変数xy[]を返します。 ※配列変数を返す関数の使い方はこちら(配列変数と関数【使い方まとめ】)。 |
画像の中心座標を返す関数の呼び出しと値取得
xy=imgxyc(4,"C:\poku\ポク太郎アイコン.bmp")//4は色幅の指定です
x=xy[0]//見つかった位置の中心x座標
y=xy[1]//見つかった位置の中心y座標
1~3行目 | 1 2 3 |
xy=imgxyc(4,“C:\poku\ポク太郎アイコン.bmp“)//4は色幅の指定です x=xy[0]//見つかった位置の中心x座標が入る y=xy[1]//見つかった位置の中心y座標が入る |
配列xy[0]にX座標(画像の中心)が代入される。 配列xy[1]にY座標(画像の中心)が代入される。 |
BMP画像の幅と高さを得る関数 | 見つけた指定画像の中心座標を返す関数 | 高圧縮jpegと劣化なしbmp画像を取得する関数 | あいまいな画像認識の前に“できない理由”を調べる |
○見つけた画像の中心座標を返す関数
コメント