catalinaの備忘録

ソフトウェアやハードウェアの備忘録。後で逆引きできるように。

情報処理技術者試験について思うこと

こんな記事が話題になっていたので乗っかってみます。

他人の出した話題、特に今回のような匿名ダイアリーにはあまり乗っからないのですが、昔の自分を見ているような気がしたので。

情報処理技術者試験なんて何の役にも立ちません

ちなみに私は最後に情報処理技術者試験受けてから6年くらい経ってるので、今は実情が変わっているかもしれません。あしからず。

情報処理技術者試験とは?

ひとまず試験区分一覧を見てみましょう。

IPA 独立行政法人 情報処理推進機構:試験制度:試験区分一覧

有名どころでは下端にある基本情報とその上の応用情報ですね。で、 基本情報から上に向かうほど高度になります(だいたいのイメージです)。

で、上部の「高度な知識・技能」の灰色枠にはピンク枠の縦書きがいっぱい並んでいますが、ここが高度情報処理技術者と位置づけられてるところです。

試験名を見ればスペシャリストかゼネラリストかだいたい予想つきますね。

偉そうに話する前に、どれか持ってる?

3つ取りました。

ここから先行くならプロマネ、アナリストと進むところですが、私の目的と合致しないので受けてないです。

情報処理技術者試験は役に立たない?

そのまま参考書を勉強するだけではスキルアップにはなりません。そのうえ引用元にあるような暗記方式では尚更でしょう。

そのままではスキルアップにはなりませんが、技術者として幅を広げるという役に立ちますので、ここで私の過去を振り返ってみます。冒頭の「昔の自分を見ているような気がした」フラグ回収です。

昔の自分を見ているような気がした

引用元の匿名ダイアリーを見ると、昔の自分を見ているようです。

今にして思えば、昔の自分は視野が狭かったなぁとしみじみ思います。

私はもともと映像関係の組み込みソフトウェア開発をしており、何年か前にWEB系にキャリアチェンジしています。

そういった経歴のため、引用元にある以下の出題に関しては「知っているし、実装技術についても理解していて当たり前」という話になってきます。暗記するどころか勘ぐってしまいます。

次の画像符号化方式のうち,携帯電話などの低速回線用の動画像の符号化に用いられるものはどれか。
    JPEG
    MPEG-1
    MPEG-2
    MPEG-4

私の思考:

MPEG-4と答えさせたいのだろう。しかし、問題文が抽象的だなぁ。。。
ワンセグならMPEG-4でいいけど、「低速回線」というのがどのくらいを指しているのかがわからない。
いやいや、「回線」というからには放送関係の話ではなくスマホのHLSの話になるのかな。
そうすると、HLSで使用されるコーデックの話か?ああ、でもHLSの中身ってH.264だし実質MPEG4か。消去法で見たときもMPEG4以外なさそうだし。MPEG4でいっか。

といった感じです。

問題の解きやすさ/解きづらさというのは、所属する業界と立場によるものが大きくて、たとえば上記例題は業務システムの実装がメインの人は少々解きづらい問題です。(=手っ取り早く暗記で解決でもいいレベル)

これとは逆に、勉強を始めた当初の私はDB関係の出題は一切解けませんでした。 なぜならDBなんて触ったことありません。なのでERDなんて見たこともないし、書くこともない。タイミングチャート読めてロジアナでデバッグできるほうが重要。そういう世界です。

こういった所属業界や立場ごとの差があるのでこの設問はダメだとか頭ごなしに拒否するのではなくて、「知らない業界の話かな。。。」程度に軽く受け流してから、腰を据えて勉強するのがいいんじゃないかなと思います。

私もDBを勉強するために、当時のVisualStudioの付録のSqlServerを立てて色々動かしてやっと理解しました。すごく遠回りだったとは思いますが、身についた内容は今も使えているので、無駄にはならないと思います。

(物理マシン1台用意したのは勿体なかったかもしれない)

情報処理技術者試験が役立つ場面

先の例では業界や立場によって問題の解きやすさが変わってくるよという話でした。

そうすると情報処理技術者試験って誰向け?ということになるのですが、試験制度を再確認すると「基本情報」と「応用情報」は「情報処理技術者」としての土台に当たります。

即ち「全員これくらいは知っていてほしい」というレベルで、ソフトウェア開発に従事する人であれば、各個人どこに位置するかを調べるための腕試しということで良いのではと思っています。

「基本と応用がこんな簡単なんだから、高度も簡単に合格できるのでは」と思う人はまず問題集を買ってからざっと見てみるといいと思います。

たとえばエンベデッドであれば午前問題からいきなり回路図出てきたりしてなかなかカオスで楽しい世界です。2入力ANDを3入力ANDにしたいとか。

午後はウォシュレットの設計や立体駐車場の入出庫システム作ったりと、身近なシステム例だからこそ楽しかった記憶があります。

話を戻しましょう。

まあ、とりあえずは「役立つ/役立たない」論争になったときのために取っておくのをお勧めします。

試験に合格しておけば「持ってるけど実務じゃ役に立たないよ。転職の時の飾りかな」程度にドヤれるのでお勧めです。

真面目な話を少しだけすると、仕事の幅が広がるというメリットがあります。

試験に合格しておくことで

  • 何の知識もないし、あるかどうかも不明な人

という評価が

  • 最低限この試験の知識くらいはある人

に上がります。 そうすると仕事の内容も幅が広がっていきますし、その結果は転職でも有利に働きます。 その試験の難しさやレベルを理解しない会社であれば、辞めてもいいと思います。はい。 (ただし、情報処理技術者試験だけがすべてではないということをお忘れなく。)

情報処理技術者試験が役立つ場面(ネタ)

ネタになってしまいますが転職時に人身売買ブラック企業を回避できるメリットがあります。

実際にあったことなのですが、、、

面接時

面接官「基本情報とかの資格もってる?」
自分「基本情報は持っていませんが、ソフトウェア開発技術者とエンベデッドを持ってます」
面接官「基本情報持ってないの?うーん、あなたの年齢でそれはちょっと厳しいねぇ。。。クドクド」

とありがたい説教いただいたことがあります。

話の内容から推測するに、お客さんから「基本情報くらい持ってる人を寄越せ」くらいに怒られたのかな?と思っています。

帰宅するとその会社からお祈りの留守電入っていたので、すぐポチって消しておきました。嫌な事件だったね。

尚、このネタは業界辞めるまで使い続けるつもりです。

情報処理技術者試験の問題点(試験のやり方が古い)

技術内容に関する設問は少々古臭いとはいえ、汎用的なものを目指すとこうなるのだろうと思っています。

それはそれでいいのですが、やり方が古いと感じます。これが最大の問題です。未だに受験者を会場に集めて筆記式ですよ。 この筆記試験の最大の敵。それは高度試験の午後問題でやってきます。

いくつかの高度試験の午後2に「小論文の筆記」というものがあります。 これは「2時間ずっと文字を書く握力があるか」を調べる体力測定試験です。 合計2000~3000文字くらい(具体的な数字忘れました)をひたすら筆記するわけです。

私は体力不足とエンピツの持ち方が悪いのが相まって、2時間書き続けることができませんでした。

で、小論文の筆記って極悪で、章構成の変更が効かないんですよね。一度書いたらそれっきり。書き直ししていたら時間切れになってしまう。 なので、よくある文章の書き方

  • アウトラインで全体の構成を作る
  • どんな内容を盛り込むかをだいたいの肉付けしていく
  • 清書

を勉強して、書き慣れる必要があります。

当時は文章の書き方を勉強しつつ、体力づくりのために腕立て伏せとかしていたのですが、なんというか、もはや試験とは全く別のところで苦労していて「いい加減に試験制度を見直しなさい」と言いたくなるレベルです。

暗記で解けない午後問題

言及元ではこのように批判されています。

情報処理技術者試験で測れる能力は以下の2つだけです。

    内容の理解はともかく、ある用語を「聞いたことがある」かどうか。
    150分間、落ち着いて椅子に座っていられるかどうか。

まあ、午前試験についてはその通りでしょう。

しかしこれでは主語が大きすぎています。 情報処理技術者試験は前述のとおり、いくつもの受験カテゴリがあり、それぞれで試験内容が異なります。

内容の理解はともかく、ある用語を「聞いたことがある」かどうかだけで解けるのはせいぜい午前問題までです。

応用情報以上の午後およびそれ以上の問題は暗記や「聞いたことがある」レベルでは解けなくなります。

たとえば応用情報以上でよく見かけた設問にこんなのがあります

  1. A氏は下図のような設計を行った。しかし要件を満たせないことがわかった。満たせていない要件を要件定義シート中から抜き出して述べよ

  2. 前の設問で抜き出した要件を満たせていないのはなぜか、本来要件を満たすべきプロセス名をDFD中から抜き出して述べよ

  3. 実際に要件を満たすために、プロセスはどのように変更されるべきか述べよ

(疲れている状態で勉強していると「A氏に修正させろ。レビューで突き返せ」と投げたくなる、素晴らしい設問です。疲労度チェックに使えます)

このテの設問は用語や基礎や暗記だけでは解けませんし、現場独自のルールみたいなのも通用せず、一般論で解けるように作られています。

  • 文章をよく読んで理解し
  • 要件定義、設計書などから読み取れることだけを事実として
  • 「普通こうでしょう」みたいなローカルルールは持ち込まず
  • 一般的なやり方で、説明可能な手法で物事を解決する

ことが求められます。 これが結構難しくて、現場でも出来ない人が結構います。

何かしらの技術を勉強中の段階では特に顕著で、直観的な理解だけで済ませていると詰まってしまいます。 私自身もそういう部分があって、新しい技術要素などを「なんとなく理解したつもり」で使っていても、その内容の説明を求められて詰まることがあります。

このように「直観的になんとなく」ではなく「理論的に理解している」ことが試されるのが午後問題です。

感想と今後の展望

珍しく他人の文章に言及しました。昔の自分も言及先と似たようなことを思っていました。

たしか昔はこんなこと考えてたと思います。

  • こんなの役に立たないでしょ。うちの仕事じゃ使わない
  • マークシート式なので暗記ばかり。勉強が楽しくない。

コードを書いていくクリエイティブさとと比べると情報処理の試験勉強はとても地味で刺激が少ないものです。 突然出てくる未知の用語がとても苦痛だった記憶があります。

日本では試験に合格しなくてもプログラマとして働いていける環境なので、情報処理技術者試験は「将来の自分の選択肢を増やすための手段の一つ」として捉えておくくらいで良いかと思います。

なので、引用元の方の仰るとおり、役に立たないと思うならそれはそれで良いと思います。 利用価値の見えないものに時間を使うくらいなら、もっと費用対効果の高いことへ時間を使った方が幸せになれるということでしょう。

もし将来気が向いて「体系立ててITに関する勉強をしたい」とか思った時に選択肢の一つとしてあればいいかなと思います。

私も情報処理技術者試験に関してはシステムアーキテクトを取ってからはもう手を出すのを辞めました。(確かこのブログを開設したのと同じくらいの時期だったと記憶しています。)

今は自分で作りたいものをどんどん作っていき、必要があれば情報収集と勉強を繰り返していくフェーズだと思っています。

それでは今回はこれくらいで。

kerasを試す

この記事は以前下書きしたものを公開し忘れていたものです。

情報が古い恐れがありますのでご注意ください。

リモートワークでいつもと違う環境で仕事しています。かたりぃなです。 通勤時間がゼロなので、睡眠時間と勉強時間が増えていい感じです。 とはいえ自宅にはゲームなどの誘惑があるので、電源やLANを引っこ抜いておくなどの物理的対策を施しておく必要があります。

今回はDeepLearningフレームワークのKerasを試してみます。

動機

chainerの最終リリースが行われ、これが最終バージョンとなるそうです。 最新のDeepLearningを追いたい人はPyTorchへどうぞとのことです。

とはいえ、折角選んだchainerというフレームワークが終わってしまうので、そのままどうぞとガイドに従うのも少々嫌です。 ので、導入が簡単ときいたことのあるkerasを試してみます。

kerasはバックエンドを切り替えることができるらしいです。 一旦デフォルトのtensor flowで動かしてみて、慣れてきたらCNTK(Microsoft Cognitive toolkit)とかに変えて試したみたいなとか思っています。

環境構築

vscodeのコンテナ機能を使って簡単に試してみます

手元の環境は

です。

早速やっていきます。まずは実験用のコンテナを作ります。

  1. コマンドパレット(Ctrl + Shift + 'P')を開く
  2. コマンドパレットに'Remote'と入力。候補が表示される
  3. 表示された候補から'Remote-Containers: Open Workspace In Container'を選択
  4. 言語やフレームワークの選択で、Python3(Develop python3 applications)を選択する。

dockerfileのビルドが行われ、コンテナが起動します。 dockerfileやコンテナ起動時のパラメータ類は.devcontainerに格納されます

早速動かしてみましたが、ダメでしたので、設定変更しておきます。

コンテナの設定を変更する

pythonのバージョンを確認する KerasのバックエンドであるTensorFlowがpython3.7までしか対応していないとのことでした。(2020.02.28現在) バージョンを確認して、合ってないようなら修正します。

$ python -V
Python 3.8.1

はいダメですね。

dockerfileのfrom行で指定しているpythonのバージョンを細かく指示しておきましょう。

FROM python:3

FROM python:3.7

として保存します。

そしてvscodeを開きなおすと、「dockerfileが変更されているけどどうするか。rebuild or ignore」という選択肢が出るので、rebuildを選択してしばし待ちます。 暇なら"detail"をクリックしてログでも眺めておきましょう。

シェルが起動したら再度バージョンを確認。

$python -V
Python 3.7.6

よさそうです。 これでTensor Flowが入ります。あとでdockerfileに書くか、コミットしましょう。

apt-get update
pip3 install tensorflow
pip3 install keras

トラブルシューティング詳細

TensorFlowのPythonインターフェースを使うには、以下のurlにあるsystem requirementにあわせる必要があります ここにないバージョンの場合は修正する。(3.8 -> 3.7) https://www.tensorflow.org/install/pip

kerasの動作確認

サンプルコードで動作確認をします サンプルコードは

git clone https://github.com/keras-team/keras.git

で持ってこれます examplesに色々入ってる。 中身はchainerのやつと似たり寄ったりですね。

examplesの動かし方

cd keras/examples python ./mnist_mlp.py

ログ

Using TensorFlow backend.
2020-02-03 00:10:50.371771: W tensorflow/stream_executor/platform/default/dso_loader.cc:55] Could not load dynamic library 'libnvinfer.so.6'; dlerror: libnvinfer.so.6: cannot open shared object file: No such file or directory
2020-02-03 00:10:50.371973: W tensorflow/stream_executor/platform/default/dso_loader.cc:55] Could not load dynamic library 'libnvinfer_plugin.so.6'; dlerror: libnvinfer_plugin.so.6: cannot open shared object file: No such file or directory
2020-02-03 00:10:50.372012: W tensorflow/compiler/tf2tensorrt/utils/py_utils.cc:30] Cannot dlopen some TensorRT libraries. If you would like to use Nvidia GPU with TensorRT, please make sure the missing libraries mentioned above are installed properly.
Downloading data from https://s3.amazonaws.com/img-datasets/mnist.npz
11493376/11490434 [==============================] - 3s 0us/step
60000 train samples
10000 test samples
2020-02-03 00:10:55.722601: W tensorflow/stream_executor/platform/default/dso_loader.cc:55] Could not load dynamic library 'libcuda.so.1'; dlerror: libcuda.so.1: cannot open shared object file: No such file or directory
2020-02-03 00:10:55.722728: E tensorflow/stream_executor/cuda/cuda_driver.cc:351] failed call to cuInit: UNKNOWN ERROR (303)
2020-02-03 00:10:55.722776: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:156] kernel driver does not appear to be running on this host (2a25a8fd3a58): /proc/driver/nvidia/version does not exist
2020-02-03 00:10:55.723133: I tensorflow/core/platform/cpu_feature_guard.cc:142] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
2020-02-03 00:10:55.738064: I tensorflow/core/platform/profile_utils/cpu_utils.cc:94] CPU Frequency: 2904000000 Hz
2020-02-03 00:10:55.738448: I tensorflow/compiler/xla/service/service.cc:168] XLA service 0x5591706d4e20 initialized for platform Host (this does not guarantee that XLA will be used). Devices:
2020-02-03 00:10:55.738608: I tensorflow/compiler/xla/service/service.cc:176]   StreamExecutor device (0): Host, Default Version
Model: "sequential_1"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_1 (Dense)              (None, 512)               401920    
_________________________________________________________________
dropout_1 (Dropout)          (None, 512)               0         
_________________________________________________________________
dense_2 (Dense)              (None, 512)               262656    
_________________________________________________________________
dropout_2 (Dropout)          (None, 512)               0         
_________________________________________________________________
dense_3 (Dense)              (None, 10)                5130      
=================================================================
Total params: 669,706
Trainable params: 669,706
Non-trainable params: 0
_________________________________________________________________
Train on 60000 samples, validate on 10000 samples
Epoch 1/20
60000/60000 [==============================] - 7s 115us/step - loss: 0.2429 - accuracy: 0.9252 - val_loss: 0.1477 - val_accuracy: 0.9557
Epoch 2/20

ログをざっくり翻訳

mnistデータのダウンロードしてくれてますね。 ダウンロードしたデータセット~/.keras/datasets/に置かれるようです。

なんか警告がたくさん出てるけど、動かすだけなので今は無視します。NVidiaのDeepLearningSDKが入ってないとか、CUDAが入ってないとかそういうの。 cuInitでCUDA初期化失敗したり、カーネルモードドライバが無いと言ってたり。 さらに、CPUのSIMD命令を使おうとしたけどそれもダメでしたと(AVX2) 一言で言うと「学習すごく時間かかるよ」ってことですね。 GPUなし、CPUのSIMD拡張命令も無しってことなので。

ネットワーク確認

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
dense_1 (Dense)              (None, 512)               401920    
_________________________________________________________________
dropout_1 (Dropout)          (None, 512)               0         
_________________________________________________________________
dense_2 (Dense)              (None, 512)               262656    
_________________________________________________________________
dropout_2 (Dropout)          (None, 512)               0         
_________________________________________________________________
dense_3 (Dense)              (None, 10)                5130      
=================================================================
Total params: 669,706
Trainable params: 669,706

コードでいうと以下の箇所と一致します。

model = Sequential()
model.add(Dense(512, activation='relu', input_shape=(784,)))
model.add(Dropout(0.2))
model.add(Dense(512, activation='relu'))
model.add(Dropout(0.2))
model.add(Dense(num_classes, activation='softmax'))

入門でよくあるmnistの3層のNNです。 Denseで生成される関数は output = activation(dot(input, kernel) + bias)とのことなので、そのまま解釈すればよさそうです。

  • dense_1,dense_2では512個のユニットがあり、
  • 活性化関数RELUを通して出力する
  • 念のため。dotはいわゆる内積。重みと入力を掛けて足す
  • ログ中のParamは各層の結合数 + ユニット数

ログ中のParamの値は、たとえばdense_1はMNISTの784次元のデータが入力されるので 784 * 512 + 512 = 401920 ということですね。 最初の512が重み係数をもつユニット数で、次の512がバイアスですね。 同様にdense_2は 512 * 512 + 512 で 262656となります。

感想と今後の展望

思ったより簡単に動きました。 マニュアルも普通に読めますし、当面はこれでいいかなといったところです。 それでは今回はこれくらいで。

2020年の抱負と昨年の振り返り

2019年のふり返り、2020年の抱負

新年あけましておめでとうございます。例年やっているふり返り記事になります。かたりぃなです。

まず最初に。気が付けばこのブログの読者も30人を超えていました。まだまだ未熟者のブログではありますが読んでくださってありがとうございます。

今後も活動を続けていきますのでご愛顧のほどよろしくお願いします。

最初に2020年の目標を一言で表現すると。。。

ダイの大冒険のアニメ化の合わせて、ARで魔法や必殺技を再現する!」

です。20年以上前の夢、メドローアやアバンストラッシュ撃ちたいとかミナカトールで魔法陣を発動させたいという夢を叶える絶好のチャンスです。

(いつも物体検出やトラッキングで詰まっているように見えるのは気のせいということにしておきましょう)

それでは2019年のふり返りと2020年の抱負をやってみたいと思います。

2019年やったこと

このブログで2019年に記事にしたものをふり返ってみます。

記事にしたものは3つあります。それとは別に、記事にしてないものも軽く触れてみます。

1. フォトグラメトリ

OpenMVGとOpenMVSですね。

目的は「コスプレ用のアイテムを3Dプリンタで作りたい。3Dモデリングが手間かかるので、3Dモデルも自動で作りたい」というものでした。

試行錯誤しましたが、目的を完全に果たすことはできませんでした。

目標達成には至りませんでしたがOpenMVGのコードを追うことで技術的な理解が深まった点は良かった点かなと思います。今までARで追ってきていた技術の基礎の延長上の話だったので、やっぱり基礎は大事だなと思った次第です。

最終的にはMeshRoomというOSSを使用することで、使えそうな3Dデータが得られました。このMeshRoomで生成した3Dモデルも完全なものではないので、3Dモデリングの下書きとして利用しています。

結局は単体技術で全ての課題を解決するだけではなくて、運用まで含めて妥当な落としどころを見つけるのが大事ですね。もちろん単体技術で解決できるならそれは理想ではあるのですが。

2. インフラ

私の中で利用できる技術が2つ増えました。

  • ELKスタック(ElasticSearch, LogStash, Kibana)
  • Ansible-Playbook + ELKスタック

どちらもdocker上で動かしています。

EKL

ログ分析はシステムを運用するうえで今後も必要な技術だと考えているので、少しずつでもこれらを使えるようになっておいて損はないと思います。

実際の運用ではELKを素のままで使うことはおそらくないだろうなと思っていて、何らかのデータストレージのフロントとして使うことが多いだろうと想定しています。

また、ELKに文字列を突っ込む際に形態素解析を試したりしたのも楽しかったですね。PythonからMecabを叩いてたりしました。

Ansible-Playbook + EKL

まだ記事にしていないお話しです。「Ansible-Playbook + ELKスタック」というものを試していました。

どういうものかというと、Ansible-Playbookのログ(changedとかokとか出るアレ)をELKに渡しておくことでログの視認性を良くするのが目的です。

Playbookのログって見づらいので、色々と試行錯誤していてこの手法に辿り着きました。

これができると何がいいかというと、よくあるPlaybookの問題「changedが出てるけど、これ何?常に出る(=実は無視していい)やつでは?」を簡単に切り分けできるようになるだとうと思っています。

もちろんログを蓄積してあるという前提ですが。

CI/CDの監視で使えば幸せになれるかもしれませんね。本年の早い段階で記事にしておくつもりです。

Ansible-Docker

これもまだ記事にできてないお話しです。Dockerのデプロイで外部のコンテナリポジトリを使わずにデプロイするものです。

AnsibleのモジュールでDockerコンテナを操作できるものがあるので、利用したものです。 やりたいことと完全にマッチしているわけではありませんが、工夫すれば色々とできそうです

Ansible-Playbookの枠組みで次のことが実現できるので、迅速に開始させたいサービスでコンテナを使う場合には選択肢としてアリなのではと思っています。

  • dockerイメージを作れる
  • dockerイメージをエクスポートできる
  • dockerイメージをインポートできる
  • コンテナ操作できる(調査中)

3. MixedReality(Hololens)

自分はHololensでC++を使う奇特な人種なので、UWP用の新しいC++/CLRとしてWinRTを試してみました。C++/CXより良くなってる気がします。しばらく使っていくうちに現時点での不足部分もわかってきました。

記事にしていませんが、C++/WinRTを使ってUnityネイティブプラグインを書いてみたりもしました。

まだうまくいってなくて落ちたりするので、もう少しデバッグしてから記事にする予定です。

Unityネイティブプラグインに手出しした理由は、C++だけだとライブラリの充実度などの問題で、開発速度があがらないためです。たとえばVRMやglTFのモデルの取り込みとかはUnityのほうが圧倒的に進んでいる印象です。

そう思ってUnityで色々と試してみたものの、やはり慣れない環境というのは手間取ってしまいます。

特にHoloToolkitからMRTKへの移行で躓いてしまったのは残念ポイントです。そうこうしているうちに2019年が終わってしまいました。

2020年はリベンジです。

あと新型も買わなきゃ(レンタルかなぁ)ですね。

4. 記事にしてない大きなカテゴリ

そのうち記事にするので軽く触れてみます。(後者は記事にはしないかも)

  • TweLiteプロジェクトの再構築
  • 投資

twelite

TweLiteはZigBeeプロトコルでIoT的な用途で使える便利なやつです。 今回TweLite2525Aが出てたのと、開発環境がVSCodeになっていたので一通り作り直しました。

久しぶりの組み込みプログラミングでしたが、慣れている部分が多いのでサクっといきました。 TweLiteは次の点が優れていると思います。

なので、私のような低レベルレイヤで戦った人であればコード読んですぐ開発に入れる環境でした。 (OS固有の仕様とか無いので、一般的な組み込みプログラムの理論だけで通用する)

電子回路回りも作ってあるので、あとはどこかのイベントで実験するだけですね。

投資

投資はプログラムとは全く関係なくて、他の道を探すときにどうなるのだろうという試みの一つになります。

動機は

  • 不労所得が欲しい(収入を増やしたい)
  • 老後の資産形成

などです。

サラリーマンの収入は、勤めている企業の収益や社内政治に影響される部分が大きくて、収入を増やすにはそれらの理解が欠かせません。

私は社内政治というか人づきあいに興味が薄いので、市場理解のほうへ挑戦したというところです。

市場理解と投資の関係について少し述べると、市場そのものの動きを理解するために実際に投資・運用して、自分自身が投資家の立場としてどうするかを理解していくのが近道だと考えたためです。

2018年は実験、2019年は本格的に投資の売買をしました。

一旦の結論として「物事を分析して判断する力」があれば投資で稼ぐことは可能だということがわかりました。

この「物事を分析して判断する力」力は多くのソフトウェアエンジニアには自然と備わっていると思っていて、例えばリスク管理の分野で考えるなら

  • どこまでなら損を許せるか(リスク評価と対策)
  • 損した原因を分析できる(原因分析)
  • スコープを明確化できる(短期的な売買/長期的な売買を区別できる)

などが該当するのではないかと考えます。 「損」という言葉を「障害」や「影響範囲」などに置き換えれば身近なものに感じるのではないでしょうか。

ひとまず年利5%前後を達成できているので、継続していきたいと思います。

ファイナンスのための確率解析 II (連続時間モデル)

ファイナンスのための確率解析 II (連続時間モデル)

ファイナンスのための確率解析 I

ファイナンスのための確率解析 I

  • 作者:
  • 出版社/メーカー: 丸善出版
  • 発売日: 2012/04/20
  • メディア: 単行本

こんな本購入したので、こちらも機械学習のついでに読み進めていっています。 知らない用語ばかりなので難航していますが、新しい知識というものは楽しいものです。

2020年のテクノロジー予想

ARって未来の技術」とか「特別なもの」みたいに思われていたのが2018,2019年までかなと思っています。

ここ数年のテクノロジーを見ていると、ARデバイス単体でARができるのは当たり前で、次のステップに移りつつあると考えます。

具体的には

などが考えられます。

ガートナーが発表しているテクノロジのハイプサイクルで2018年に「過度な期待のピーク期」を超えて「幻滅期」へ、2019年には図から消えました。2018年の発表では、"今後5~10年"に"競争優位性をもたらす可能性が高い"との表現でした。

このことから、2020年はまさに啓蒙活動や生産の安定性にむけた大事な時期ではないかと考えます。

xRについて思うこと。

毎年がVR元年と言われているここ数年ですが、エンドユーザーに向けてxR(VR,AR,MR)を推すのは少々筋が悪いのでは?と思っています。

xRは表現手段、情報の表示手段の一つであってユーザーが求めているものではないはずです。ユーザーが求めているものは

  • 必要としている情報を
  • 必要なタイミングで
  • わかりやすく見せてくれること

だと思っています。

スマートフォンが普及した現代ではスマートフォンの画面に情報を表示するだけで充分な場合もあります。 逆にスマートフォンの画面だけではわかりにくい情報は、別の方法でユーザーに見せる必要があります。

前者はいわゆるビューワーやクーポンなどのアプリで、後者は地図アプリなどが代表例でしょうか。

xRでも同じことで、概念的には「従来と見せ方の手段が異なる」だけです。

しかしデバイスとしての制約(装着するなど)があるため、どうしても区別してユーザーに説明することになってしまうので、「これはVRである」「これはARである」みたいにあまり重要ではない部分に話を持っていかれている感がします。

AR,MRについて技術的な観点から考えると「仮想世界と現実世界の情報をシームレスにやりとりする」という点がポイントになるのかなと思っています。

キーボードやマウスを使わなくても片手に収まるタッチパネルだけで情報検索ができるようになったのと同じように、タッチパネルを使わなくても声だけ、周囲の情報だけで自動的にユーザーが必要としている情報を推論して必要な情報を提示するという形が将来のMRなのかなと思っています。

2020年やりたいこと

Hololensをメインにやっていこうと思います。今までサーバ側がメインだったので、HololensとUnityをしっかりと調べたいと思います。

Hololens2も来ますし、そっちに軸足を移しつつ進めていきたいですね。

また、2020年からは転職も視野に入れて活動しようかと思っています。

本業は都内のWeb屋で働いていて、器用貧乏な中年です。 もしこのブログの内容を見て興味あるという方いらっしゃいましたらtwitterかコメントでも連絡いただければと思います。

本業の内容はこのブログより深く高度なことをやってはいますが、どろり濃厚なので公にはしづらいのです。あしからず。

それはさておき、まずは自分の力で何かを作り上げていくのが何よりも大事だと考えているので、今年もそれに向けて頑張っていこうと思います。それではこれくらいで。

本年もよろしくお願いします

VS Code Remote Developmentを試してみた(感想)

晩秋から冬へ移り変わっていく季節ですね。世間では色々なものが発表されていて、どこから手を付けていこうかとワクワクしています。 今回は開発環境まわりがパワーアップしたので、その記事になります。

開発環境の構築

Web開発ではリモートマシンで作業することが多く、そのためには数多くの設定をしてあげる必要があります。

俗に「環境構築」とか呼ばれる作業で、これがとても面倒だったりします。

実際の使い方は公式チュートリアルが充実しているので省略します。

https://code.visualstudio.com/remote-tutorials/containers/getting-started

自分の場合は既にdockerとvscodeが動作する環境があり、dockerもそれなりに触っていたので、1時間前後で完了して雰囲気は掴めました。

今回は少しだけ昔を振り返りつつ、今回のVScode拡張機能で何ができるかを纏めます。

ちょっと昔の環境構築

ちょっとだけ昔、Web開発といえばVirtualBox仮想マシン設定からでした。(今もある程度はこういう作業必要だったりしますが)

https://catalina1344.hatenablog.jp/entry/2014/04/02/222630

少し進んでVagrantとかPappertみたいな環境構築ツールも登場しましたが、環境構築の苦労はあまり変わらなかった印象です。

なんで大変なの?て言われると、その時々によって状況が変わるという部分が大きくて、たとえば

  • 環境構築ツール(たとえばVagrant)のバージョンが違う
  • 開発担当者の環境そのものが違う
    • win/mac
    • 環境構築ツールを動かす言語(RubyとかPythonとか)のバージョン

みたいなのがあります。

毎回こういう地雷を踏みながら、特定条件下(社内だけとか)でしか使えないナレッジが溜まっていくわけです。

最近の環境構築

いまどきはDockerという軽量でポータブルな仮想環境があるので、これで環境構築がとても楽になった印象です。

楽になった部分はありますが、まだ解決できていなかった部分もあります。

尚、今回のエントリは「まだちょっとだった部分」が解決されたよというお話しです。

dockerを使うことで昔より楽になった

  • ターミナル設定
  • ファイル共有設定
  • ネットワーク設定

dockerになってから、すごくラクになりましたね。 トラブルが起きたら結局設定ファイル見て頑張るみたいなのはありますが、それはそれで。

dockerを使っても、まだちょっとだった部分(今回のvscodeで解決!)

  • エディタの設定
  • デバッガの設定
  • localとremoteでのバージョン合わせ

ここはdocker含めて、環境構築ツールでは解消しきれていなかった部分です。

そもそもDockerが提供するのは「仮想環境」であって、「開発環境」ではないというだけな話です。

問題を解消できていない理由自体もとても簡単です。開発環境として使う場合、ローカルマシンとリモートマシン両方の設定が必要になってくるからですね。

たとえば

  • エディタをどう動かすか
    • localで動かしてファイル共有だけする
    • sshfsとsshで直にremote編集か
  • リモートデバッガでは接続先に何かをインストールする必要がある
    • 使う言語にあわせたリモートデバッガが必要
    • ネットワークのポート設定も必要だったり
  • intellisense(コード補完)を効かせるための設定が面倒
    • remoteとファイル共有だけしてるケースだと、localとremoteで同一パッケージが必要

みたいなのがあったりして、とても手間でした。

特に最後のintellisenseの設定が鬼門で、たとえばPythonで開発する場合

  1. DockerコンテナのPython関係のファイルをWindowsから見えるようマウントする
    • パスが違ってたりしてうまくいかない。
    • この方法は諦めた
  2. ローカルのWindowsマシンにAnacondaでも入れてみる力技でいってみる
  3. パッケージの関数も補完してほしいからpip installとかをwindowsとコンテナ側それぞれでやる
    • ただしWindowsには入れにくいパッケージがあったりする。(graphvizとか)
    • pip instal時にビルドするタイプ、かつ依存ライブラリもってるやつ
  4. windows側に全部そろっていくなら、dockerいらなくね?

みたくなってました。

VS Code Remote Developmentを使う

公式:

https://code.visualstudio.com/docs/remote/remote-overview

図を見るとわかるとおり、RemoteOS上にVS Code Serverを置いて、そいつが全部面倒みてくれるという仕組みのようです。

こうすると何が起きるのかというと、remotedevelopment当初のキャッチフレーズのとおり

VScodeとdockerコンテナのシームレスな連携」

です。

まずは使ってみた感想

控え目に言って最高です。

何が最高かって

  • ものの数分で各プログラム言語のコンテナが立ち上がって開発を始められる
    • js, php, python, C#, R, C++, ...
    • 裏でdocker-pullして必要なものを追加してくれてる
  • デバッガやコード補完も動く
    • 過去インストールした拡張パックが影響してるかもしれないが、特に難しい設定もなく動く
    • Python, PHP, C#(dotnet core)で確認
  • 追加のライブラリを入れたい
    • 単にdockerfileを編集すればいける
  • 開発環境の面倒な初期設定全部やってくれる
    • 以下のような問題を気にしなくていい
      • コンテナ作るためのdockerfileどうするとか
      • ネットワーク割り当てどうしよう、nginxの設定どうしようとか
      • ファイルのマウントどうしよう。どこが適切か(パーミッション維持する必要あるなら尚更)とか

少し掘り下げて使ってみた感想

少し掘り下げて、実用上問題ないか試してみた感想

  • よくあるWebアプリ(CMSとか)の基本構成もサポートされてる
    • Webアプリ + DB みたいな構成
    • python + postgreSQLみたいなのもプリセットにあるので楽々作れる。
  • 過去に自分が作ったコンテナを利用できる
    • dockerfile もしくは docker-compose.yml を指定するだけ
      • 起動時にどのコンテナにアタッチするか訊かれるので、アプリが動いてるコンテナを指定
    • 昔作ったdocker-composeで動作確認できた
      • nginxコンテナをfront
      • pythonPHPコンテナををback

実用を考えた場合にどうなのか?

VS Code Remote Development を実際に使うことを考えてみると、まあアリなのではないかなと思っています。

ただ、手放しで全てOKといえるわけではなくて、本番環境のコンテナどうやって作るかなどは別途考える必要がありそうです。

(開発用の色々なものが入ったままのコンテナを本番に置く勇気は無いので。。。)

とはいえ、原理的にはdockerを開発環境のback-endに置くというだけのことなので、dockerを前提とした開発であればアリだと思います。

構成もシンプルなので、困ったときは通常のdockerコマンドで外から操作できるのも強いところです。

感想と今後の展望

VS Code Remote Developmentという武器を手に入れたので個人開発が大きく捗りそうです。

デバッガの設定が面倒だからと諦めてprintfデバッグしてた環境とか、大きく改善されますね。

あとは開発環境の宗教論争が始まった時に「Windows10Proとdockerとvscodeで統一すればいい」と火に油を注げるようになります。

それでは今回はこれくらいで。

OpenMVG, OpenMVSで3D再構築する

前回のエントリでOenMVGを使って三次元再構成ができることが確認できました。 今回はさらに進んで、ジオメトリを再構成してみます。

カメラ内部パラメータの設定

前回のエントリで生成したカメラ内部パラメータは間違えていました。正しくはこうなります。

間違えていた原因としては、OpenCVキャリブレーション関数でのRow/COlumnsの扱いが逆になっていたためでした。

手作業で格子状の画像からこんな感じの交点を抽出しましたが、これは横7, 縦5個の交点です。

    corners = np.array( [
        [1013, 321], [1052, 319], [1090, 318], [1129, 316], [1166, 315], [1204, 314], [1240, 313],
        [1012, 360], [1050, 358], [1088, 357], [1126, 353], [1164, 353], [1201, 352], [1237, 350],
        [1012, 395], [1050, 394], [1087, 394], [1124, 391], [1160, 389], [1197, 389], [1234, 386],
        [1011, 432], [1048, 431], [1085, 430], [1122, 427], [1158, 425], [1195, 424], [1230, 422],
        [1011, 469], [1047, 466], [1083, 465], [1120, 463], [1156, 460], [1192, 458], [1227, 456],
    ], np.float32  )

どういうことかというと、

    rows = 7
    cols = 5

として対応する画像上の点を生成するべきなのですが、rowとcolを逆に設定していたためにおかしなことになってました。 opencvあるあるですね。

というわけで、キャリブレーションやりなおすとこうなりました。

kp='2105.02823002;0;795.46581198;0;1386.68788826;422.25675948;0;0;1'
pIntrisics = subprocess.Popen( [os.path.join(OPENMVG_SFM_BIN, "openMVG_main_SfMInit_ImageListing"),  "-i", input_dir, "-o", matches_dir, "-k", kp, "-d", camera_file_params, "-c", "3"] )

キャリブレーションのコードはこちら

    cols = 5
    rows = 7

    # コーナー検出をせずに、自前で入力する
    corners = np.array( [
        [1013, 321], [1052, 319], [1090, 318], [1129, 316], [1166, 315], [1204, 314], [1240, 313],
        [1012, 360], [1050, 358], [1088, 357], [1126, 353], [1164, 353], [1201, 352], [1237, 350],
        [1012, 395], [1050, 394], [1087, 394], [1124, 391], [1160, 389], [1197, 389], [1234, 386],
        [1011, 432], [1048, 431], [1085, 430], [1122, 427], [1158, 425], [1195, 424], [1230, 422],
        [1011, 469], [1047, 466], [1083, 465], [1120, 463], [1156, 460], [1192, 458], [1227, 456],
    ], np.float32  )

    image_points = []
    image_points.append(corners)

    # 検出した画像座標上の点に対応する3次元上の点を作成する。
    world_points = np.zeros((rows * cols, 3), np.float32)
    world_points[:, :2] = np.mgrid[:cols, :rows].T.reshape(-1, 2)
    print('world_points shape:', world_points.shape)  # world_points shape: (54, 3)

    for img_pt, world_pt in zip(image_points[0], world_points):
        print('image coordinate: {} <-> world coordinate: {}'.format(img_pt, world_pt))

    # 画像の枚数個複製する。
    imagenum = 1
    object_points = [world_points] * imagenum

    np.set_printoptions(suppress=True)
    ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(object_points, image_points, (1920, 1017),None,None)
    print("camera instristics mtx = {}".format(mtx) )

PythonからOpenCVを使ってのキャリブレーションは、こちらのサイトを参考にさせていただきました。 http://pynote.hatenablog.com/entry/opencv-camera-calibration

キャリブレーションで得たパラメータを使ってOpenMVGを叩くコードはこんな感じです。 ほぼチュートリアルのままですが。 https://gist.github.com/javoren/dd7075211776ee51ac45c06b3827d905

これを実行すると

  • imagesディレクトリの画像をもとに三次元点群を生成する
  • tutorial_out/reconstruction_globalディレクトリに結果を出力する

という感じに動きます。

できあがったデータはこんな感じです。

f:id:Catalina1344:20191007140654p:plain

前回のエントリではキャリブレーションパラメータが間違えていて、何が何やら状態でしたが、これなら何か見えてきそうな気がしますね。

openMVS形式にファイルを変換する

できあがったデータはopenMVSにもっていきたいので、プロジェクトを変換します。

openmvgのコンテナ内で次のコマンドを実行します。

cd /opt/openMVG_Build/Linux-x86_64-RELEASE
openMVG_main_openMVG2openMVS -i /mnt/work/tutorial_out/reconstruction_global/sfm_data.bin /mnt/work/openMVS/scene.mvs -o /mnt/work/scene.mvs

これで/mnt/work/scene.mvsという、OpenMVSで利用可能なファイルが完成しました。

OpenMVSの用意

openmvsのリポジトリ公式の手順をもとにdockerコンテナを作成します。 まとめるのが下手なので、一旦個別にRUNしていくだけの簡単なものです。 rootディレクトリにすべて展開しちゃってるのはご愛敬ということで。。。

# Use Ubuntu 18.04 (will be supported until April 2023)
FROM ubuntu:16.04

# Add openMVG binaries to path
ENV PATH $PATH:/opt/openMVG_Build/install/bin

# Get dependencies
RUN apt-get update && apt-get install -y \
  cmake \
  build-essential \
  graphviz \
  git \
  coinor-libclp-dev \
  libceres-dev \
  libflann-dev \
  liblemon-dev \
  libjpeg-dev \
  libpng-dev \
  libtiff-dev \
  python-minimal; \
  apt-get autoclean && apt-get clean

##Prepare and empty machine for building:
RUN apt-get -y install build-essential git mercurial cmake libpng-dev libjpeg-dev libtiff-dev libglu1-mesa-dev libxmu-dev libxi-dev
RUN hg clone https://bitbucket.org/eigen/eigen#3.2
RUN mkdir eigen_build
RUN cd eigen_build && cmake . ../eigen
RUN cd eigen_build && make && make install

# boost, opencv
RUN apt-get -y install libboost-iostreams-dev libboost-program-options-dev libboost-system-dev libboost-serialization-dev
RUN apt-get -y install libopencv-dev
RUN apt-get -y install libcgal-dev libcgal-qt5-dev

##VCGLib (Required)
RUN git clone https://github.com/cdcseacave/VCG.git vcglib
RUN apt-get -y install libatlas-base-dev libsuitesparse-dev
RUN git clone https://ceres-solver.googlesource.com/ceres-solver ceres-solver
RUN mkdir ceres_build
RUN cd ceres_build && cmake . ../ceres-solver/ -DMINIGLOG=ON -DBUILD_TESTING=OFF -DBUILD_EXAMPLES=OFF
RUN cd ceres_build && make && make install

RUN apt-get -y install freeglut3-dev libglew-dev libglfw3-dev
RUN git clone https://github.com/cdcseacave/openMVS.git openMVS
RUN mkdir openMVS_build 
RUN cd openMVS_build && cmake . ../openMVS -DCMAKE_BUILD_TYPE=Release -DVCG_ROOT="$main_path/vcglib"

RUN cd openMVS_build && make && make install

このコンテナを起動するdocker-compose.ymlは次のようになりました。

version: "3"
services:
  openmvg:
    build:
      context: ./openMVG
      dockerfile: ./Dockerfile
    image: openmvg
    container_name: "openmvg"
    tty: true
    volumes:
      - "./work/:/mnt/work" 
      - "./work/images/:/opt/openMVG_Build/Linux-x86_64-RELEASE/images"

  openmvs:
    build:
      context: ./
      dockerfile: ./dockerfile
    image: openmvs
    container_name: "openmvs"
    tty: true
    volumes: 
      - "./work/:/mnt/work"
      - "./work/images/:/openMVS_build/bin/undistorted_images"

このコンテナに入って、次のコマンドを実行していけば三次元再構成ができます。

cd /openMVS_build/bin
# 密な点群にする
./DensifyPointCloud /mnt/work/openMVS/scene.mvs

密な点群にしてみるとこうなります。 f:id:Catalina1344:20191007140818p:plain

点の数がずいぶんと増えたので、キャラクタも武器も目視確認できますね。

cd /openMVS_build/bin
# メッシュにする
./ReconstructMesh /mnt/work/openMVS/scene_dense.mvs

点のままでは3DCGソフト上で扱いにくいのでメッシュにします。

f:id:Catalina1344:20191007141559p:plain

Blenderへのインポート時点でテクスチャがはがれてしまいましたが、ひとまず読み込みできました。

試しにキャラクタ部分のみ残してみるようにしたところ、およそ20万ポリゴンでした。

感想と今後の展望

ゲームのスクリーンショットをもとに三次元再構成ができることの確認ができました。 少し手直ししてあげれば3Dプリンタで出力することもできそうです。

ただし、今回の手法は弱点も存在していて、「光沢部分が凸なポリゴンとして認識されてしまう」という課題があります。 これはゲーム画面のレンダリング時は光沢として白色になるわけですが、分析時はその白色は凸のためにできたのか、もともと白かったからなのかという判断がうまくつかないからのようです。

もう少し入力データを工夫して色々と試してみたいと思います。

また、今回利用した手法(SfM)以外にも、DeepLearningを用いた手法もあるようなので、そちらも試していきたいと思います。

それでは今回はこれくらいで。

OpenMVGを試してみる(環境構築+α)

夏が終わって秋らしい気候になってきました。秋は色々と創作意欲を刺激されるイベントが多いので、今のうちから準備をやっていきたいと思います。

OpenMVGとは

公式はこれですね。 github.com

MultiViewGeometryの略で、複数視点から三次元ジオメトリを再構成しようってやつです。

技術的なカテゴリとしてはフォトグラメトリとかSLAMに近いもののようです。

これらの細かい区別はよくわかりません。あしからず。

モチベーション

なんでこういうのに興味を持ったかというと、ARアプリと3Dプリンタを組み合わせるときに大事な技術になるのではないかという思いからです。

以前のエントリで、ゲーム中の登場アイテムを3Dプリンタで制作してARエフェクトを出してみるってのをやりました。

catalina1344.hatenablog.jp

これの最大の問題点は工数がかかりすぎという点で、趣味レベルで余暇を使ってやっているとはいえざっとこれくらいかかりました。

  • モデリング2か月
  • プリント, 仕上げ塗装 それぞれ1か月
  • ARアプリ1か月

スケールアップを考えたとき、一番ネックになりそうなのはモデリングかなと思っていて、ここをツール群を使って自動化したいなと考えました。

で、画像からの3Dモデル再構築ってどうなのだろうってことで試してみました。

もちろんゲーム中のSSを解析したりする行為は著作権やソフトウェア利用許諾に記載されているリバースエンジニアリングの禁止条項にかかる懸念はありますので、それはその問題として別途解決しておく必要はあります。

では早速try。

OpenMVG実行環境をdockerで作る

まずは環境作りからです。

ビルド環境

環境はいつものです。 WIndows10-pro上のdocker desktop for winwowsを使用します。

公式リポジトリをcloneしてきて、ビルドパラメータを修正します。 dockerfile末尾でmakeしている箇所の-jオプションを削除します。

# Build
RUN mkdir /opt/openMVG_Build; \
  cd /opt/openMVG_Build; \
  cmake -DCMAKE_BUILD_TYPE=RELEASE \
    -DCMAKE_INSTALL_PREFIX="/opt/openMVG_Build/install" \
    -DOpenMVG_BUILD_TESTS=ON \
    -DOpenMVG_BUILD_EXAMPLES=OFF \
    -DFLANN_INCLUDE_DIR_HINTS=/usr/include/flann \
    -DLEMON_INCLUDE_DIR_HINTS=/usr/include/lemon \
    -DCOINUTILS_INCLUDE_DIR_HINTS=/usr/include \
    -DCLP_INCLUDE_DIR_HINTS=/usr/include \
    -DOSI_INCLUDE_DIR_HINTS=/usr/include \
    ../openMVG/src; \
#    make -j 4;
    make;

jオプションを削除する意味

まずmakeのjオプションはジョブの個数を指定するオプションです。デフォルトの指定だと4プロセス平行に走らせるという意味です。

大雑把にいうと4CPUあればいい感じに走るわけなのですが、Docker for windowsのデフォルト設定ではコンテナに1CPUしか割り当てていません(うちの環境だけかも?)

この1CPU環境でjオプションを指定しているとコンテナごと応答なし状態になってしまったので、1プロセスでやってしまうということにしました。

起動パラメータ

また、このdockerfileのあるディレクトリの一つ上の階層にdocker-compose.ymlファイルを配置します。 openMVGのdockerfileが生成するコンテナの起動パラメータをまとめただけのものです。

version: "3"

services:
  openmvg:
    build: 
      context: ./openMVG
      dockerfile: ./Dockerfile
    image: openmvg
    container_name: openmvg
    tty: true
    volumes:
      - ./work:/mnt/work/

動作確認

チュートリアルらしいファイルが置かれているので叩いてみます。

対象ファイルは/opt/openMVG/src/software/SfM/tutorial_demo.py.inですが、そのままではパス指定がダメなので少し編集します

Linux上で編集したりするの大変なので、/mnt/workにでもコピーしてきて編集するのが楽です。(docker-composeでホスト側にマウントするよう指定した)

冒頭の部分を次のように書き換えます。

# Indicate the openMVG binary directory
#OPENMVG_SFM_BIN = "@OPENMVG_SOFTWARE_SFM_BUILD_DIR@"
OPENMVG_SFM_BIN = "/opt/openMVG_Build/Linux-x86_64-RELEASE/"

# Indicate the openMVG camera sensor width directory
#CAMERA_SENSOR_WIDTH_DIRECTORY = "@OPENMVG_SOFTWARE_SFM_SRC_DIR@" + "/../../openMVG/exif/sensor_width_database"
CAMERA_SENSOR_WIDTH_DIRECTORY = "/opt/openMVG/src/software/SfM/" + "/../../openMVG/exif/sensor_width_database"

これでOK。 実行は python tutorial_demo.py.inです。建物の画像をダウンロードしてきて、解析した結果をtutorial_outディレクトリに出してくれます。 ply形式なので、meshlabとかで見られます。

少しいじってみる(失敗)

チュートリアルのコードを見ると、GitHub上から画像データをダウンロードしてきて、それをもとにSfMをやってるということがわかります。 せっかくなので自前のデータを用意して差し替えてみましょう。 コードを次のようにしてみました。

def get_parent_dir(directory):
    return os.path.dirname(directory)


#os.chdir(os.path.dirname(os.path.abspath(__file__)))
#input_eval_dir = os.path.abspath("./ImageDataset_SceauxCastle")
## Checkout an OpenMVG image dataset with Git
#if not os.path.exists(input_eval_dir):
#  pImageDataCheckout = subprocess.Popen([ "git", "clone", "https://github.com/openMVG/ImageDataset_SceauxCastle.git" ])
#  pImageDataCheckout.wait()
#
#output_eval_dir = os.path.join(get_parent_dir(input_eval_dir), "tutorial_out")
#input_eval_dir = os.path.join(input_eval_dir, "images")
#if not os.path.exists(output_eval_dir):
#  os.mkdir(output_eval_dir)

input_eval_dir = "./images"
output_eval_dir = "./tutorial_out"

if not os.path.exists(output_eval_dir):
  os.mkdir(output_eval_dir)

input_dir = input_eval_dir
output_dir = output_eval_dir
print ("Using input dir  : ", input_dir)
print ("      output_dir : ", output_dir)

step5あたりで The input SfM_Data file "./tutorial_out/reconstruction_global/sfm_data.bin" cannot be read.と言われてしまいます。 このエラーの原因は、直前のプロセスまでに生成されているべきSFM_data.binが存在しないために発生するエラーです。

なぜsfm_dataが生成されていないかというと、今回はゲーム中の適当な画像を使ったのでexifヘッダが存在しないためでした。 どうもOpenMVGの実装上、jpegフォーマットのexifヘッダからカメラ内部パラメータを推測しているようです。 (カメラパラメータは、例えばテストデータとして使っているリポジトリにはK.txtなどといった形で記載されているものです。)

さらに少しいじってみる(少し進展した)

step1でsfmdata\jsonを生成していますが、ここでカメラ内部パラメータを与えることができます。 適当に引っ張ってきた値なので、使用する画像に合わせたパラメータに置き換える必要があります。

kp = "2905.88;0;1920;0;2905.88;1017;0;0;1"

print ("1. Intrinsics analysis")
#pIntrisics = subprocess.Popen( [os.path.join(OPENMVG_SFM_BIN, "openMVG_main_SfMInit_ImageListing"),  "-i", input_dir, "-o", matches_dir, "-d", camera_file_params, "-c", "3"] )
pIntrisics = subprocess.Popen( [os.path.join(OPENMVG_SFM_BIN, "openMVG_main_SfMInit_ImageListing"), "-i", input_dir, "-o", matches_dir, "-k", kp, "-d", camera_file_params, "-c", "3"] )
pIntrisics.wait()

これで、plyファイルが出力されるようになりました。meshlabで見てみるとこんな感じになりました。 f:id:Catalina1344:20190923131225j:plain うーん、よくわからないですね。

父の日ですね

たまには文章書かないと日本語忘れてしまいそうです。職場でも人と話することもないので。かたりぃなです。

 

ブログで技術以外のことを書くのは初めてかもしれません。どちらかというと政治&過去語りな内容。

興味のない人はそっと閉じてくださいね。

 

まず、私の父はもういません十数年前に他界しました。

そんな父は私がプログラマになるための最後の助けをしてくれました。

 

上京・進学のとき

時代は20世紀末期。就職氷河期が始まっているので大学進学したところで就職先があるかどうかもわからないご時世。

国公立ならあるいは?という選択肢もありましたが、浪人などしようものなら阪神淡路大震災の影響で悪化していた家庭環境。居場所がないのは自明でした。実家は四国なので、震災の直接的な影響はなかったのですが、親戚関連とかでいろいろあったらしいです。

 

公務員という選択肢も考えましたが、当時は就職氷河期の折。公務員の競争率は跳ね上がっていましたし、田舎なので縁故採用らしき枠がほとんどを持って行ってしまうんですね。悲しい現実です。

 

そんなこんなで、私がお金を使ってしまうと弟や妹が進学できなくなってしまう。国公立に賭けるみたいなギャンブル打つくらいなら専門学校で。と進路を決めました。

国公立に余裕で行ける学力がなかったのは自分の勉強不足だったんだろうなと思います。

専門学校となると今まで視野に入れてなかったので色々調べる必要がありました。

私がいた地方の専門学校は一族経営だったり、人脈だけで成り立ってたりと、そういう所だったので、こうするほかなかったという状況だったので場所は東京となりました。

母は大反対でしたが、父は快諾とまでは言わないまでも「やれるだけやってみ。無理なら帰ってこい」と言ってくれました。

 

上京の日は父がついてきていました。寮母さんに挨拶してから、西友で生活に必要なものを買ってくれたのを記憶しています。「バイトで頑張って貯めたみたいだけど、それは生活のためじゃなくて自分のやりたいことをやるために使いなさい。」そんなことを言ってた気がします。

 

当時の私の地方のバイト代は時給600が平均値でしたから、ほとんど溜まっていない状況でした。あの生活基盤を作ってくれたお金がなかったら、あっというまに困窮していたと思います。父に感謝です。

 

パソコン

進学と同時にパソコンを買いたかったのですが、そんなお金はどこにもありませんでした。進学後はなんとかしようとバイトしつつも試行錯誤の毎日でした。

通学時間中に本を読んで、紙にコードを書いて、学校のPCで打ち込むという生活を半年近く続けました。バイトも掛け持ちしていたので当時の睡眠時間は3時間前後だったと思います。今にしてみればよく生きてたなと。

専門学校の一年目が終わるころにはC++, DirectXくらいはいじれるようになっていましたが、やっぱりパソコンなしでは限界がありました。

ダメもとで父に電話したところ「ボーナスが少し入った。少しだけなら」と。

当時としてはなかなかのスペックの中古PCとモニタ(Gateway製, Pentium100MHz, RAM=96M)みたいなマシンでした。

おかげで制作発表会では実写を取り込んだ2D格闘ゲームを展示できて反響もありました。

反響があったというのが嬉しくて、寝る間も惜しんで色々プログラムを作ってた気がします。

父のおかげです。当時の私はまだ19歳でした。

 

成人式

もともと出るつもりはなかったのですが、アルバイト先の仲間から出たほうがいいといわれ、休みももらえたので出ることにしました。

成人式前日に実家に帰ってみると、母が封筒をくれました「待ってたよ。父さんから預かったお金、スーツ代。リクルートスーツじゃせっかくの成人式が台無しだからね」と。

成人式に多少なりともまともなスーツで参加できたのも父のおかげです。

その後も何度か実家には帰ったりはしました。

父から聞いた最後の言葉は「気をつけてな。悪いやつに騙されるなよ。お前は人が良すぎる」でした。

 

父の他界

世間がサブプライム問題とか賑わっていた時期でした。

当時の会社の同僚の結婚披露宴の最中に電話が鳴りました。父が倒れたと。

すぐ羽田から四国へ飛び、病院に着いてみると父は手術中でした。

待っている間に状況を聞いてみると、あまりよくないようでした。

一度は医大病院に運ばれたが、医者が居ないからと県立病院へ移送、一刻も早く手術をしないといけない状況なのに、ここにも医者が居ないから手術まで数時間待ち。そんな状況でした。

幸いにも手術は成功しました。

 

私は安心して東京へ戻り、次の日には再び職場で仕事をしていました。「元気になったら好物でも買って行ってやろう。一緒に酒飲んだこともなかったな」なんて呑気に考えてました。

3日後、再び電話がなりました。合併症とのこと。もうダメだと。

私は喪服を用意して再び四国へ飛びました。「すぐ息を引き取るわけではないけれども、回復の見込みは極めて低い。」そんなお医者さんからのお話でした。

私はせめてその時くらい一緒にいてやろうと一週間有給を入れました。

 

当時の私の職場は下請け企業なのでリーマンショックの余波を受けての政治争い(受注争い)が大変ですが、そんなことよりも大切なことがあると思っています。

 

親のことが好きとか嫌いとか、自分の立場がとか、会社の業績がとか。

そんなものどうでもよかった。ただ今まで助けてくれた父の最期を看取ることくらいしたかったのです。

 

有給の期間が過ぎ、母が告げました「あんた、リーマンショックの影響で大変なんだから帰りな。あとはなんとかする。」と。

強情な母なのでそれを受けて、次の日に東京に戻ることで話がついた夜。病院から電話でした。

「血圧が低下しています。ご家族や親類の方を。」

没年50歳後半でした。

 

職場に電話して忌引き休暇の連絡、葬儀屋の手配、病院の請求書の処理。

葬儀は私が喪主を務め無事に終えることができました。

火葬のボタンを押すとき「今までありがとうございました」と。

 

後悔

せめて一緒に酒くらい呑んでやればよかった。嫁に合わせてやりたかった。

そんな思いで四十九日を終え、やっと本格的に職場復帰したころでした。

やはり長期間職場を不在にすると政治的に不利になりますね。

現場としてはそんな負荷を押し付けられたと思うでしょうし、総務や人事は知ったこっちゃないという状況です。

心理的にも耐えられないと思い、退職を申し出ました。しばらく田舎で父の残してくれたものの処理をしようと考えていました。

 

ここで父の最期の言葉を思い出しておけばよかったと悔やまれます。

離職票の退職日や保険の加入などを偽装され、金額的にも精神的にもかなりの損失を被りました。

ストレスからの暴飲暴食からの胃潰瘍で出血多量となって死にかけましたが、今も私はなんとか生きてます。

 

もう10年以上前のことです。

 

個人的に思うこと

私は親があまり好きではありませんでした。。

ただ、今にして思えば、生活が苦しい中で、父は本当に必要なものを選んで私に与えてくれていたんだと思います。

父が他界したとき、葬儀屋さんからいただいた言葉に救われた気がします。

「皆さん、親にお礼してないと悔やまれます。ただね、子供が親にするお礼というのはですね、10歳まで一緒に生きるというのが最初にして最高のお礼なんですよ。10歳過ぎたら、感謝しつつ自分の道を進んでいく。それで充分なんですよ」と。

確かにそれくらいまでの父の姿が一番記憶に残っている気がします。それを過ぎると反抗期も始まりますし。

 

政治に対して思うこと

法の下の平等というのは何なのだろう?と父の他界を機に本気で考え続けています。

 

ただ、一つだけ不平等だと言えるのは父の他界です。

小泉政権のときに「地方切り捨てだ!」などと叫ばれていましたが、私は他人事のように思っていました。

地方切り捨てが行われたらどうなるのかも考えず、自分の地方がその切り捨てられる側になるなんて考えず。

そして「医者がいないから手術ができなかった」という言葉をまさか父が受けることなるなんて考えてもいませんでした。

 

父はこのことを教えてくれたのかもしれません。

 

総括

日本の政治によって私の父は命を奪われた。私は今でもそう思っています。

ただ、憎しみは何も生まない。だから私は悲しむ人が少しでも減るような社会になってほしい。そう願います。

今の日本社会を見ていると、皆が自分のことで精一杯で余裕がないなと感じています。

 

だとしたら、それは今の政治であったり、社会、働き方、会社、色々なしくみが限界を迎えているのではないか?と。

 

少し暗い話になりましたが、できることなら、全世界から苦しみが無くなって幸せになれる世界が訪れるといいなと思っています。

これを仏教の言葉で「大欲得清浄」というらしいです。意味は大きな欲は清浄を生む。

自分だけ良ければそれでよいというのではなく、もっと大きな目で物事を見てみると何か大切なものが見えてくるかもしれません。

 

私にそれを教えてくれたのは父の命でした。

 

南無大師遍照金剛