UWSC|見つけた指定画像の中心座標を返す自作関数

ポク太郎です。

UWSCでは“画像認識”が使えます。画像認識とは「ポク太郎を探せ!」と命令をすると「この座標にあります!」「画面上にありません!」などと判定してくれる機能です。

やり方としては、画像ファイルを用意してそのファイルのパスを指定してやることで画像認識の関数に伝えます。

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_WG_SCREEN_H:表示画面の幅と高さが代入されてるUWSCの特殊変数。

画像が見つかった場合、xy[0]xy[1]findに値を記憶します。
G_IMG_X:CHKIMG関数で直前に探し当てた画像左上X座標が入るUWSCの特殊変数。
G_IMG_Y:CHKIMG関数で直前に探し当てた画像左上Y座標が入るUWSCの特殊変数。

探し当てた座標にそれぞれwh[0]/2wh[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画像を取得する関数 あいまいな画像認識の前に“できない理由”を調べる
本記事の内容は以下でした。
○見つけた画像の中心座標を返す関数

コメント

タイトルとURLをコピーしました