jQueryのソースが読みきれなかったのキッカケに、javascriptを再学習。
学習したのは、基本的にこの一冊。
JavaScript Ninjaの極意
これが、稀に見る私にとっての良書と感じたので、
ここで学習したことをメモって、今一度理解を深めたいと思う次第。(o^^o)
向うの方は好きだよね。忍者とか。
笑えるのは、原書の表紙。
でも、内容は秀逸です。
pdfと組版と画像処理とc++とphpとjavascriptとhtml5とcss3とjQueryとjQueriUIとjQueryMobileとRadStudioとAndroidSDK/NDKとWordPressとWelcartを統合するエンジニア的視点。。廃止→as3とflashとflex 追加→柔道
2014年5月22日木曜日
2013年12月19日木曜日
大人の水彩画塗り絵のように加工する件。
前回のつづきとして、
水彩塗り絵っぽくする画像処理を考えます。
水彩塗り絵っぽくとは具体的に言うと、
・縁取りがしてある
・色が全体的に薄い
・色数が少ない
だいたい、こんなとこでしょう。
ただし、『水彩独特の筆のタッチ』とかは考慮しません。
それは、GUIアプリならば考慮できますが、自動ではなかな難しそうです。
機会があったらやってみますが。。。
ということで、縁取りは前回もやったので、
今回は、
(1)色を薄くする
(2)色数を少なくする
ということをしてみます。
具体的には、どうすればいいんでしょうね。。
ちなみに、何も参考にせずにこれを書いてるわけですが、
色は、とりあえずRGBで考えるとすると、
■■FF0000■■なんていうのは、真っ赤になっちゃいますから、
これを、■■FF8080■■あたりになるようなロジックです。
じゃぁどうするかというと、とりあえず、RGBそれぞれの成分に関して、、
0x20~0x50程度を足す。
1.2倍~2倍程度の倍率をかける。
0xffを超えるものは、0xffで頭打ちにする。
っとまぁ、この程度のことしてみた結果が以下です。
でも、まぁ、この程度でも結構いけます。
問題は、その
パラメータをヒストグラムあたりみて、自動的に設定する
ロジックですねーー。
パラメータをヒストグラムあたりみて、自動的に設定する
ロジックですねーー。
【元画像】
【変換画像】
【SRC。こんな程度。】
RR = ((RR + 0x30) * 4)/3; if(RR > 0xff) RR = 0xff; GG = ((GG + 0x30) * 4)/3; if(GG > 0xff) GG = 0xff; BB = ((BB + 0x30) * 4)/3; if(BB > 0xff) BB = 0xff; RR = ((int)(RR / 32))*32+31; GG = ((int)(GG / 32))*32+31; BB = ((int)(BB / 32))*32+31;
2013年12月15日日曜日
漫画カメラの画像処理のしくみを勝手に推測する件。
『どーゆーロジックなんだろ?』
と書きまして、その後、推測してみたわけですが、
今回は、この検証です。
●元画像がこれです。
●最終的にモノクロ画像なので、まずこれをグレイスケールにします。
グレイスケールはですね、R,G,Bに係数をかけて足し合わせて求めます。
Gray = R * 0.3 + G * 0.59 + B * 0.11;
こんな感じです。アバウトな計算でよいときは、整数計算にします。
即ち、GRAY=((R * 19660 + G * 38666 + B * 7209) >> 16) & 0xff; です。
まぁこれだと、絶対に出現しない階調が出現しちゃいますけどねー。
で、結果がこれです。
この画像のなかで、黒っぽい部分と、そのグレイだけど黒っぽい部分を抽出します。
それが、以下です。
この例では、0x38以下を黒にして表示しています。
この例では、0x70以下を黒にして表示しています
次に、斜線の画像を用意します。
まぁ画像と同じ大きさにすればよいです。
それがこれ。
そしてこの画像を、さっきのグレイっぽい画像でマスクをします。
そうすると、こうなります。
次は、輪郭の抽出です。
これは、ソーベルフィルタってやつを使います。
もちろん、これで抽出した値をどう使うかが問題となりますが、
簡単に言えば、『閾値を設定して、黒か白かにしてしまう』
ということです。
実際に抽出してみたのが、これです。
ということで、全部出揃いました。
ここで、
(1)黒抽出画像
(2)グレイ抽出マスク斜線画像
(3)輪郭抽出画像。
この3つを合成したのが、これです。
もちろん、【漫画カメラ】とまったく同じにはなりませんが、
そこらへんは、前処理とか、ヒストグラムを平均化するとか、閾値のとりかたとか、いくつかのパラメータの違いだと思われます。
もちろん、実際のプログラムでは、わざわざ画像を作ってから処理するわけではなく、
メモリやCPUコストを小さく抑えるべく、ひとつのLOOPの中で全て処理します。
もちろん、実際のプログラムでは、わざわざ画像を作ってから処理するわけではなく、
メモリやCPUコストを小さく抑えるべく、ひとつのLOOPの中で全て処理します。
まぁ、あたりまえですが\( ̄(エ) ̄ )/\( ̄(エ) ̄ )/
2013年12月9日月曜日
ベクトル図形のANDをとってみる件。(2)
つづきです。
では、順を追ってみましょう。
まず最初に、直線を登録(setLine)しているので、
こっから、頂点と交点、即ち、直線の始点/終点/直線同士の交点を求めます。
交点の求め方とかは、ここらへんを参考にどうぞ。
そして、今度はそのY座標だけをArrayに入れて、SORTしてみます。
そうすると、こういう結果になります。
図で言えば、こういうことです。
では、順を追ってみましょう。
まず最初に、直線を登録(setLine)しているので、
こっから、頂点と交点、即ち、直線の始点/終点/直線同士の交点を求めます。
交点の求め方とかは、ここらへんを参考にどうぞ。
そして、今度はそのY座標だけをArrayに入れて、SORTしてみます。
そうすると、こういう結果になります。
# 0 : 20.0000 - 10.0000 # 1 : 40.0000 - 10.0000 # 2 : 60.0000 - 20.0000 # 3 : 36.3636 - 20.9091 # 4 : 50.0000 - 30.0000 # 5 : 10.0000 - 40.0000 # 6 : 30.0000 - 40.0000 # 7 : 60.0000 - 40.0000 # 8 : 45.0000 - 40.0000 # 9 : 40.0000 - 50.0000
# 0 : 10.0000 # 1 : 20.0000 # 2 : 20.9091 # 3 : 30.0000 # 4 : 40.0000 # 5 : 50.0000
図で言えば、こういうことです。
ここで、Y座標は6コあることがわかります。
このY座標で水平な線を引き、
全ての登録した直線に対して、その直線で分割してしまいます。
ただし、水平な線は含みません。
ようするに、こういうことです。
データにすると、こういうふうになっています。
ここで、いくつかの値を一緒に登録しています。
(1)【tag】。分断する前の直線を一意に識別するための番号。
(2)【bup】。直線が、上を向いているか(終点のY座標>始点のY場表)どうか。
(3)【hnum】。その直線が、どの段(直線の中点がどのY座標の間にあるか)にあるか。
※全て、あとで使います。
# 0 tag:1 bup:1 bHz:0 hnum:1 x1:20.0 y1:10.0 x2:16.7 y2:20.0 x:18.3 y:15.0 # 1 tag:4 bup:0 bHz:0 hnum:1 x1:35.0 y1:20.0 x2:20.0 y2:10.0 x:27.5 y:15.0 # 2 tag:5 bup:1 bHz:0 hnum:1 x1:40.0 y1:10.0 x2:36.7 y2:20.0 x:38.3 y:15.0 # 3 tag:8 bup:0 bHz:0 hnum:1 x1:60.0 y1:20.0 x2:40.0 y2:10.0 x:50.0 y:15.0 # 4 tag:1 bup:1 bHz:0 hnum:2 x1:16.7 y1:20.0 x2:16.4 y2:20.9 x:16.5 y:20.5 # 5 tag:4 bup:0 bHz:0 hnum:2 x1:36.4 y1:20.9 x2:35.0 y2:20.0 x:35.7 y:20.5 # 6 tag:5 bup:1 bHz:0 hnum:2 x1:36.7 y1:20.0 x2:36.4 y2:20.9 x:36.5 y:20.5 # 7 tag:7 bup:0 bHz:0 hnum:2 x1:60.0 y1:20.9 x2:60.0 y2:20.0 x:60.0 y:20.5 # 8 tag:1 bup:1 bHz:0 hnum:3 x1:16.4 y1:20.9 x2:13.3 y2:30.0 x:14.8 y:25.5 # 9 tag:5 bup:1 bHz:0 hnum:3 x1:36.4 y1:20.9 x2:33.3 y2:30.0 x:34.8 y:25.5 # 10 tag:4 bup:0 bHz:0 hnum:3 x1:50.0 y1:30.0 x2:36.4 y2:20.9 x:43.2 y:25.5 # 11 tag:7 bup:0 bHz:0 hnum:3 x1:60.0 y1:30.0 x2:60.0 y2:20.9 x:60.0 y:25.5 # 12 tag:1 bup:1 bHz:0 hnum:4 x1:13.3 y1:30.0 x2:10.0 y2:40.0 x:11.7 y:35.0 # 13 tag:5 bup:1 bHz:0 hnum:4 x1:33.3 y1:30.0 x2:30.0 y2:40.0 x:31.7 y:35.0 # 14 tag:3 bup:0 bHz:0 hnum:4 x1:45.0 y1:40.0 x2:50.0 y2:30.0 x:47.5 y:35.0 # 15 tag:7 bup:0 bHz:0 hnum:4 x1:60.0 y1:40.0 x2:60.0 y2:30.0 x:60.0 y:35.0 # 16 tag:2 bup:1 bHz:0 hnum:5 x1:10.0 y1:40.0 x2:40.0 y2:50.0 x:25.0 y:45.0 # 17 tag:3 bup:0 bHz:0 hnum:5 x1:40.0 y1:50.0 x2:45.0 y2:40.0 x:42.5 y:45.0
これで、準備が整いました。
これから、ANDとかORの演算をすることになります。
次回につづきますが、きっと、ちょっとわかる人は、この図を見ればわかります。
つづく。
2013年12月8日日曜日
ベクトル図形のANDをとってみる件。
●図形を演算する話。
ベクタ画像を合成(演算)する件。のつづきです。
簡単に実装してみますです。
こぅいぅときゎ、まず、どう使いたいかをcodingしてみます。
とりあえず、こうしました。

実際には、7つのステップを踏んで、この座標を割り出しています。 それが、以下ですね。
ベクタ画像を合成(演算)する件。のつづきです。
簡単に実装してみますです。
こぅいぅときゎ、まず、どう使いたいかをcodingしてみます。
とりあえず、こうしました。
aPolies A; //1つめ A.setLine(20,10,10,40); A.setLine(10,40,40,50); A.setLine(40,50,50,30); A.setLine(50,30,20,10); //2つめ A.setLine(40,10,30,40); A.setLine(30,40,60,40); A.setLine(60,40,60,20); A.setLine(60,20,40,10); A.execute(); A.test();で、test()の結果が以下です。
# moveTo [5] 36.36 20.91 # lineTo [5] 30.00 40.00 # lineTo [0] 45.00 40.00 # lineTo [3] 50.00 30.00 # lineTo [4] 36.36 20.91それぞれのデータをグラフにすると、以下です。


実際には、7つのステップを踏んで、この座標を割り出しています。 それが、以下ですね。
# 0 : 20.0000 - 10.0000 # 1 : 40.0000 - 10.0000 # 2 : 60.0000 - 20.0000 # 3 : 36.3636 - 20.9091 # 4 : 50.0000 - 30.0000 # 5 : 10.0000 - 40.0000 # 6 : 30.0000 - 40.0000 # 7 : 60.0000 - 40.0000 # 8 : 45.0000 - 40.0000 # 9 : 40.0000 - 50.0000 ------------------------ # 0 : 10.0000 # 1 : 20.0000 # 2 : 20.9091 # 3 : 30.0000 # 4 : 40.0000 # 5 : 50.0000 ------------------------ # 0 tag:1 bup:1 bHorizon:0 x1:20.0 y1:10.0 x2:10.0 y2:40.0 x:15.0 y:25.0 # 1 tag:2 bup:1 bHorizon:0 x1:10.0 y1:40.0 x2:40.0 y2:50.0 x:25.0 y:45.0 # 2 tag:3 bup:0 bHorizon:0 x1:40.0 y1:50.0 x2:50.0 y2:30.0 x:45.0 y:40.0 # 3 tag:4 bup:0 bHorizon:0 x1:50.0 y1:30.0 x2:20.0 y2:10.0 x:35.0 y:20.0 # 4 tag:5 bup:1 bHorizon:0 x1:40.0 y1:10.0 x2:30.0 y2:40.0 x:35.0 y:25.0 # 5 tag:6 bup:1 bHorizon:1 x1:30.0 y1:40.0 x2:60.0 y2:40.0 x:45.0 y:40.0 # 6 tag:7 bup:0 bHorizon:0 x1:60.0 y1:40.0 x2:60.0 y2:20.0 x:60.0 y:30.0 # 7 tag:8 bup:0 bHorizon:0 x1:60.0 y1:20.0 x2:40.0 y2:10.0 x:50.0 y:15.0 ------------------------ # 0 tag:1 bup:1 bHz:0 hnum:1 x1:20.0 y1:10.0 x2:16.7 y2:20.0 x:18.3 y:15.0 # 1 tag:4 bup:0 bHz:0 hnum:1 x1:35.0 y1:20.0 x2:20.0 y2:10.0 x:27.5 y:15.0 # 2 tag:5 bup:1 bHz:0 hnum:1 x1:40.0 y1:10.0 x2:36.7 y2:20.0 x:38.3 y:15.0 # 3 tag:8 bup:0 bHz:0 hnum:1 x1:60.0 y1:20.0 x2:40.0 y2:10.0 x:50.0 y:15.0 # 4 tag:1 bup:1 bHz:0 hnum:2 x1:16.7 y1:20.0 x2:16.4 y2:20.9 x:16.5 y:20.5 # 5 tag:4 bup:0 bHz:0 hnum:2 x1:36.4 y1:20.9 x2:35.0 y2:20.0 x:35.7 y:20.5 # 6 tag:5 bup:1 bHz:0 hnum:2 x1:36.7 y1:20.0 x2:36.4 y2:20.9 x:36.5 y:20.5 # 7 tag:7 bup:0 bHz:0 hnum:2 x1:60.0 y1:20.9 x2:60.0 y2:20.0 x:60.0 y:20.5 # 8 tag:1 bup:1 bHz:0 hnum:3 x1:16.4 y1:20.9 x2:13.3 y2:30.0 x:14.8 y:25.5 # 9 tag:5 bup:1 bHz:0 hnum:3 x1:36.4 y1:20.9 x2:33.3 y2:30.0 x:34.8 y:25.5 # 10 tag:4 bup:0 bHz:0 hnum:3 x1:50.0 y1:30.0 x2:36.4 y2:20.9 x:43.2 y:25.5 # 11 tag:7 bup:0 bHz:0 hnum:3 x1:60.0 y1:30.0 x2:60.0 y2:20.9 x:60.0 y:25.5 # 12 tag:1 bup:1 bHz:0 hnum:4 x1:13.3 y1:30.0 x2:10.0 y2:40.0 x:11.7 y:35.0 # 13 tag:5 bup:1 bHz:0 hnum:4 x1:33.3 y1:30.0 x2:30.0 y2:40.0 x:31.7 y:35.0 # 14 tag:3 bup:0 bHz:0 hnum:4 x1:45.0 y1:40.0 x2:50.0 y2:30.0 x:47.5 y:35.0 # 15 tag:7 bup:0 bHz:0 hnum:4 x1:60.0 y1:40.0 x2:60.0 y2:30.0 x:60.0 y:35.0 # 16 tag:2 bup:1 bHz:0 hnum:5 x1:10.0 y1:40.0 x2:40.0 y2:50.0 x:25.0 y:45.0 # 17 tag:3 bup:0 bHz:0 hnum:5 x1:40.0 y1:50.0 x2:45.0 y2:40.0 x:42.5 y:45.0 ------------------------ # 0 tag:5 bup:1 bHz:0 hnum:3 x1:36.4 y1:20.9 x2:33.3 y2:30.0 check:1 # 1 tag:4 bup:0 bHz:0 hnum:3 x1:50.0 y1:30.0 x2:36.4 y2:20.9 check:1 # 2 tag:0 bup:0 bHz:1 hnum:3 x1:33.3 y1:30.0 x2:50.0 y2:30.0 check:0 # 3 tag:5 bup:1 bHz:0 hnum:4 x1:33.3 y1:30.0 x2:30.0 y2:40.0 check:1 # 4 tag:3 bup:0 bHz:0 hnum:4 x1:45.0 y1:40.0 x2:50.0 y2:30.0 check:1 # 5 tag:0 bup:0 bHz:1 hnum:4 x1:30.0 y1:40.0 x2:45.0 y2:40.0 check:1 # 6 tag:0 bup:0 bHz:1 hnum:3 x1:50.0 y1:30.0 x2:33.3 y2:30.0 check:0 ------------------------ # 0 tag:5 bup:1 bHz:0 hnum:3 x1:36.4 y1:20.9 x2:33.3 y2:30.0 check:1 # 1 tag:5 bup:1 bHz:0 hnum:4 x1:33.3 y1:30.0 x2:30.0 y2:40.0 check:1 # 2 tag:0 bup:0 bHz:1 hnum:4 x1:30.0 y1:40.0 x2:45.0 y2:40.0 check:1 # 3 tag:3 bup:0 bHz:0 hnum:4 x1:45.0 y1:40.0 x2:50.0 y2:30.0 check:1 # 4 tag:4 bup:0 bHz:0 hnum:3 x1:50.0 y1:30.0 x2:36.4 y2:20.9 check:1 ------------------------ # moveTo [5] 36.36 20.91 # lineTo [5] 30.00 40.00 # lineTo [0] 45.00 40.00 # lineTo [3] 50.00 30.00 # lineTo [4] 36.36 20.91つづく。
2013年11月30日土曜日
2013年9月27日金曜日
ベクタ画像を合成(演算)する件。
なぜかはよくわからないけど、図形を演算するロジック、
そう、イラストレータで言えば、『パスファインダ』、
これ↓である。
この機能を作りたかったのだが、どうにもこうにもそれらしい情報が、
ネットを見てもほとんどないのである。
で、かろうじて合ったのはここ。
→http://www7b.biglobe.ne.jp/~garaku/Boolean.html
途中まではわかりやすいのだが、途中以降はよくわからないので、自分流にやってみた。
でも、そもそもなんでこんな基本的なことが出てないんだろうと言う疑問はさておき、
とりあえず、題材を元にロジックをかいてみよう。
【1】題材はこれ。
ピンクの図形と、薄緑の図形。
【2】ベクトル方向
もちろん、緑図形が抜けているのはベクトルの廻りが逆だから。
今回は、右回りを基本とする。
基本というか、最外郭が右回りという前提である。
【3】Y座標の算定
全てのベクトルを見たとき、次の点のY座標を抽出する。
図では横線として表示。
●ベクトルの始点
●ベクトルの終点
●ベクトル同士の交点
-----------------
そして、各ベクトルを横線で分割する。
【4】ベクトルに値を設定
上向きを+1、下向きを-1とする。
--------------------
次に、横線の間の各段(横線の数-1)ごとに、
左側から、値を集計し、記入す。
最後は0になるはず。
0にならなかったら、図形が閉じていないのだ。
【5】今回は、図形をORしてみる。
【6】図形を分割したんだよ。
上記の【5】の作業で作成された、三角形と四角形は、←の図のようになる。
ここからいらないと思われる水平のベクトルを削除していくのだ。
【7】ちょっと説明が難しいので、簡単な例を。
←の図は四角形が3つだが、上の四角形の底辺(=下の四角形の上辺)の位置の水平のベクトルを考えてみる。
【8】左回り図形になってしまったが、、、
頂点を左から番号をふると、6コある。
【9】頂点が6コということは、間は5コということである。
これの、偶数番目の間にあるベクトルを削除するのである。
上の四角形の底辺のベクトルは、4と3と2なので、2を削除する。
左下の四角形の上面のベクトルは、1と2なので、2を削除する。
右下の四角形の上面のベクトルは、4と5なので、4を削除する。
【10】ちなみに、頂点がダブったときも、頂点は2コあるということにする。
よって、上部の三角形の底辺は、
1-2-3-4-5-6-7-8なので、2-3,4-5,6-7のベクトルは削除される。
また、1と2、3と4、5と6、7と8は同じ点なので、最終的にはこの三角形の底辺の部分の水平のベクトルは全て削除される。
あとは、冗長点の削除をすればよいですね。
つづく。
そう、イラストレータで言えば、『パスファインダ』、
これ↓である。
この機能を作りたかったのだが、どうにもこうにもそれらしい情報が、
ネットを見てもほとんどないのである。
で、かろうじて合ったのはここ。
→http://www7b.biglobe.ne.jp/~garaku/Boolean.html
途中まではわかりやすいのだが、途中以降はよくわからないので、自分流にやってみた。
でも、そもそもなんでこんな基本的なことが出てないんだろうと言う疑問はさておき、
とりあえず、題材を元にロジックをかいてみよう。
【1】題材はこれ。
ピンクの図形と、薄緑の図形。
【2】ベクトル方向
もちろん、緑図形が抜けているのはベクトルの廻りが逆だから。
今回は、右回りを基本とする。
基本というか、最外郭が右回りという前提である。
【3】Y座標の算定
全てのベクトルを見たとき、次の点のY座標を抽出する。
図では横線として表示。
●ベクトルの始点
●ベクトルの終点
●ベクトル同士の交点
-----------------
そして、各ベクトルを横線で分割する。
【4】ベクトルに値を設定
上向きを+1、下向きを-1とする。
--------------------
次に、横線の間の各段(横線の数-1)ごとに、
左側から、値を集計し、記入す。
最後は0になるはず。
0にならなかったら、図形が閉じていないのだ。
【5】今回は、図形をORしてみる。
次に、横線の間の各段(横線の数-1)ごとに、
左側からベクトルをみて、+1(↑)と0(↓)を抽出し、それらのベクトルが離れている場合は右回りになるように、三角形または四角形を作成する。
【6】図形を分割したんだよ。
上記の【5】の作業で作成された、三角形と四角形は、←の図のようになる。
ここからいらないと思われる水平のベクトルを削除していくのだ。
【7】ちょっと説明が難しいので、簡単な例を。
←の図は四角形が3つだが、上の四角形の底辺(=下の四角形の上辺)の位置の水平のベクトルを考えてみる。
【8】左回り図形になってしまったが、、、
頂点を左から番号をふると、6コある。
【9】頂点が6コということは、間は5コということである。
これの、偶数番目の間にあるベクトルを削除するのである。
上の四角形の底辺のベクトルは、4と3と2なので、2を削除する。
左下の四角形の上面のベクトルは、1と2なので、2を削除する。
右下の四角形の上面のベクトルは、4と5なので、4を削除する。
【10】ちなみに、頂点がダブったときも、頂点は2コあるということにする。
【11】残ったベクトルをつなぎ合わせると、左図のような図形ができあがる。
【12】【6】に戻って、同様の処理を行う。
【13】水平のベクトルはこのようになる。
【14】右上部分を拡大すると、こんな感じ。よって、上部の三角形の底辺は、
1-2-3-4-5-6-7-8なので、2-3,4-5,6-7のベクトルは削除される。
また、1と2、3と4、5と6、7と8は同じ点なので、最終的にはこの三角形の底辺の部分の水平のベクトルは全て削除される。
【15】残ったベクトルをつなぎ合わせると、このようになる。
※点線部はないよ。
※点線部はないよ。
あとは、冗長点の削除をすればよいですね。
つづく。
登録:
投稿 (Atom)