5.20. 回帰と類似度

Image クラス上のもう2つの測定は、画像をピクセル値の分布以外のものとして要約します。しきい値処理されたピクセルの線形回帰は、アプリケーションが対処できるを与えます。これはライントレースロボットへの古典的な入力です。類似度の測定は、2つの画像がどれだけ似ているかを記述する単一の数値を与えます。これはゴールデンイメージ回帰テストや大まかな変化検出器への自然な入力です。

5.20.1. 線形回帰

画像の前景ピクセルがたまたまフレームを横切るを形成する場合(ロボットが追従しているトラック上のテープ、地平線、道路や廊下の縁など)、アプリケーションは通常、個々の前景ピクセルすべてを欲しいわけではありません。それらすべてを通る最適な線を、線がどの向きでフレームのどこを横切るかを判断できるようにパラメータ化した形で欲しいのです。

get_regression() がその近似を行います。binary()find_blobs() が使うのと同じしきい値タプル形式を取り、しきい値に一致するすべてのピクセルを特定し、それらのピクセルを通る最適な線を記述する単一の line 結果を返します。

line = img.get_regression([(0, 60)])
if line:
    img.draw_line((line.x1(), line.y1(),
                   line.x2(), line.y2()),
                  color=(255, 0, 0))

この近似はTheil-Sen線形回帰です。より馴染みのある最小二乗近似よりも外れ値に強いロバストな手法です。真の線から遠く離れた少数のピクセルは、最小二乗法のように結果を歪めることがなく、これは実際のしきい値出力のノイズの多い前景という現実に合致します。

line 結果は、画像の矩形にクリップされた端点(x1y1x2y2)、線の長さと大きさ(lengthmagnitude)、そして線の幾何学的な記述を極形式(thetarho)で運びます。水平からの線の角度と、原点からの垂直距離です。極形式は制御ループが通常欲しいものです。theta は線がどちら向きに傾いているかをロボットに伝え、rho は線が画像のどこを横切るかを伝え、この2つに対するフィードバックループがロボットを線の中央に保ちます。

いくつかのキーワード引数がロバスト性とコストを調整します。x_stridey_stride は近似中にピクセルをスキップします。ストライドを大きくすると、近似するピクセルが少なくなる代わりに回帰が安価になります。area_thresholdpixels_threshold は、十分な一致ピクセルを背後に持たない線を拒否します。target_size は近似の前に入力をより小さいサイズに再スケールします。回帰は画像の80×60の代理上で、線の方向精度をあまり損なうことなく高速に実行されます。

許容可能な線を近似できなかった場合(しきい値がピクセルに一致しなかった、または線に見えないパターンに一致した場合)、メソッドは None を返します。実際のライントレースコードは、線の属性にアクセスする前にすべての get_regression() 呼び出しを None チェックで保護します。

5.20.2. 画像の類似度

別の種類の測定です。「画像には何が含まれているか?」と尋ねる代わりに、「これら2つの画像はどれだけ似ているか?」と尋ねます。使うべき操作は get_similarity() で、ソース画像と参照画像の間の構造的類似性指標(SSIM)を計算します。

s = img.get_similarity(reference)
print(s.mean, s.stdev)

SSIMは画像処理全般で使われる標準的な画像類似度の指標です。これは類似度に関する人間の直感に近い振る舞いをするためです。小さなずれや小さな明るさの変化はスコアをわずかに下げ、大きな構造的変化(物体の欠落、異なるシーン)はスコアを劇的に下げます。スコアは -1 から +1 の範囲です。+1 は2つの画像が同一であることを意味し、0 は無関係であることを意味し、-1 は構造的に正反対であることを意味します。返される similarity オブジェクトは、画像全体の平均SSIMに加えて、タイルごとのスコアの標準偏差、min、maxを公開します。

大きい数よりも小さい数の方が良いという種類の比較(「何も変わっていない」ときにゼロを報告し、変化が蓄積するにつれて上昇すべき回帰テストなど)では、dssim=True フラグが構造的非類似度を返します。これは平均SSIMを 1 から引いたもので、返り値は同一の画像では 0.0 となり、異なるにつれて上昇します。

5.20.3. SSIMの使用例

2つの一般的なアプリケーション。

ゴールデンイメージ回帰テスト。テストフレームワークは既知の良好な条件下で参照フレームをキャプチャし、それをゴールデンイメージとして保存します。その後のテスト実行は同じ条件下でキャプチャし、SSIMでゴールデンイメージと比較します。あるしきい値(許容範囲に応じて 0.95 または 0.98)を超えるスコアは合格、それ未満は不合格です。テストフレームワークは何が変わったかを知る必要はありません。SSIMスコアがその信号です。

大まかな変化検出。フレーム差分のより粗いバージョン(小さな明るさの変化は無視するが大きな構造的変化には反応するもの)を求めるアプリケーションは、ピクセルごとの difference() の後にしきい値を適用する代わりに、参照フレームに対するSSIMを使えます。SSIMはピクセルごとの差分よりも照明のドリフトに敏感ではないため、「個々のピクセルが変化した」ではなく「シーンが実質的に異なって見える」を検出することが目的の場合に、より良い選択になります。

両方のアプリケーションは同じ呼び出し(img.get_similarity(reference))を使い、返されたスコアのしきい値でトリガーします。違いは、しきい値が高いか(回帰テスト、ほぼ同一の一致を探す)低いか(変化検出、何らかの大きな構造的変化を探す)だけです。

5.20.4. 変換と比較の形式

有用な細かい点。get_similarity()draw_image() と同じ xyx_scaley_scaleroirgb_channelalphacolor_palettealpha_palettehinttransform パラメータを受け付けます。参照画像はSSIM比較が実行されるに、これらのパラメータによって配置、スケール、変換されます。

これは、事前に変換した参照画像を用意することなく、アプリケーションが「既知の変位/回転/スケールのに、このシーンは参照フレームとどれだけ似ているか」を尋ねられることを意味します。これは、パラメータ空間を探索して参照のどの変換が現在のフレームに最もよく一致するかを報告するトラッカーを構築する安価な方法です。