サリエンシーマップを使うと、画像の中でどこが最も目立つかを計算論的に可視化することができます。広告業界のプロはあの手この手で人の視線を集めるレイアウトを模索していますが、PythonのOpenCVであれば簡単に、そして定量的に解析することが可能です。
こんにちは。wat(@watlablog)です。
画像処理の中にはサリエンシーマップという人の目の知覚に関係する解析手法があります。ここでは、PythonのOpenCVを使ってサリエンシーマップを作る方法を紹介します!
サリエンシーマップについて学ぼう!
サリエンシーとは?
サリエンシー(Saliency)とは、顕著性という意味の英単語です。
脳科学の研究分野で特に頻繁に見られる単語です。
難しい話は色々あるみたいですが、僕は専門家では無いので詳しくは語りません。ボトムアップ性注意…とか。
ちょっと何言ってるかわかりませんね。
以下の外部サイトが結構詳しく書いてあって勉強になります。
脳科学辞典:サリエンシー
サリエンシーマップとは何をするための物?
上記外部リンクにも書いてありますが、サリエンシーマップと呼ばれる解析手法を使えば、画像の輝度、色、方位、方向と様々な特徴量を計算して、「画像の中で目立つ場所」を抽出してくれます。
それが何の役に立つか?と思うかも知れませんが、世の中目立ちたがりは沢山いるものです。
例えば広告のデザインにサリエンシーマップを使えば、目立たせたいオブジェクトを際立たせるための試行錯誤に、客観的な評価を利用出来ます。
そして今流行りのYouTuber。動画のサムネは集客力を確保するために重要な役目を担っていますが、動画内の最も目立つシーンを使ってサムネを作ったりすることも可能でしょう。
本ページのようなブログでも、画像の配置やカラー、レイアウト、広告の配置はブロガーにとって気になる所、僕は面倒なのでやりませんが、こだわればきっと良い記事が書けるでしょう(…たぶん)。
では早速、Pythonでコーディングしてみましょう!
Pythonでサリエンシーマップを作成するコード
opencvの他にopencv-contribのインストールが必要
画像処理はいつもと同じようにOpenCVを使います。しかし、コーディングをする前に、インストールするパッケージがあります。以前「Pythonで画像処理!OpenCVのメリットとインストール法」でOpenCVをインストールしましたが、これだけでは足りず、以下のpipコマンドでopencv-contrib-pythonをインストールする必要があります。
1 |
python -m pip install opencv-contrib-python |
全コードとサリエンシー計算の解説
今回は比較的短いコードなので、以下に画像読み込みからグラフ表示までの全コードを載せます。画像ファイルのパスが正しければ、このコードを実行するだけで簡単にサリエンシーマップを得ることが出来ます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
import cv2 from matplotlib import pyplot as plt path = 'sample.jpg' # 画像のパス i = cv2.imread(path, 1) # 画像読み込み # サリエンシーディテクション saliency = cv2.saliency.StaticSaliencySpectralResidual_create() bool, map = saliency.computeSaliency(i) i_saliency = (map * 255).astype("uint8") # matplotlibの表示に合わせてRGBの順番に色を並び替える。 i = cv2.cvtColor(i, cv2.COLOR_BGR2RGB) # ここからグラフ設定 # フォントの種類とサイズを設定する。 plt.rcParams['font.size'] = 14 plt.rcParams['font.family'] = 'Times New Roman' fig = plt.figure() ax1 = fig.add_subplot(111) # 画像をプロット ax1.imshow(i_saliency, cmap='jet') # 軸のラベルを設定する。 ax1.set_xlabel('x [pix]') ax1.set_ylabel('y [pix]') # レイアウト fig.tight_layout() # 表示 plt.show() plt.close() |
「サリエンシーディテクション」と書いてある部分が本記事のメインですが、saliencyは計算方法を決めています。サリエンシーディテクションには様々な計算方法があり、今回はStaticSaliencyを使いました(後程その他の計算も試してみます)。
boolではTrue、またはFalseが返され、サリエンシー計算が成功すれば1になります。エラー処理等の目的で活用可能と思います。
mapがサリエンシーマップです。このmapは0~1の範囲で値が格納されているので、astype関数を使ってunit8(符号無8ビット整数型)に変換しています。こうすることで、マップの値は0~255になるので、画像表現することが容易になります。
実行結果
2つの画像でサリエンシーマップを試してみました。上の画像はド〇クエのスラ〇ムですが、一目瞭然で目に視線が行きますよね?サリエンシーマップを見てみると正に目の部分が赤くなっていることがわかり、その他キャラクターのエッジや口部分の数値は非常に低い値を示しています。感覚と一致しました(少なくとも僕は)。
続いて碁盤の上で碁石がいくつかある様子の画像です。この画像の場合のサリエンシーマップを見てみると、右下隅の定石形が高い値となっています。他の場所よりも石が密集している部分が高くなるようで、他の部分は石が1つずつしかないのに対し、唯一この部分だけ複数の石が連なっているので、確かに視線が行きやすいのかも知れません。
大体感覚通り…かな?
まとめ
サリエンシーマップは画像の中で「目立つ」部分を抽出するのに適した計算手法とわかりました。
PythonコードはOpenCVのパッケージを使えば非常に簡単にサリエンシーマップを描くことができるとわかりました。但し、これまでWATLABで扱っていたOpenCVのパッケージだけでは足りず、opencv-contribが必要だったので、pipでインストールすることが必要です。
コーディングしたプログラムを使って2つの画像のサリエンシーマップを算出してみましたが、どちらも違和感無く「目立つ」場所を示していたと感じました。
世の中色々な計算手法がありますね!「人間の知覚」が数値化されるのはホントに不思議な感覚です!
Twitterでも関連情報をつぶやいているので、wat(@watlablog)のフォローお待ちしています!
コメント