Shaderプログラミング勉強 1日目

Shaderを身につけたかったので色々勉強することにしました。 元々少しかじってましたが、実践につかったことなかったので全く身についてませんでした。 ブログにアウトプットすることによってもう少しに身につけていきたい。 記載している内容はThe book of Shadersに記載されていることと変わりないので、そちらを参照していただいたほうがいいです。

patriciogonzalezvivo.com

Shaderとは

画像処理において全てのピクセルに対して並列に計算を実行してくれるもの。GLSLという言語で記述する。高速にきれいな絵が描ける。 Fragment ShaderとVertex Shaderの2種類のファイルを記述する。 Fragment Shaderは色情報の記述。 Vertex Shaderは頂点情報の記述。

Fragment Shader初歩

まずはサンプルコード。

#ifdef GL_ES
precision mediump float;
#endif

void main() {
    gl_FragColor = vec4(1.0,0.0,1.0,1.0);
}

main関数内に色情報に関する記載をする。gl_FragColorは色情報を保持する予約語(*)。このmain関数内の意味はR, B, A情報を1にした色情報にするという意味。 * gl_FragColorは1.31から非推奨になったとのこと。開発者が自由に変数名を決めれるっぽい。

また、GLSLでは浮動小数点の精度が結構重要になってくる。このため、浮動小数点型の精度を指定することができる。精度が高ければ品質が上がるけど速度が下がる。精度が低ければ品質は下がるけど速度が上がる。

precision lowp    float; // 低精度
precision mediump float; // 中精度
precision highp   float; // 高精度

一番最初の例ではopenGLESでは中精度のfloat値を使用するということを宣言している。

uniform変数

Shaderでは並列処理をするため、CPUから各ピクセルごとに独立した変数を渡すことはできないけど、一様に変数を渡すことはできる。それがuniform変数。 型としてはfloat、vec2、vec3、vec4、mat2、mat3、mat4、sampler2D、samplerCubeなどがあるとのこと。 浮動小数点精度の宣言の後に記載すれば良い。

#ifdef GL_ES
precision mediump float;
#endif

uniform vec2 u_resolution; // Canvas size (width,height)
uniform vec2 u_mouse;      // mouse position in screen pixels
uniform float u_time;     // Time in seconds since load

例えばu_timeに経過時間を送ってあげるとこんな感じで時間経過ごとに色変化を行うことができる。

#ifdef GL_ES
precision mediump float;
#endif

uniform float u_time;

void main() {
    float freq = 6.0;
    
    gl_FragColor = vec4(abs(sin(u_time*freq) - 0.3),abs(sin(u_time*freq) - 0.7),abs(sin(u_time*freq)),1.0);
}

gl_FragCoord

gl_FragCoordはピクセルの位置を保持してる。これはスレッドごとに異なる値を持つため、varying変数と呼ぶ。ここでいう"スレッド"とは1ピクセルごとみたいな理解を僕はしてる。

openFrameworksで使用する場合

こんな感じ

void ofApp::setup(){
    ofShader shader;
    shader.load("", "フラグメントシェーダを記述したファイル");
}

void ofApp::draw(){

    shader.begin();
    shader.setUniform1f("u_time", ofGetElaplsedTimef()); // ここでuniform変数を渡してる
    ofRect(0, 0, ofGetWidth(), ofGetHeight()); // この領域にShaderで記述した部分が記載される
    shader.end();

}

参考URL

patriciogonzalezvivo.com

yoppa.org

データサイエンティスト養成読本 機械学習入門編を読んだ 他

データサイエンティスト養成読本 機械学習入門編

データサイエンティスト養成読本 機械学習入門編 (Software Design plus)

データサイエンティスト養成読本 機械学習入門編 (Software Design plus)

機械学習に関する基礎知識が書いてあるので、最近話題の人工知能についてもう少し突っ込んで知識を得てみたいなという方にはピッタリの内容ではないでしょうか。 メディアなどで"人工知能"ともてはやされているものの実情は不透明なところが多いと思うので、実際はどんなことやってるんだろうと調べてみたい方向けかなという感じでした。

結構わかりやすく書かれているのでおすすめです。

Pythonでデータ解析をやってみたいという方に最適な章も構成されてて、Numpy, Scikit-Learn, Scikit-Imageとかその辺の触り方とかも載ってます。 あとDeep Learningに関する記事も数ページしかないものの、ちょっと難しい記事を読むのはしんどいなという方向けに書かれてる気がしてわかりやすかったです。特にCNNなんかはわかりやすかった気がします。

統計的機械学習もう少し勉強したい

統計的機械学習はなかなか難しいのでもっとアウトプットして自分のものにしていきたいところ。

Relmを使ってみた

Realmとは

iOSAndroidで使える組み込みのDB。移植や操作が簡単なので最近人気っぽいです。 実際使いやすい。

Realm is a mobile database: a replacement for SQLite & Core Data

RelmObject

RLMObjectクラスがRelmで扱うデータオブジェクトのクラス。 ここにデータ突っ込む。下記コードの他主キーとかを指定したりする。その辺は後でまとめる。

@interface myObject: RLMObject

@property (nonatomic) NSString *name;
@property (nonatomic) NSData   *date;
@end
RLM_ARRAY_TYPE(myObject)

DBへ保存

こうするとRLMオブジェクトをDBに保存できる。 本当はもっと綺麗にまとめたいけど、それは後ほど。。

myObject *o = [myObject new];
o.name = @"Katoh";
o.date = [NSDate now];

RLMRealm* realm = RLMRealm.defaultRealm;
[realm transactionWithBlock:^
{
    [realm addOrUpdateObjectsFromArray:o];
}];

2値画像をベクター画像に変換

2値画像をベクター画像に変換する必要があったので色々調査。

Illustratorで簡単にできが、プログラムの中で処理をしたかったので一旦違う方法で攻めます。

Potrace

Peter Selinger: Potrace

Potraceを使えば任意のフォーマットのベクター画像に変換できます。書き出しはpdf, svg, postscript, eps, dxfなど色々。 ただし入力はpnm (pbm, pgm, ppm), bmpのみ。jpegとかpngを変換しようとしてる場合はこのフォーマットにしておく必要があります。

公式サイトにバイナリファイルが置かれてるのでこれをダウンロードすればそのままコマンドラインから使えます。

SVGファイルを出力するコマンド

potrace -s [filename]

実行例 f:id:l94q:20150908010249j:plain

ビットマップ画像

f:id:l94q:20150908010424p:plain

SVG画像(SVGの表示できなかったので、ここで表示してるのはPNG

Autotrace

AutoTrace

今回ベクトル化したかったのは文字のストロークだったので、アウトラインをベクトル化するPotraceは使えなかったので他のを調査。 Autotraceだと中心線をベクトル化してくれるので、文字とかサインをベクトル化したい場合に便利。

公式サイトからはダウンロードできなくなってるのでHomebrewでインストール。

brew install autotrace

使い方

autotrace -centerline -color-count 2 -output-file output.svg -output-format SVG input.bmp

-centerlineのオプションつけることで中心線をベクトル化してくれる。

実行例

f:id:l94q:20150908011611j:plain

ラリーページのサイン(ビットマップ画像)

f:id:l94q:20150908011638p:plain

SVG画像

所感

本当は文字のベクトル化を自分で細線化→ベクトル化のコードを加工としていたのだけど、アルゴリズムが想像以上に複雑で躓いてました。実際こういうツールがあるのだから、全部自分でやるというのは無駄なことと考えたほうがいいと感じました。時間も限られてるしね。 既存にあるツールで使えるものはどんどん使って、空いた時間で自分の伸ばすべきスキルを伸ばすのがいいと感じました。

Pythonで画像処理いろいろ

今日は画像処理仕事があったので、色々と復習。 基本openCV使ってます。

2値化

ret, binarizedImage = cv.threshold(input, 180, 255, cv.THRESH_BINARY)

binarizedImageが2値化された画像。

細線化

こちら参照

github.com

ラベリング

scipyを使う

from scipy import ndimage

stel = np.ones((3, 3))
label_img, n_labels = ndimage.label(input, stel)

4近傍を隣接画素としたい場合は引数のstelを外す。上記は8近傍を隣接画素としてる。

iPythonでのスクリプトファイルのリロード

ipythonでimportしたスクリプトファイルを修正した後再度importしても、pycファイルから読み込まれて更新が反映されないというのに困ってた(というか毎回iPython再起動してた)んだけど、こうやればいいみたいなこと知った。

import scriptFile

...

reload(scriptFile)

もっと早く調べてればよかった。。

2015/9/5 pythonメモ

iPythonのステップ実行

スクリプト言語で個人的に結構ストレスだったのはIDEによるデバッガが乏しいところでした。 (自分が知らなかっただけですが。。基本printfデバッグしてました。。)

デバッグ方法は以下のとおり。

  1. 以下のコードを宣言しておく。

(ここから転載。)

qiita.com

import sys

def set_trace():
    from IPython.core.debugger import Pdb
    Pdb(color_scheme='Linux').set_trace(sys._getframe().f_back)

def debug(f, *args, **kwargs):
    from IPython.core.debugger import Pdb
    pdb = Pdb(color_scheme='Linux')
    return pdb.runcall(f, *args, **kwargs)
  1. ブレークポイントとしたいところでset_trace()関数を呼び出す。

  2. 以下のコマンドでステップ実行が可能。もちろん変数の中身を見たりなども可能。



ctrl+qでブレークポイントから抜け出せる。

numpy arrayの比較

arrayの中身が同一か比較するにはこうする。

if np.equal(array1, array2).all():
    print "equal"
else:
    print "not equal"