OpenCV 5.0.0
Open Source Computer Vision
読み込み中...
検索中...
見つかりません
🤖 AIによる機械翻訳(非公式) — これは OpenCV 5.0.0 公式リファレンス(英語)を AI (Claude) で自動翻訳したものです。訳に誤りを含む場合があります。正確な情報は 公式英語版(原文) を参照してください。
画像ピラミッド

前のチュートリアル: モルフォロジー演算を用いた水平線および垂直線の抽出
次のチュートリアル: 基本的なしきい値処理

原著者Ana Huamán
互換性OpenCV >= 3.0

目標

このチュートリアルでは、以下の方法を学ぶ:

  • OpenCVの関数 pyrUp() および pyrDown() を使って、与えられた画像をダウンサンプリングまたはアップサンプリングする。

理論

覚え書き
以下の説明は、BradskiとKaehlerによる書籍 Learning OpenCV に基づくものである。
  • Usually we need to convert an image to a size different than its original. For this, there are two possible options:
    1. 画像を拡大する(ズームイン)、または
    2. 画像を縮小する(ズームアウト)。
  • OpenCVには画像を文字どおりリサイズする幾何変換関数(resize。これについては今後のチュートリアルで示す)があるが、本節ではまず画像ピラミッドの利用について解析する。画像ピラミッドは非常に幅広いビジョンアプリケーションで広く応用されている。

画像ピラミッド

  • 画像ピラミッドとは、ある1枚の元画像から生成される画像の集まりであり、目的の停止点に到達するまで連続的にダウンサンプリングされたものである。
  • There are two common kinds of image pyramids:
    • ガウシアンピラミッド: 画像をダウンサンプリングするために使用される
    • ラプラシアンピラミッド: ピラミッドの下層にある画像(解像度の低い画像)からアップサンプリングした画像を再構成するために使う
  • このチュートリアルではガウシアンピラミッドを使う。

ガウシアンピラミッド

  • ピラミッドを複数の層の集まりとして想像してほしい。層が上にいくほどサイズは小さくなる。
  • 各層は下から上へ番号が振られており、層 \((i+1)\)(\(G_{i+1}\) と表記)は層 \(i\)(\(G_{i}\))より小さい。
  • ガウシアンピラミッドで層 \((i+1)\) を生成するには、次の手順を行う:

    • \(G_{i}\) をガウシアンカーネルで畳み込む:

    \[\frac{1}{256} \begin{bmatrix} 1 & 4 & 6 & 4 & 1 \\ 4 & 16 & 24 & 16 & 4 \\ 6 & 24 & 36 & 24 & 6 \\ 4 & 16 & 24 & 16 & 4 \\ 1 & 4 & 6 & 4 & 1 \end{bmatrix}\]

    • 偶数番目の行と列をすべて取り除く。
  • 得られる画像が元画像のちょうど4分の1の面積になることはすぐに分かるだろう。この処理を入力画像 \(G_{0}\)(元画像)に対して繰り返すと、ピラミッド全体が生成される。
  • The procedure above was useful to downsample an image. What if we want to make it bigger?: columns filled with zeros ( \(0 \))
    • まず、画像を各次元で元の2倍に拡大し、新たに加わった偶数行と
    • 上に示したのと同じカーネル(4倍したもの)で畳み込みを行い、「欠落したピクセル」の値を近似する
  • これら2つの手順(上で説明したダウンサンプリングとアップサンプリング)は、OpenCVの関数 pyrUp() および pyrDown() で実装されている。以下のコード例で見ていく:
覚え書き
画像のサイズを縮小するとき、実際には画像の情報を失っている

コード

このチュートリアルのコードを以下に示す。

解説

プログラムの全体的な構造を確認しよう:

画像を読み込む

ウィンドウを作成する

ループ

ユーザー入力を待つ無限ループを実行する。ユーザーが ESC を押すとプログラムは終了する。さらに、2つのオプションがある:

  • アップサンプリングを実行 - 拡大('i' を押す)

    3つの引数を指定して関数 pyrUp() を使う:

    • src: 現在の画像兼出力画像(画面に表示され、入力画像の2倍になるはず)
    • Size( tmp.cols*2, tmp.rows*2 ) : 出力サイズ。アップサンプリングを行うため、pyrUp() は入力画像(この場合は src)の2倍のサイズを期待する。
  • ダウンサンプリングを実行 - 縮小('o' を押す)

    3つの引数を指定して関数 pyrDown() を使う(pyrUp() と同様):

    • src: 現在の画像兼出力画像(画面に表示され、入力画像の半分になるはず)
    • Size( tmp.cols/2, tmp.rows/2 ) : 出力サイズ。ダウンサンプリングを行うため、pyrDown() は入力画像(この場合は src)の半分のサイズを期待する。

入力画像が(両次元とも)2の倍数で割り切れることが重要である点に注意してほしい。そうでない場合はエラーが表示される。

結果

  • このプログラムは、デフォルトで samples/data フォルダに含まれる画像 chicky_512.png を呼び出す。この画像は \(512 \times 512\) であり、したがってダウンサンプリングしてもエラーは発生しないことに注意してほしい( \(512 = 2^{9}\) )。元の画像を以下に示す:
  • まず 'd' を押して pyrDown() 操作を2回続けて適用する。出力は次のようになる:
  • 画像のサイズを縮小しているため、解像度が多少失われているはずである点に注意してほしい。これは('u' を押して)pyrUp() を2回適用した後に明らかになる。出力は次のようになる: