19

上記の2つの画像リサンプリングアルゴリズム(バイキュービックとランツォス)をC++で実装したいと思います。そこには何十もの既存の実装があることを私は知っていますが、それでも私は自分で実装したいと思っています。それらがどのように機能するかを理解したいという理由と、主流の実装にはないいくつかの機能(構成可能なマルチCPUサポートや進捗レポートなど)を提供したいという理由で、それを作りたいと思っています。

ウィキペディアを読んでみましたが、少し乾燥しすぎています。おそらく、これらのアルゴリズムのより良い説明がいくつかありますか?SOでもGoogleでも何も見つかりませんでした。

追加:これらのトピックについて、誰も私に良いリンクを教えてくれないようです。誰かが少なくともここでそれらを説明しようとすることができますか?

4

3 に答える 3

12

両方のアルゴリズムの基本的な操作原理は非常に単純です。どちらも畳み込みフィルターです。各出力値に対して、畳み込み関数の原点を移動して出力の中心に配置し、入力のすべての値にその位置の畳み込み関数の値を掛けて加算する畳み込みフィルター。

畳み込みの 1 つの特性は、出力の積分が 2 つの入力関数の積分の積であることです。入力画像と出力画像を考慮する場合、積分は平均の明るさを意味し、明るさを同じに保ちたい場合は、畳み込み関数の積分を 1 に加算する必要があります。

それらを理解する方法の 1 つは、畳み込み関数を、距離に応じて入力ピクセルが出力ピクセルにどれだけ影響するかを示すものと考えることです。

畳み込み関数は通常、距離がある値よりも大きい場合にゼロになるように定義されているため、すべての出力値に対してすべての入力値を考慮する必要はありません。

lanczos 補間の場合、畳み込み関数はsinc(x) = sin(x*pi)/x関数に基づいていますが、最初のいくつかのローブのみが取得されます。通常 3:

lanczos(x) = {
    0 if abs(x) > 3,
    1 if x == 0,
    else sin(x*pi)/x
}

この機能はフィルターカーネルと呼ばれます。

lanczos でリサンプリングするには、出力と入力を互いにオーバーレイし、ポイントがピクセル位置の場所を示すことを想像してください。各出力ピクセル位置に対して、そのポイントからボックス +- 3 出力ピクセルを取得します。そのボックス内にあるすべての入力ピクセルについて、出力ピクセル座標の出力位置からの距離をパラメータとして、その位置でのランチョス関数の値を計算します。次に、計算された値をスケーリングして正規化し、合計が 1 になるようにする必要があります。その後、各入力ピクセル値を対応するスケーリング値で乗算し、結果を加算して出力ピクセルの値を取得します。

lanzos 関数には分離可能性プロパティがあり、サイズを変更する場合、グリッドは規則的であるため、水平方向と垂直方向に別々に畳み込みを行い、各行の垂直フィルターと各列の水平フィルターを事前に計算することでこれを最適化できます。

バイキュービック畳み込みは基本的に同じですが、フィルター カーネル関数が異なります。

詳細については、本Digital Image Processingのセクション 16.3にかなり適切で完全な説明があります。

また、skiaの image_operations.ccとconvolver.ccには、lanczos 補間のかなりよくコメントされた実装があります。

于 2009-06-03T20:12:38.913 に答える
12

Ants Aasma が言っていることは大まかに違いを説明していますが、なぜそのようなことをするのかについて特に有益ではないと思います.

リンクに関する限り、あなたは画像処理の非常に基本的な質問をしています。このテーマに関するまともな入門書にはこれが説明されています。私の記憶が正しければ、ゴンザレスとウッズはそれについてはまともなのですが、私は本から離れていて確認できません。

詳細に移ると、基本的に何をしているのかを考えるのに役立つはずです。新しい値を補間したい測定値の正方格子があります。アップサンプリングの単純なケースで、すでに持っているすべての測定値の間に新しい測定値が必要だと想像してみましょう (例: 解像度を 2 倍にする)。

一般にその情報がないため、「正しい」値を取得できません。したがって、それを見積もる必要があります。これを行う方法?非常に簡単な方法は、線形補間することです。2 つの点でこれを行う方法は誰もが知っています。それらの間に線を引き、線から新しい値を読み取るだけです (この場合は中間点で)。

画像は 2 次元なので、左右と上下の両方の方向でこれを行う必要があります。結果を推定に使用すると、「バイリニア」補間が得られます。

これの主な問題は、非常にローカルで高速な「最近傍」アプローチよりも優れていますが (そして低速ですが)、あまり正確ではないことです。

最初の問題に対処するには、2 点の線形近似よりも優れたものが必要であり、より多くのデータ ポイント (ピクセル) に何かを近似する必要があり、非線形になる可能性があるものを必要とします。精度と計算コストの適切なトレードオフは、3 次スプラインと呼ばれるものです。したがって、これにより滑らかな適合線が得られ、再び、新しい「測定値」を中央の値で概算します。これを両方向に行うと、「バイキュービック」補間が得られます。

そのため、より正確ですが、それでも重いです。速度の問題に対処する 1 つの方法は、畳み込みを使用することです。これは、フーリエ領域では単なる乗算であるという優れた特性を持っているため、非常に迅速に実装できます。ただし、任意の時点での畳み込み結果が、ある関数 (イメージ) が別の製品に統合されることを理解するために、実装について心配する必要はありません。通常は、カーネルと呼ばれるはるかに小さなサポート (ゼロでない部分) 関数です。 )、その後、カーネルはその特定のポイントを中心に配置されます。個別の世界では、これらは単なる積の合計です。

3 次スプラインに非常に似たプロパティを持つ畳み込みカーネルを設計し、それを使用して高速な「双 3 次」を取得できることがわかりました。

Lancsoz のリサンプリングも似たようなものですが、カーネルのプロパティがわずかに異なります。つまり、主に異なる特徴的なアーティファクトがあることを意味します。これらのカーネル関数の詳細は十分に簡単に調べることができます (wikipedia や紹介テキストにあると思います)。グラフィックプログラムで使用される実装は、高度に最適化される傾向があり、より効率的ではあるが一般的ではない特殊な仮定を持っている場合があります。

于 2009-06-03T21:02:30.513 に答える
5

さまざまな画像補間方法の基本的な理解のために、次の記事を提案したいと思います。畳み込みによる画像補間。より多くの補間方法を試したい場合は、imageresamplerは最初から優れたオープンソースプロジェクトです。

私の意見では、画像補間は2つの側面から理解できます。1つは関数フィッティングの観点から、もう1つは畳み込みの観点からです。たとえば、畳み込みによる画像補間で説明されているスプライン補間は、キュービック補間の関数フィッティングの観点からよく説明されています。

さらに、画像の補間は常に特定のアプリケーション、たとえば画像のズーム、画像の回転などに関連しています。実際、特定のアプリケーションでは、画像補間をスマートな方法で実装できます。たとえば、画像の回転は3つのせん断方法を介して実装でき、各せん断操作中に異なる1次元補間アルゴリズムを実装できます。

于 2013-01-17T17:20:58.277 に答える