Painterly Rendering

画像を油彩のラフスケッチ風に変換するプログラムを作ってみました。画像の分析ツールを作る一環で、情報を落としてラフスケッチのようなシンプルなシェープやカラーだけを確認できたらいいなと思いました。

 

きっかけ

シンプルにするならポスタリゼーションだろう、と以前つくったカラーパレットを取り出す処理を利用して画像を減色してみることにしました。カラーパレットを指定した数(例えば32色)で取得して、全ピクセルを色空間で一番近いパレットカラーに置き換えていきます。

 

そして予想通り、なんだか味気ない結果になりました。う~ん、こういうことではない・・・。

でもボ~っと眺めていたらあることに気が付きました。自分が絵を描くときはこのポスタリゼーションの等高線(色の境界線)に沿って筆を流しているような気がする。絵を描く時と同じような手順を使ったら絵のようになるかもしれない。

自分の描き方なら手順も分かっているので、画像処理でも同じような仕組みにすれば近い結果が得られるのではないかと考えました。

 

手順

ポスタリゼーションで分けた色の境界部分だけを抽出しました。この輪郭線に筆を走らせればいい感じになりそうです。

 

次に筆を流す方向ですが、これは輪郭線の方向に流せばいいと思いました。若干強引ですが、画像をモノクロにして勾配から法線マップを生成します。そして細かい情報は要らないのでボカして大雑把にします。

 

法線マップのXとY成分を90度回転させたベクトルマップに変換します。ゲーム開発だとフローマップといわれるものですね。

 

ベクトルを確認するために矢印を置いてみました。シルエットに沿って矢印が流れているのが確認できます。

ブラシの大きさはポスタリゼーションの輪郭画像を周辺サンプリングして、輪郭線が少ないところは大きく、輪郭線が密集しているところは小さくしています。

ブラシの色は減色したポスタリゼーションの画像を下地にして同じ座標から取得しています。そして色の順番は暗から明へ重ねて描画していきます。これは油彩で描く場合と同じです。

 

ブラシはこのような画像を用意しました。これを配置していきます。

 

結果です。ラフスケッチっぽくなっていると思います。

その他の変換例です。

 

 

「ラフスケッチ風」なら今回ぐらいでいいかなと思うのですが、「油彩画風」にするとなると足りないものが多いし、全工程で修正をいれたくなりますね。何かいいアイデアが浮かんだらまた取り組んでみようと思います。

 

開発環境:VIsual Studio Community 2017, WPF

Color Scheme

画像から配色パターンを分析するプログラムを作ってみました。

学生をしていた頃のことですがアメリカの美術大学の色彩のクラスでカラースキームというものを習いました。カラースキームとは色の持つ心理的な性質を利用して雰囲気をつくる色彩設計といったところです。

今でも印象に残っているのは先生が「いい絵は必ず配色パターンを守っている」と昔の名画等を例に説明をしてくれたことでした。無意識に何となくいいなと思わせる絵はしっかり色の設計がなされているものなんだなと思いました。

そしてそんな風に絵の背景にある配色パターンを視覚化できたらいいなと思いプログラムに取り組んでみました。

カラーウィール

カラーウィールとは片側が暖色に、反対側が寒色になっている色相環チャートです。実はひとつだけではなく色々と種類があるのですがプログラムではRGBとRYBを使うことにしました。

RGBカラーウィール

デジタルではおなじみの光の三原色(赤、緑、青)をもとにしたカラーウィールです。一般的に広く利用されているのはこのカラーウィールだろうと思います。

RYBカラーウィール

赤と青と黄色を原色とした伝統的なカラーモデルで、近代の科学的な色彩理論に先立つものです。今でも絵画や美術教育の現場で使われています。自分もこのカラーウィールで習いました。RGBカラーウィールと比べると赤から黄色までの幅が広いですね。画像処理のソフトウェアでもTraditional Color Wheelといった名前で用意されていたりします。

カラースキーム

代表的なカラースキームを紹介していきます。色彩や油彩の授業ではRYBカラーウィールを使って色を習ったのでRYBをもとに説明していきます。

Analogous Color Scheme

隣り合った色を組み合わせる配色です。色相の差がないので目に優しいグラデーションの構成になります。

画像例。黄色からオレンジ、緑色のグラデーション。調和が取れた配色ですね。

Complimentary Color Scheme

反対側にある色を使った配色です。暖色と寒色のコントラストのある引き締まった配色になります。

画像例。赤い花に緑色の背景を置くことで赤がさらに赤く見えます。

Split-Complimentary Color Scheme

Complimentary Color Schemeとの違いは反対色の隣りの色を使うことでコントラストを和らげています。

画像例。黄緑色の背景に紫や赤がちりばめられています。

その他にもTriadicやSquare等といったパターンがあります。余談ですが個人的にはSplit-Complimentaryが好きな配色パターンです。絵を描くときは完全にチャート通りの配色にするのではなくAnalogousで大まかな色を埋めた後に適度に幅のある反対色をちりばめていくというパターンを好んで使っています。

プログラム

WPFを使って上記の要素をプログラムに実装してみました。カラーウィールはRYBとRGBを用意しました。ウィールによって結果の分布は変わりますね。分布は中央ほど彩度が低く、外側ほど彩度が高くなるようにしています。

画像から抽出したカラーパレットをカラーウィール内に配置し、用意した各カラースキームと分布がどれだけ近いかを計算して近いパターンから順番に並べています。

また少し歪めたカラースキームのパターンも用意しました。青とオレンジは補色の関係ですが、感覚的には水色もオレンジの補色だと思うので厳密に比較せずにパターンの形を歪めて幅を広くもたせています。

プログラムを使ってみたいという方は以下のリンクからどうぞ。画像をドラッグ&ドロップすると結果が表示されます。(あくまで試作プログラムなので精度は期待しないでください)

ダウンロードはこちら

今後の課題

色の分布を12色に分けて計算していますが、もう少し曖昧でもいいのかなと思っています。なかなか思うような結果になってくれませんが、きっちりパターンに当てはめていくのも無理があるのかもしれませんね。この辺は機械と人間の目の違いもあるかもしれません。

開発環境:VIsual Studio Community 2017, WPF

Color Palette #2

画像から代表色のカラーパレットをつくるプロセスを改良しました。前回はHSV空間を利用していたのですが、今回はこれを改めてRGB空間とHSL空間を使いました。前回の反省点はこれです。

・K-Meansで色を混ぜ過ぎて結果の彩度が落ちていた
・HSV空間の軸の単位が違うことをあまり気にせず、しかも立方体モデルを使っていた

HSVを利用していたのはHue(色相)をもとに画素を分けたい思惑があったからなのですが、色相、彩度、明度、とそれぞれの軸の単位が違うので結果に偏りが出ます。RGBはそれぞれが同じ単位なので意外としっかりした結果が返ってきます。この辺も面倒くさがらずに検証しておくべきでした。

 

基本的な流れは前回と一緒です。初めに画像を縮小して画素を6400個ぐらいに減らします。大体80×80ピクセルぐらいの密度ですね。画像は分かりやすくパーティクルで表現してみました。

 

そこからRGB空間内で6400個の画素をメディアンカットでキューブに分けていきます。だいたい64個に分けます。このキューブの中心座標をK均等法でクラスタリングするための初期座標に使います。

 

次にRGB空間はそのままにK均等法で6400個の画素をクラスタリングします。クラスタの数は64個で、初期座標にメディアンカットで作ったキューブの中心座標を使います。この初期位置が大事で、これをランダムにしたりするとどの画素にも選ばれないクラスタが生まれる可能性があります。なのでなるべく画素の分布に合わせて配置するためにメディアンカットを使っています。だいたい4~8回ぐらいクラスタリングを繰り返せば十分な精度が得られます。この段階で64個のクラスタを作りました。前回はここまでで終わっていましたが今回は続きます。

 

今回追加したクラスタリングのプロセスです。K均等法で作った64個のカラーからさらにクラスタリングして8色を選んでいます。クラスタリングした画素の平均値を求めると色が混ざってグレーに近づいてしまうため、画素の平均座標は求めつつも混ぜることはせずに平均座標から最短距離の画素の色を選択するようにしました。この処理は色空間内の距離で行われるので、使う色空間次第で結果が微妙に変わってきます。

RGB空間、HSV空間、HSL空間と試してみましたが、自分好みのはっきりした分かりやすい色を選ぶために明度軸の両端に近づくにつれて空間が狭くなるHSL空間を採用しました。8色だけ選ぶとなると、一番明るい色、一番暗い色、そして残りは様々な色相という組み合わせにしたかったのでHSL空間が最適な形でした。また中心からベクトルを加算して少し外側に押し出すことで、彩度や明度が強い画素が選ばれやすくなるように工夫しています。HSLは中心がグレーで球状に近い立体なのでこのような場合に都合がよかったのもあります。

 

最近WPFで作成した画像ビューワにもこのアルゴリズムを搭載してみました。表は二次元でも裏側では三次元的な処理が走っています。

 

開発環境:VIsual Studio Express 2008, XNA 3.1

シャドウマッピングのしくみ

思うところがあってシャドウマップの仕組みについて書いてみようと思いました。シャドウマップを初めて実装した頃はわかりやすい図説がなくて苦労した記憶があります。シャドウマップの解説によくある横から見た図はいまいち概念がわかりにくいので、自分なりにわかりやすく書いてみようと思います。

シャドウマップの肝であるプロジェクションマッピング(投影マッピング)のシェーダを書いてみました。左上はライトからの視点です。現実のプロジェクションマッピングと違ってCGではテクスチャーがモデルを突き抜けて行きます(裏側も描画される)。この性質が影を判定するために役に立ちます。

左上はライト視点で描画した深度マップです。10メートルぐらいの深度で描画しています。この深度マップをプロジェクションマッピングに使ってみます。この時点で影のようなものが落ちているように見えますよね。モデルの裏側や遮蔽されている部分にもモデルの表側の深度がそのまま投影されている状態になります(ここが大事)。

こんどはカメラから見たライトと各ピクセルの距離の値を描画してみます。深度マップと同じようにカメラに近いほど黒く、遠いほど白くなっています(深さも10メートルぐらいでグラデーションするようにして深度マップと合わせています)。

※カメラから見たピクセルのワールド座標を光源視点の空間へ変換して、光源からのZ座標(距離)を測るといった計算をしています。

どちらの画像もライトからの距離を記録しているという点では同じです。

上の2枚を比較して1枚目が2枚目より暗い部分が影になります。暗いということはライトに近い表側の深度が描かれている(遮蔽されている)部分だということが分かると思います。

このように実際のプロセスを順々に見せていけば理解しやすいかなと思いました。もうだいぶ昔ですがシャドウマップの仕組みを理解した時はちょっとした感動でした。考えた人はすごいですね。

開発環境:VIsual Studio Express 2008, XNA 3.1

猫の毛色 #2

思うところがあり猫の毛色プログラムに手を加えてみました。もともと一日で作ったプログラムなので、雑なコードを綺麗にしてグラフィックもスッキリした雰囲気にしてみました。子猫モデルも作り直しました。

プログラムに使っている毛色のパターンの分岐図も作ってみました。このプログラムでは4つの遺伝子を使い、毛色パターンも11種類にとどめています。

生まれる猫の確率もわかりやすく表示させてみました。白猫の組み合わせでも黒い猫が生まれるから不思議ですよね。

つづく・・・

開発環境:VIsual Studio Express 2008, XNA 3.1

Color Palette

久々に色彩のプログラムを改良しました。今回は画像のカラーパレットをつくってみました。

画像から代表的な色を選ぶというのが大まかな流れですが、減色パレットのアルゴリズムが方向性に近いと思いその方向で進めることにしました。減色アルゴリズムはメディアンカットとK平均法を実装してみました。デバッグ目的も兼ねてアルゴリズムも視覚化してみました。

 

Median-Cut(メディアンカット)

メディアンカットは色空間に立方体を配置し、それを細分化していくことでグループ分けをしていくような仕組みです。

メディアンカットの流れ

1.ピクセルデータすべてを含む立方体を配置する

2.一番長い辺を軸にして立方体を分割する

3.立方体に含まれるピクセルデータの平均色を求めて、立方体の代表色とする

4.2~3をパレットの数だけ繰り返す

HSV空間のHue方向にだけ重みを付けて分割しやすくするようにしましたが、メディアンカットだけだと結果が大雑把な色になりがちなのでK平均法を試すことにしました。

 

K-Means(K平均法)

各ピクセルをグループに分けて、グループに含まれるピクセルの平均色を代表色にする仕組みです。クラスタリングの代表的なアルゴリズムです。

K平均法の流れ

1.減色する色数分の代表色をランダムに色空間に配置する

2.各ピクセルデータとの距離を計算し、一番近いピクセルをその代表色のグループに含む

3.代表色をグループに含まれるピクセルデータの平均の位置(重心)に移動させる

4.2~3をある程度の回数繰り返す

距離を測るのでそれなりに重いです。K平均法は初めのランダム配置で結果までの計算量が変わるのでメディアンカットである程度まで分割した立方体の位置を初期位置として実行するようにしました。

 

最低限の色は取れているかと思うのですが、まだまだ精度が甘いですね。もう少しアルゴリズムを改良していく予定です。

 

開発環境:VIsual Studio Express 2008, XNA 3.1

Stock Chart #3

今回もチャートプログラムの進捗です。

 

コメント表示

comment_20161213

調べ物をしているとなぜここで値動きに変化があるのかと思うことがあるので記入できるようにしました。

 

comment_detail_20161213

このプログラムを作るきっかけになったのはPokemon Goで急騰急落した任天堂のチャートでした。あのチャートに様々なドラマを見て心揺さぶられました。笑

今年はPokemon Goから始まりSuper Mario RunやNintendo Switchの発表といろんなことがあった銘柄でしたね。

 

売買記録の表示

purchase_position_20161213

自分の売買の反省材料として買った場所と売った場所を表示できるようにしました。これってありそうでない機能なんじゃないかと思います。

 

詳細データの表示

detail_20161213

チャート上でマウスオーバーするとその日の詳細データを表示するようにしました。移動平均線からの乖離率は電卓使って計算するのは面倒ですからね。

 

チャートの上下反転

reverse_20161213

自分の判断が間違っていないか確認するために反転機能を入れてみました。描いている絵にデッサン狂いがないか鏡で反転させて確認するのと似ていますね。

 

出来高を背景に表示

volume_bg_20161213

出来高を価格帯で背景に表示しました。出来高が多い場所は値動きが鈍くなるものですが、それが視覚的にわかりやすくなったかと思います。

ビジュアル以外にも日経平均との相関係数を計算したり、傾向やパターンを統計的に調べられる関数を書きました。実際に使うことでだいぶ実用性の高いプログラムになってきました。

 

開発環境:VIsual Studio Express 2008, XNA 3.1

Stock Chart #2

チャートプログラムの進捗を動画にしてみました。

全体的に何もない状態からパラパラとアニメーションをさせていますが、本来なら一回で描画するモデルの頂点数を調節することでアニメーションしているように見せています。

 

ポートフォリオ

stockchart_20160919222306

保有している株の割合を視覚的に知りたいなと思うことがあったので円グラフを作ってみました。証券会社のポートフォリオページって意外と数字だけで殺風景なんですよね。まだまだ視覚的に楽しくできる余地はあると思います。

 

チャート

stockchart_20160917_volume_animation

チャートを時間軸でスライドさせられるようにしました。これで右に表示している価格別出来高の推移が視覚的にわかるようになりました。これをやりたくてこのプログラムを始めたようなところがあるのでまずまずの目標は達成できたかな。チャートを動的に観察出来るようにすることが最終的な目標で、複雑怪奇な株価の力学を少しでもわかりやすくしてみたい。

 

指標

stockchart_20160920174705

NYダウや為替も別の場所から情報を取ってきて表示させるようにしました。どこのCSVデータも基本的に始値、終値、安値、高値が書かれているので、一度仕組みを作ってしまえば読み込むのは簡単です。

 

開発環境:VIsual Studio Express 2008, XNA 3.1