エイバースの中の人

アプリとWEBサービスを作っているABARSのBLOGです。

PythonでGoogleCloudStorageにファイルをアップロードする

PythonでGoogleCloudStorageにファイルをアップロードします。

まず、IAMでサービスアカウントを作成し、サービスアカウントの鍵情報をjsonでダウンロードします。その後、CloudStorageのBucketの権限にサービスアカウントを追加します。

必要なライブラリをインストールします。

pip3 install google-cloud-storage
python3 upload.py src.zip dest.zip

ダウンロードしたJSONを使用してアップロードします。

import os
import sys
from google.cloud import storage

os.environ["GOOGLE_APPLICATION_CREDENTIALS"]='xxx.json'
client = storage.Client()
bucket = client.get_bucket('backup')

print("from : "+sys.argv[1])
print("to   : "+sys.argv[2])
blob = bucket.blob(sys.argv[2])
blob.upload_from_filename(filename=sys.argv[1])

SakuraVPSからGCE f1microへの乗り換え

ABARSのWEBサイトを、SakuraVPSからGCEのf1microに乗り換えました。当時は2010年にSakuraの専用サーバからSakuraVPS 512MBに乗り換えて、かなりコストダウンになったのですが、GCEのf1microではついに無料になりました。

スペック的には、当時のVCPU 2コア+SSD 20GB+メモリ512MBから、VCPU 1コア+HDD 30GB+メモリ512MBへの移行になります。WordPressやMySQLを使わないレガシーなサービスしか動かしていないため、メトセラのゲームサーバを動かしても、GCEのf1microでもCPU使用率は余裕がありそうです。

Sakura VPS

スクリーンショット 2018-12-30 10.07.52


GCE f1micro

スクリーンショット 2018-12-30 10.06.08


静的なWEBサイトを動かす分には、かなりお得です。

セットアップは下記サイトを参考にしました。
GCE の無料枠のサーバを立るときに、初見でハマりそうなところ

なお、GCEはFTP接続できないので、SFTP接続が必要になります。
GoogleComputeEngineのVMインスタンスにFTP接続しようとして奮闘した話 結局SFTP

今回、CentOS7にして、Let's Encryptを使用してhttps対応もしました。
CentOS 7 + Apache 2.4 に Let’s Encrypt の証明書を導入する手順

性別推定モデルにおけるランダムイレージング

SqueezeNetにおける性別推定モデルにおいて、学習時にランダムイレージングを使用して効果を計測しました。ランダムイレージングは、ランダムに一部の領域を塗りつぶすことで、汎化性能を上げる手法です。

使用前
agegender_gender_squeezenet_


使用後
agegender_gender_squeezenet_augumented


ランダムイレージングを使用すると、accuracy for trainingが下がり、accuracy for validationが上がります。ただ、使用前、使用後でaccuracy for validationに大差はないため、このモデルではあまり効果がないようです。

YoloKerasFaceDetection

性別推定モデルのSqueezeNetとMobileNetの比較

IMDB wikiデータセットを使用して性別推定モデルを構築した場合の、lossとaccuracyをSqueezeNetとMobileNetで計測しました。

SqueezeNet

agegender_gender_squeezenet_


MobileNet

agegender_gender_mobilenet_


MobileNetの方がTrainingのaccuracyは高くなるのですが、Validationのaccuracyが伸びていかないため、SqueezeNetでも十分そうです。

SqueezeNetは10.2MB、MobileNetは34.4MBの重みになります。

YoloKerasFaceDetection

Darknetにおける転移学習の効果

Darknetを使用した学習では、引数に学習済み係数を与えて転移学習を行うことができます。Darknetで使用するYOLOv2の前段はVGGライクな特徴検出器となっており、Imagenetなどの大規模データで学習したフィルタ係数を流用することで、効率的に学習を行うことができると言われています。

今回はFDDBを使用した顔検出において、転移学習の効果を確認します。モデルはYOLOv2-tinyを使用します。FDDBのデータセットは2845枚で、3/4をトレーニング、1/4をバリデーションとして用います。

まずは、転移学習をしない場合の学習の推移です。

yolov2-tiny-train-one-class_32600


次に、転移学習をする場合の学習の推移です。

yolov2-tiny-train_431800


転移学習をしない場合は、最初のlossが大きいですが、転移学習をする場合は最初のlossが低い地点からスタートすることがわかります。また、lossの低下速度が速くなっています。

ただ、転移学習をしない場合でも、Geforce1050tiで一晩で学習が終わっており、また、最終的にできあがるモデルの精度もあまり違わないため、Darknetにおいては転移学習をしなくてもよさそうという結論です。

ソースコード:YoloKerasFaceDetection

YAD2KでYolov2の重みをKerasに変換する

YAD2Kを使用することで、Darknetで学習したYolov2の重みをKerasに変換することができます。

変換を行うには以下のコマンドを使用します。
python3 yad2k.py yolov2-tiny.cfg yolov2-tiny.weights yolov2_tiny.h5

注意点として、64bitでビルドしたDarknetを使用している場合、yad2k.pyのweights_file.read(16)をweights_file.read(20)に書き換える必要があります。
    weights_header = np.ndarray(
        shape=(4, ), dtype='int32', buffer=weights_file.read(20))
(参考:Tiny Yolo conversion fails to detect any objects

以下のコマンドでテストを行います。
python3 test_yolo.py yolov2_tiny.h5

MMdnnを使用してモデルをcaffeからkerasに変換する

MMdnnはマイクロソフトが開発しているモデルコンバータです。モデルデータをIRに変換することで、モデルの相互変換を可能にしています。

MMdnn

mmdnnをインストールし、caffemodelとprototxtからhdf5に変換するには以下のようにします。inputShapeを指定しない場合、None例外が発生します。

pip2 install mmdnn
mmconvert --srcFramework caffe --inputWeight face.caffemodel --inputNetwork face.prototxt --dstFramework keras --outputModel face.hdf5 --inputShape 1,3,448,448

GoogleAppEngineのhttps対応

GoogleAppEngineでhttps対応を行うには、カスタムドメインの設定からマネージドセキュリティを有効にします。

ssl

アプリ側は、Pythonからhttpsかhttpかを判定し、適切なURLにリダイレクトします。

def get_host(self):
	if self.request.scheme.lower() != 'https':
		return "http://"+self.request.host
	return "https://"+self.request.host

CoreMLでfloat配列から推論する

Caffeと同様に、CoreMLでもMLFeatureProviderという形式でデータを与え、predictionFromFeaturesを呼び出すことで、float配列から推論を行うことができます。

任意のfloat配列からMLFeatureProviderを取得するには、MLMultiArrayにfloat配列を書き込み、MLMultiArrayを持つNSMutableDictionaryを作成し、NSMutableDictionaryからMLDictionaryFeatureProviderを生成することになります。このとき、ディクショナリのキーはmlmodelの入力層の名前になります。

NSArray *shape = @[@1, [NSNumber numberWithInt:src_w], [NSNumber numberWithInt:src_z], [NSNumber numberWithInt:src_y], [NSNumber numberWithInt:src_x]];
MLMultiArray* data = [[MLMultiArray alloc] initWithShape:shape dataType:MLMultiArrayDataTypeFloat32 error:&error];
int shape_size=1*src_w*src_z*src_y*src_x*sizeof(float);
memcpy( data.dataPointer, src, shape_size );
NSMutableDictionary *inputDict = [[NSMutableDictionary alloc] init];
inputDict[key] = data;
MLDictionaryFeatureProvider *inFeatures = [[MLDictionaryFeatureProvider alloc] initWithDictionary:inputDict error:&error];

mlmodelに対してpredictionFromFeaturesを呼び出すことで推論します。

id outFeatures = [model predictionFromFeatures:static_cast(inFeatures) error:&error];

処理結果はMLFeatureProviderで出力されます。ディクショナリのキーは出力層の名前になります。

NSSet *keys = [outFeatures featureNames];
MLFeatureValue *value = [outFeatures featureValueForName:key];
MLMultiArray* res=value.multiArrayValue;
double* fsrc = (double*)res.dataPointer;
float* fdst = (float*)dest;
for( int i=0; i<res.count; i++ ){
	fdst[i] = (float)fsrc[i];
}


predictionFromFeaturesとMLFeatureProviderの使い方はcoremltools/coremlpython/のソースコードを参照してください。

CoreMLの出力はdoubleですが、内部的にはMetalPerformanceShaderでhalf floatで実行されるそうです。How can I use half floats with CoreML neural nets?

CaffeModelをmlmodelに変換する

CaffeModelからCoreMLで使えるmlmodelに変換するにはcoremltoolsを使います。

pip install coremltools


PIPが古い場合はpipをupgradeします。

pip install --upgrade pip


以下のスクリプトをpython3で実行することでcaffemodelをmlmodelに変換します。

import coremltools
coremlmodel = coremltools.converters.caffe.convert(
        ("lenet.caffemodel", "lenet.prototxt"))
coremlmodel.save("lenet.mlmodel")


python3 coreml.py 

================= Starting Conversion from Caffe to CoreML ======================
Layer 0: Type: 'Input', Name: 'data'. Output(s): 'data'.
Ignoring batch size and retaining only the trailing 3 dimensions for conversion. 
Layer 1: Type: 'Convolution', Name: 'conv1'. Input(s): 'data'. Output(s): 'conv1'.
Layer 2: Type: 'Pooling', Name: 'pool1'. Input(s): 'conv1'. Output(s): 'pool1'.
Layer 3: Type: 'Convolution', Name: 'conv2'. Input(s): 'pool1'. Output(s): 'conv2'.
Layer 4: Type: 'Pooling', Name: 'pool2'. Input(s): 'conv2'. Output(s): 'pool2'.
Layer 5: Type: 'InnerProduct', Name: 'ip1'. Input(s): 'pool2'. Output(s): 'ip1'.
Layer 6: Type: 'ReLU', Name: 'relu1'. Input(s): 'ip1'. Output(s): 'ip1'.
Layer 7: Type: 'InnerProduct', Name: 'ip2'. Input(s): 'ip1'. Output(s): 'ip2'.
Layer 8: Type: 'Softmax', Name: 'prob'. Input(s): 'ip2'. Output(s): 'prob'.

================= Summary of the conversion: ===================================
Detected input(s) and shape(s) (ignoring batch size):
'data' : 1, 28, 28

Network Input name(s): 'data'.
Network Output name(s): 'prob'.

Xcodeに取り込むと以下のように見えます。

xcode_lenet


アプリに組み込む場合、Xcodeでは拡張子がmlmodelと表示されますが、アプリからはmlmodelcとしてアクセスする必要があります。mlmodelcにはXcodeが自動的に変換します。mlmodelcには手動で変換することもできます。

/Applications/Xcode.app/Contents/Developer/usr/bin/coremlc compile in.mlmodel out.mlmodelc

Compile .mlmodel to .mlmodelc for Xamarin.iOS?

Mac環境でlibtiffをビルドする

libtiffのダウンロードページからtiff-4.0.9.tar.gzをダウンロードします。
https://download.osgeo.org/libtiff/

./configureしたあとでmakeします。

libtiffフォルダに.libsフォルダが生成され、libtiff.5.dylibが生成されます。

デフォルトではlibtiff.5.dylibを/usr/local/libにインストールしようとするため、install_name_toolでrpath経由のパスに変更します。

install_name_tool -id @rpath/libtiff.dylib libtiff.5.dylib 
otool -L libtiff.dylib
libtiff.dylib:
@rpath/libtiff.dylib (compatibility version 9.0.0, current version 9.0.0)
/usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.8)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.60.2)

VAEによる正常品のみからの不良品検出

製造工程の不良品を検出する場合、製造工程の不良率は低いため、不良画像をなかなか集めることができません。そのため、正常品のみから不良個所を判定する手法が求められており、AutoEncoderを使用する方法が提案されています。

AutoEncoderでは、入力画像の特徴を表すベクトルを学習します。Encoderでは入力画像を低次元の潜在変数zに写像します。Decoderでは潜在変数zから元解像度まで復元します。学習では、X->Encoder->z->Decoder->xと計算し、Xとxの誤差を最小化します。

AutoEncoderは正常品から学習しているため、不良品の特徴は捉えることができません。そのため、AutoEncoderの出力と、不良品の画像の差分を取ることで、不良個所を判別することができます。

AutoEncoderのzを直接学習せず、正規分布のパラメータを学習するようにしたのがVAEです。VAEを使用してMNISTで不良品検出をするには、以下の記事が参考になります。

Variational Autoencoderを使った画像の異常検知 前編

Colaboratoryに上記サイトのコードをコピペして実行してみます。実行結果が以下の画像です。画像上(old)がVAE、画像下(new)がVAEの損失関数をMVAEのみにしたバージョンです。1の画像を正常画像、9の画像を異常画像として、濃い青の部分が異常個所になります。このように、正常画像のみから異常画像を検出できることがわかります。

2dim


潜在変数zを2次元から4次元に変更して実行してみます。こちらの方が精度が高いように思われます。

4dim


8次元版。次数を上げすぎるとすべての特徴を表現できてしまい、異常検知が困難になります。

8dim


学習自体は正常画像のみで実行できますが、潜在変数をどれくらいの次元数に設定するかの判断のために、いくつかは不良画像が必要かと思われます。

SurfaceBook2でdGPUが認識しなくなる

SurfaceBook2はしばらく使っているとdGPUが認識しなくなります。具体的に、再起動やスリープからの復帰をすると認識しなくなり、ディスプレイを取り外して再びセットすると使えるようになります。この状態になると、毎回、ディスプレイを取り外す必要があり、とても不便です。

この問題は、PCの起動状態から、電源ボタン長押しで強制シャットダウンしたあと、20秒程度長押しでPCの電源ONすることで解消します。ただし、一度解消しても、一ヶ月程度でまた同じ問題が起きるため、再び、同じ操作をする必要があります。

Surface book2でnvidia gpuを認識しない。

MacのUnity Pluginからサードパーティのdylibを読み込む

MacのUnity Pluginはbundle形式になっています。bundleをビルドする際、bundleからサードパーティのdylibを読み込みたい場合があります。

通常の手順でdylibをリンクし、bundleをビルドした場合、otool -Lでbundleの依存関係を表示すると以下のようになります。

otool -L mybundle
mybundle:
/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1454.90.0)
/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 400.9.0)
@rpath/libthirdparty.dylib (compatibility version 0.0.0, current version 0.0.0)

このとき、@rpathからlibthirdparty.dylibが読み込まれるように設定されていますが、@rpathは$PATHなため、Unityから読み込めません。

そこで、install_name_toolで@rpathを@loader_pathに書き換えます。

install_name_tool -change @rpath/libthirdparty.dylib @loader_path/../Frameworks/libthirdparty.dylib mybundle

その上で、以下のようにContents/Frameworlsにdylibを配置すれば、dylibへのパスが通ります。

mybundle.bundle/Contents/MacOS/mybundle
mybundle.bundle/Contents/Frameworks/libthirdparty.dylib 

Unity+WindowsMRでメニューキーの入力を取得する

UnityでWindowsMRの開発を行う場合、通常はUWPでの開発が必要ですが、SteamVRをインストールしていると通常のStandaloneモードで開発することができます。その際、ProjectSettingsのXR SettingのVirtualRealitySupportのチェックボックスを入れるだけで、Main Cameraが自動的にステレオカメラになり、位置と方向が反映されます。

virtual_reality


コントローラの入力を取得する場合、スティックはInputManager、ボタンはInput.GetKeyを使用します。スティックの入力を取得するには、InputManagerで名前を登録した後、Input.GetAxis ("Horizontal2")のようにします。トリガーの入力を取得するには、Input.GetKey(KeyCode.JoystickButton14) のようにします。

input_manager


ここまで、開発は順調に進んでいたかのように見えたのですが、WindowsMRでメニューキーの入力を取得しようとしてトラブルが起きました。以下のサイトのキーコードに従って、Input.GetKey(KeyCode.JoystickButton6)としても、反応しないのです。

Input for Windows Mixed Reality

調査を進めたところ、WindowsMRでもStreamVRを使用している場合は、OpenVRのキーコードに従う必要があることがわかりました。具体的に、Input.GetKey(KeyCode.JoystickButton0)とするとキー入力が取得できました。

Input for OpenVR controllers

ヘッドマウントディスプレイは、Acer、Samsung Odyssey、Dell Visorの三種類を試しましたが、眼鏡に一番やさしいのはDell Visorでした。Oculus Goよりも余裕があり、セルフレームでも締め付けられません。



Dell Visorの箱はとても大きいので、以下のケースがおすすめです。

第29回IGポート株主総会レポート(2018/08/28)

IGポートの株主総会に行ってきました。今年の参加人数は70人程度。座席の密度が高く、過去、最大レベルの人数です。

IMG_0316

招集通知の一株純資産の訂正についてのお詫び。石川社長から、先立ってもらったメール質問への回答がありました。

”業績予想を下回ることへのお詫び。12話のシリーズの海外への納品は終わったが、監査法人の指摘により、イベント上映を行う来期に計上することになった。CGコストの増加によって、引当金を積んだ。それによって第4四半期の利益が大きく下回る。来期の赤字は、コンテンツ投資の償却負担。アニメビーンズ、マンガドアの費用など、プラットフォームへの投資。プラットフォームには資金、コンテンツ、協力者が必要。制作事業はパッケージ販売の低迷によりプリプロ予算が供与できない。アニメーターの固定費増加、受注額と実制作費の乖離。制作、営業、管理で改善に取り組む。ぷららとの提携。配信を主とする会社。オリジナルコンテンツを創出して配信することで赤字を減らす。投資案件の明確化を図る。魔法使いの嫁、曇天に笑うに続く、シナジーを産むコンテンツを模索していく。五カ年計画を策定している。同業他社よりも資本効率が悪いとの声。真摯に受け止め、経営に邁進する。事前に質問をいただき、ありがとうございました。”

以下、質疑応答です。

魔法使いの嫁の海外売上の国別の比率と中国に売れた理由。


中国と欧米の割合は非開示だが、中国の方が多い。和田社長のアイディアでPVを作り持って行った。PVを見てご購入頂いた。通常は企画書のみ。契約の内容次第で、入金が長期期間にわたることが多いがまとめて前期に支払われる内容だった。海外の書籍販売については、韓国、フランスが多くの割合を占めている。

7/3にトーマツからの監査意見。そこからの訂正について、経理、IRの人材が不足しているのではないか。


マンパワーの不足もあるが、増強している。管理部にも2名を入れた。

経営管理の問題。取締役は制作に強く関わっていて、管理が手薄になっていないか。


ウィットスタジオを立ち上げたが、全ての業務を一人でやっていた。今期から、郡司取締役に入ってもらい、外部との折衝を担当してもらうなど、分担を進める。

アニメ会社4社かかえているが、4社かかえる必要性がどれくらいあるのか。統合することで合理化できないか。


クリエイターの多様化の状況。クリエイターには、金銭的というよりは優秀なクリエイターについていきたいという面がある。多様性か必要。

IGから和田、森下が会社を作った経緯。IGだけだと中間から下が伸び悩む。よりフレッシュな作品を緊張感を持って作れるようにした。

減価償却はどのようにやっているのか。中期経営計画において2022年から急に利益があがっているのはプラットフォームの貢献によるものなのか。


映像マスターは1年で償却。コンテンツ資産は1次利用によって期間が異なる。計画は積み上げ方式。投資額から、版権収入を見込む。納品後、減価償却が抜けたタイミングで利益があがる。

劇場作品のFateを作るのも大きな要因。勝負作もぶつけたい。制作事業は作品のヒットに収益が依存する。スマホビジネスについては安定的に利益を生むプラットフォームを作るのが大事。

実写映画に出資している理由。


社員からも質問されている。サイコパスを作った時に実写の本広監督に出会ったというのが大きい。面白いものを作るという観点では同じ。本広監督が亜人を制作した。四月の長い夢は映画祭で賞をとった。

ブラッドの実写版のクオリティが低い。版権のコントロールが必要ではないか。


著作権は海外の会社からの許諾。亜人は制作をIGが受けている。IGの中に実写部隊を置いている。CGについては実写ともシナジーがある。本広監督にはヒットの法則を社員に伝えてもらう意味もあり社員になってもらった。

ROE以外の目標数値はあるのか。


利益率7%。資本効率については高めていきたいが、減価償却に出てしまうので、将来キャッシュフローを増やしていく。

アニメーションを作る環境として、世間は好景気で仕事は多いが、単価が厳しい。ただ、この状況はピンチとチャンスであり、大きなチャンスと考えている。それは、金銭的な蓄えがあるかないかというのが大きい。お金の力とクオリティに挑戦できる力というのは大きい。

絶版Z。海賊版対策として活用してはどうか。


書籍部門を閉じてコミックに集中していた。今期から書籍部門を再開する。頂いた案も検討する。

違法アップロードの対策は。


法務課長が官民連携で検討している。

版権事業の原価には何が乗るのか。


映像マスターは出資した額。コンテンツ資産はIGグループの制作費。


その後、議案採決。総会の時間は1時間15分でした。銀英伝の上映会は時間の関係で欠席しました。今年はお土産はありませんでした。

GoogleCloudStorageの公開アクセス設定

GoogleCloudStorageにアップロードしたファイルに誰でもURLでアクセスできるようにするためには、GoogleCloudStorageのBucketを公開アクセスに設定する必要があります。

公開アクセスの設定をするには、Bucketの権限設定でallUsersに読み取り権限を設定します。

公開アクセス


公開アクセスの設定を有効にすると、以下のようなURLでBucket内のファイルにアクセスすることができます。

https://storage.googleapis.com/[Bucket]/[File]

個人識別のための顔認識の学習済みモデル

個人識別のために顔認識を行う場合、FineTuningを行う方法と、FeatureExtractorを使う方法があります。

前者は、予め決まっている人物を識別したい場合に使用し、VGG16等をベースにFineTuningを行っておき、学習後の学習済みモデルを使用して人物を特定します。後者は再学習は不要な方法であり、事前に膨大な顔画像で学習させておいた学習済みモデルを使用して、その中間層のデータを取得することで、顔の特徴を示す特徴ベクトルを取得し、認識したい人物のベクトルと、カメラから取得した人物のベクトルとの距離を計算することで個人を識別します。

CNNをFeatureExtractorとして使う場合の学習済みモデルとしては、VGG Faceがあります。これは、2015年に公開されており、ネットワーク構造はVGG16です。しかし、VGG Faceは商用利用不可となっています。

そこでTensorFlowで動く商用利用可のモデルとして2017年に公開されたのが、FaceNetです。ネットワーク構造はInception ResNetとなっています。

2018年にはVGG Face2が公開されました。VGG Faceから精度が向上し、商用利用可のライセンスとなっています。ネットワーク構造はResNetとSENetの2バージョンがあります。

VGG Face2のデータセットはクリーニングされており精度が高いため、FaceNetの方でもVGG Face2のデータセットで再学習が行われ、精度が改善しています。

KerasでVGG FaceおよびVGG Face2を使うには、keras-vggfaceを使用することができます。VGG16、ResNet、SENetに対応しています。

test.pyをコメントアウトして実行すると、以下のようにデータセットの中から最も近い人を表示します。

('\n', 'RESNET50')
('\n', array([[1.2077236e-07, 6.9855632e-06, 9.1819614e-01, ..., 1.4105116e-07,
        9.3622623e-07, 9.7075758e-07]], dtype=float32))
('\n', 'Predicted:', [[[' A._J._Buckley', 0.91819614], [' Billy_Butler', 0.007661988], [' Chris_Hardwick', 0.007469104], [' A._J._Pierzynski', 0.0045922087], [' Michael_Voltaggio', 0.0044681374]]])
.('\n', 'VGG16')
('\n', array([[9.7901160e-01, 4.9870639e-08, 7.0865167e-07, ..., 5.4379225e-08,
        7.6642658e-07, 3.7070203e-07]], dtype=float32))
('\n', 'Predicted:', [[['A.J._Buckley', 0.9790116], ['David_Denman', 0.0014457349], ['Carmine_Giovinazzo', 0.0008676527], ['Robert_Buckley', 0.0007245681], ['Eddie_Cahill', 0.00041833066]]])

特徴ベクトルを取得するには、include_top=FalseにしてFC層を除外した上で推論します。VGG Face(VGG16)の場合は4096次元、VGG Face2(ResNet)の場合は2048次元になります。

model = VGGFace(include_top=False, input_shape=(224, 224, 3), pooling='avg',model='vgg16')
print model.predict(x)[0]

東証のXBRLのパーサをオープンソース化しました

東証のXBRLのzipをパースしてBSとPLを抽出するパーサをオープンソース化しました。
abars/xbrl2bspl

アーキテクチャは以下を参照下さい。
XBRLからネットネット株を探す

TDnetViewをオープンソース化しました

iOSとAndroidでリリースしている東証の適時開示情報ビューワをオープンソース化しました。プルリクエストも受け付けていますので、機能追加したい場合はプルリクエスト頂ければと思います。また、フォークして別バージョンを作成頂いてもよいかと思います。

TDnetView for iOS
TDnetView for Android
Search
Profile

abars

アプリとWEBサービスを開発しています。最近はUnityとGAE/pyが主戦場。

ブラウザ向けMMOのメトセライズデストラクタ、イラストSNSのイラストブック、東証の適時開示情報を検索できるTDnetSearchを開発しています。

かつてエンターブレインのTECH Win誌でATULADOを連載しました。

サイト:ABARS
Twitter:abars
Github:abars

Twitter
TopHatenar
HotEntry
Counter

アクセス解析付きカウンター。あなたのBLOGにもどうですか?登録はこちらから。

TOP/ BLOG/ LECTURE/ ONLINE/ RUINA/ ADDON/ THREAD/ METHUSELAYZE/ IPHONE/ MET_IPHONE/ ENGLISH/ RANKING