シンプルなRGBカラーコンポーネントのクロマキー

予想外の場所でクロマキーの使用に遭遇する機会が増えています。 長い間、私自身の何かを実現しようとする考えが生まれました。



慣れていない人にとって、クロマキーとは何ですか? クロマキーは、フィルムビデオテレビの制作で広く使用されている画像合成技術です。 毒緑と明るい青が「キー」カラーとして最もよく使用されますが、それはそのような色合いが人の顔と髪の色のスペクトルに見られないためです。 地下の洞窟などの非常に暗いシーンでは、明るいオレンジ色をキーとして使用します。



しばらく考えて、HSLモデルを使用した最も簡単なオプションではなく、遠くから行った後、私はすぐに普遍的な何かを実現できませんでした。 私は言わなければならない、この「ある」時間は非常にきちんと引きずられた。 そして、まったく予想外に、コンポーネントの1つを単純に破棄し、その値でアルファチャネルを作成するという単純なオプションを試してみるというアイデアが思い浮かびました。 このようなタスクで最も頻繁に使用されるものの1つとして、緑のチャンネルが基礎として採用されました。

思考の流れはこれでした:

-合計で各チャネルの256階調があります

-30番目の値をほぼ下回るすべての要素は、「黒」の緑に起因する可能性があります

-緑の成分が支配的なオプションは、ほぼ確実に緑です(まだ灰色のグラデーション、灰色に近いグラデーションなどがあります)



インターネットからランダムに撮影した画像を持つ





vid8o.files.wordpress.com/2011/01/chromakey.jpg?w=620撮影



同様に撮影した背景





(誰に属しているのかわかりません)



24ビット画像と8ビットマスク(アルファチャネル)のアルゴリズムを実装します。



byte const black_threshold = 30; byte* chroma_p = chroma_data; byte* alpha_p = alpha_data; for (int counter = 0; counter < size; ++counter) { byte b = *chroma_p++; byte g = *chroma_p++; byte r = *chroma_p++; // ,      if (g > r && g > b) { //     ,       if (g < black_threshold) *alpha_p++ = 255; else { //         byte m = g - max(r, b); *alpha_p++ = 255 - m; } } }
      
      







実行、取得:



仮面





背景にオーバーレイ画像をマスクします





その結果、私たちの実装はかなり良いが非常に大まかな結果を示しています。 特に、結果の画像に緑の霧が見られます。 マスクのヒストグラムを見てください。







透明領域のマスクの主要部分は17〜100の範囲にあることがわかります。 したがって、値100〜255の間隔を間隔0〜255に引き伸ばし、シュラウドを「強制終了」して、そのようなヒストグラムを取得します。







そして、これは私たちが必要とするものにもっと似たマスクです







その結果、不要なベールを取り除きました







しかし、マスクの周りに残っているハローとトーンの緑色の「フレア」が見られます。これは元の緑色の背景に対して自然に見え、新しい背景に対してはかなり異質に見えました。 一般に、結果は安上がりでしたが、いくつかの質問が残っています。 ハローに対処する方法は? たたみ込みでマスクを狭めたり、マスクのヒストグラムを別の方法で引き伸ばしたりすることができます。



しかし、私はフレアに対処する方法がわからないので、食物はさらなる仕事のために十分です。 批判、アドバイス、推奨事項を歓迎します。



また、GPU、OpenCVなどを使用した実装を含む、類似の作品へのリンクにも感謝します。



UPD 1:処理された画像とマスクのサイズを2倍にした



All Articles