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

目的

ここでは、bioinspired モジュールが、ある特定の光条件下で我々の目が知覚するよく知られた錯視、すなわち Adelson のチェッカーボードをどのように再現できるかを示す。

Adelson のチェッカーボード

下のチェッカーボード画像を見ると、人間の目は「B」のマスを「A」のマスより明るく知覚するが、両者はまったく同じRGB色で描かれている。もちろん物理世界では、チェッカーボードの「B」のマスは「A」より明るいが、この画像では緑のシリンダーの影が「B」のマスにかかることで、結果的に「A」と「B」のマスが実際には同じ輝度を持つようになっている。

Adelson checkerboard

我々の視覚系は影を「補正」し、あたかも影が存在しないかのように「B」のマスを明るく知覚させる。これは中心窩領域で行われる局所適応プロセスによるものである。

Adelson によるオリジナルの説明は こちら で見ることができる。

証明: 画像編集プログラムを使い、2つのマスの一部を切り出して背景なしで見比べることで、自分自身を納得させることができる。ピッカーツールで2つのマスのRGB値を測定することもできる。

この画像では、AとBのマスの小片を切り出して並べて配置した。両者が同じ輝度を持つことは一目瞭然のはずである。

この錯視が機能するのは、ノートパソコンの画面上で見るチェッカーボード画像が、網膜の局所適応が2つのマスを同時に考慮するような寸法で網膜に投影されるためであることを知っておくとよい。

中心窩の視野領域は、1メートル先で1インチ程度のものである(そして眼はいわゆる「サッカード」によって絶えず動いているため、脳はリアルタイムで色のシーン全体を再構成できる)。これは、AまたはBのいずれか1文字がいつでも中心窩に当たりうることを意味する。

重要なのは、1回の眼の固視で両方の文字を同時に見ることができなくても、ある文字を見ているときに中心窩はその周囲の光情報も考慮するという点である。つまり、中心窩は実際には隣接する細胞も知覚している。

正味の効果として、ある領域を見るとき、眼はその領域を取り囲むものを考慮して、局所的に輝度に適応し、ノイズを除去し、輪郭を強調するなどし、これが錯視を機能させる。これを網膜は「中心-周辺 (center surround)」方式で機能すると言う。

したがって、より明るい細胞に囲まれた「A」の細胞は、より暗く知覚されうる。比較として、細胞「B」の近傍はより暗いため、細胞「B」はより明るく知覚される。

最後に、影のエッジは柔らかいため、網膜はこの情報を除去する。その結果、影はチェス盤全体の観察を妨げず、知覚された細胞の輝度によって「自信を持って騙される」ことを可能にする。

錯視の再現

bioinspired モジュールは、(同時に)小細胞性網膜プロセス、すなわち我々の中心窩視覚を模倣し、我々の目の局所適応を再現する。

これは、parvo チャンネルの出力が、我々の目で知覚するものに近い輝度値を実際に含むと期待できることを意味する。具体的には、この場合「B」のマスのRGB値が「A」のものよりも実際に明るくなると期待される。

我々の目の動作を正しく模倣するには、opencv に正しい画像部分で局所適応を行わせる必要がある。これは、opencv の「局所」の概念が我々の画像の寸法と一致するように確保しなければならないことを意味する。さもなければ、局所適応は期待通りには機能しない。

このため、画像解像度に応じて hcellsSpatialConstant 引数(技術的には低空間カット周波数、すなわち緩やかな輝度変化への感度を指定する)を調整する必要がある場合がある。

このチュートリアルの画像では、デフォルトの網膜引数で問題ないはずである。

画像を bioinspired モジュールに与えるには、独自のコードを使うか、bioinspired モジュールに付属する example_bioinspired_retinaDemo の例を使うことができる。

実行すると

example_bioinspired_retinaDemo -image checkershadow_illusion4med.jpg

画像が小細胞性チャンネルと大細胞性チャンネルの両方で処理される(ここでは最初のものだけに関心がある)。

独自のコードを使うことを選んだ場合、小細胞性(および大細胞性)チャンネルは実際に定常状態になるまでに何回かの反復(処理されるフレーム)を必要とする点に注意してほしい。

実際、parvo(および magno)チャンネルは時間情報を考慮する。つまり、フレームを与え始めたときは、目を閉じている状態に似ている。その後、目を開けてチェス盤を見るのである。

これは静止画像だが、あなたの網膜は新しい状況(目を開けること)に移行し始めたばかりで、適応しなければならない。

この過渡状態の間は輝度情報が重要となり、多かれ少なかれ絶対輝度値が見える。絶対輝度こそ、錯視を再現するためには見てはならないものである。

定常状態に達するとすぐに、より文脈的な輝度情報を受け取るようになる。あなたの目は中心-周辺方式で機能し、注目領域の輝度レベルを評価するために近傍の輝度を考慮する。そしてそのとき、我々の錯視が現れるのである!

これはビデオを処理するときには気にする必要のないことである。なぜなら、複数のフレームを自然に仮想網膜に与えているからである。しかし、単一フレームを処理する場合にはこの点に注意する必要がある。

単一フレームを処理し、定常状態の応答だけが必要な場合に実際にやるべきことは、同じフレームを網膜に繰り返し与えることである(これがサンプルコードの行っていることである)。これは静止ビデオに対して行うのと同じである。あるいは、網膜の時間引数を0に設定して、ただちに定常状態を得ることもできる(xmlファイルの photoreceptorsTemporalConstant および hcellsTemporalConstant 引数)。ただしこの場合、実際の網膜の挙動を再現する点で意図的に精度を落としたもので実験していることを認識しておくべきである!

ここに、画像を処理するために使用した小さなPythonコードの断片がある。これは20回の反復を行う。これは、(十分すぎるほど)足りると実験的にわかった任意の数である。

import cv2 as cv
inputImage = cv.imread('checkershadow_illusion4med.jpg', 1)
retina = cv.bioinspired.createRetina((inputImage.shape[1], inputImage.shape[0]))
# the retina object is created with default parameters. If you want to read
# the parameters from an external XML file, uncomment the next line
#retina.setup('MyRetinaParameters.xml')
# feed the retina with several frames, in order to reach 'steady' state
for i in range(20):
retina.run(inputImage)
# get our processed image :)
retinaOut_parvo = retina.getParvo()
# show both the original image and the processed one
cv.imshow('image', inputImage)
cv.imshow('retina parvo out', retinaOut_parvo)
# wait for a key to be pressed and exit
# write the output image on a file
cv.imwrite('checkershadow_parvo.png', retinaOut_parvo)
void imshow(const String &winname, InputArray mat)
Displays an image in the specified window.
int waitKey(int delay=0)
Waits for a pressed key.
void destroyAllWindows()
Destroys all of the HighGUI windows.
bool imwrite(const String &filename, InputArray img, const std::vector< int > &params=std::vector< int >())
Saves an image to a specified file.
Mat imread(const String &filename, int flags=IMREAD_COLOR_BGR)
Loads an image from a file.

画像を処理するためにどの手法を使ったとしても、最終的にこのような結果が得られるはずである:

Parvo output for adelson checkerboard

結果の分析

parvo チャンネルの出力における「B」のピクセルが「A」のものより明るくなると予想していた。

.. そして実際にそうなっている!

結果の画像を見ても、一見しただけではあまりわからないかもしれない。「B」のマスは入力画像と同様、我々の目には「A」より明るく見える。違いは、入力画像とは逆に、今やピクセルのRGB値が実際に明るくなっている点である。出力画像を見るとき、我々は実際には小細胞性プロセスを2回適用していることに注意してほしい。まず bioinspired モジュールで、次に我々の目で適用しているのである。画像編集プログラムとピッカーツールでマスの輝度を測定するか、マスの小片を切り出して並べて配置することで、計算された画像に錯視が現れたことを自分自身で納得できる。

次の画像では、マス「A」の一部とマス「B」の一部を切り出し、オリジナルの Adelson 画像で行ったのと同様に並べて配置した。

Illusion reproduced

「B」のマスが「A」のマスより本当に明るいことは一目瞭然のはずである!おめでとう、あなたは Bioinspired モジュールで Adelson の錯視を再現したのである!

謝辞

以下の方々に感謝したい:

Alexandre Benoit - この仕組み全体がどのように機能するかを親切に説明してくれたこと、このチュートリアルを書く機会を与えてくれたこと、そしてそれをレビューしてくれたことに対して。

Edward Adelson - 彼のチェッカーボード画像を自由に使うことを許可してくれたことに対して。

Antonio Cuni - このチュートリアルをレビューし、Pythonコードを書いてくれたことに対して。