stMind

about Arsenal, Arsene Wenger, Tech, Computer vision and Machine learning

kinect生産終了のニュースに触れて

www.nikkei.com

www.fastcodesign.com

トータルで全世界3500万台、発売60日間で800万台売れたということでギネス記録にもなったキネクトが生産終了となるようです。

キネクトといえば、RGB-D画像からRandom Forestで部位を推定する手法がCVPR2010でベストペーパーにもなりました。

www.microsoft.com

部位推定の手法も、2013年にDeepPoseがGoogleのチームによって発表された辺りからディープラーニングベースの手法が主流になって、ECCV2017のBest demoにもなったPart Affinity Fieldによる複数人リアルタイム姿勢推定がOpenPoseとしてソフトウェアが公開されたこともあって、製品レベルに一気に進化した感がありますね。

キネクトの論文で1st authorのJamie shottonさんのページを見てみるとHoloLensのチームをリードしているということだし、その他のキネクトチームのメンバーもCortanaやWindows Hello Face Recognitionのチームに移っているということなんで、キネクトの世界から進化してHoloLensを中心にしたMRの世界構築にシフトしたということが改めて発信されたということかなという感じがしました。

I lead the HoloLens Science team at Microsoft in Cambridge. My research is focused at the intersection of computer vision, AI, machine learning, and graphics, with particular emphasis on systems that allow people to interact naturally with computers.

www.microsoft.com

www.microsoft.com

インストール済みのcudnnのバージョン確認

#include <cudnn.h>
#include <iostream>

int main(int argc, char** argv) {
    std::cout << "CUDNN_VERSION: " << CUDNN_VERSION << std::endl;
    return 0;
}
$ nvcc cudnn_version.cpp -o cudnn_version
$ ./cudnn_version
CUDNN_VERSION: 5110

このプログラムはこのIssueで知ったのですが、CUDNNってNVIDIAのサイトからダウンロードした後はディレクトリにコピーするだけなので、どのバージョンをインストールしたのかぱっと見はわからなくなってしまうので、パスの通った所に実行ファイルをおいておくと何気に便利かもしれません。

failed to install chainer with cuda 8.0 / cuDNN v6 · Issue #2501 · chainer/chainer · GitHub

flickr8k dataset

Deep Visual-Semantic Alignments for Generating Image Descriptions

image caption用のflickr8k datasetは、アノテーションとVGGの特徴量は上記リンクからダウンロード可能ですが、対応する画像自体は別途ダウンロードする必要があります。各画像のダウンロード先URLをFlickr Services: Flickr API: flickr.photos.getSizesを使って取得して、バッチ的に取得するスクリプトを書きました。8k枚の画像をダウンロードするので、すごい時間がかかるのが難点ですが...

github.com

上手に考えるための引き出しを増やす

新しい分かり方

新しい分かり方

新しいアイデアを必要とする状況というのは意外と多く、その度に同じような事しか考えられず、自分はアイデアを考える才能がないなあと思ったりする人もいるかもしれないけれど、それって才能の問題ではなく、実は考える技術が下手なだけなのかもしれない。事実をそのまま受け取るのではなくて、差分を見つけたり、異なる立場から解釈してみたり、言うは易く行うは難し、そんな考え方のテクニックを何とも不思議な作品を通して体験する事ができる本。

www.masahicom.com

コンパイルエラーで個人的にわりとよく使うコマンド

OSX El Capitan 10.11.6です。

locate, export

例えば、とあるmakeを実行したらwchar.hが見つからないと言われました。

$ make
g++ libRegionBPP/libRegionBPP.cpp -c -std=c++98 -pedantic -W -Wall -fopenmp -O3 -fPIC
In file included from /usr/local/Cellar/gcc@4.9/4.9.3/include/c++/4.9.3/bits/postypes.h:40:0,
                 from /usr/local/Cellar/gcc@4.9/4.9.3/include/c++/4.9.3/iosfwd:40,
                 from /usr/local/Cellar/gcc@4.9/4.9.3/include/c++/4.9.3/ios:38,
                 from /usr/local/Cellar/gcc@4.9/4.9.3/include/c++/4.9.3/ostream:38,
                 from /usr/local/Cellar/gcc@4.9/4.9.3/include/c++/4.9.3/iostream:39,
                 from libRegionBPP/libRegionBPP.cpp:29:
/usr/local/Cellar/gcc@4.9/4.9.3/include/c++/4.9.3/cwchar:44:19: fatal error: wchar.h: No such file or directory
 #include <wchar.h>
                   ^
compilation terminated.
make: *** [libRegionBPP.a] Error 1

インクルードディレクトリにパスが通ってないのでしょう。まずは、wchar.hの場所を探して、そこにパスを通すことにします。

$ locate wchar.h
...
/usr/include/wchar.h
...
$ export CPATH=$CPATH:/usr/include

設定出来たらもう一度makeです。

$ make
g++ libRegionBPP/libRegionBPP.cpp -c -std=c++98 -pedantic -W -Wall -fopenmp -O3 -fPIC
In file included from /usr/include/string.h:176:0,
                 from libRegionBPP/libRegionBPP.cpp:34:
...
/var/folders/bq/xh66g4d17rn1xkjsmj4md4qm0000gn/T//cczqQzWW.s:3576:11: note: change section name to "__const"
        .section __DATA,__const_coal,coalesced
                 ^      ~~~~~~~~~~~~
ld: library not found for -lSystem
collect2: error: ld returned 1 exit status
make: *** [prog_dSP] Error 1

locate, export, ln

ライブラリが見つからないのだが、これもライブラリディレクトリにパスが通ってないのでしょう。

$ locate libSystem.dylib
...
/usr/lib/libSystem.dylib
$ export LIBRARY_PATH=$LIBRARY_PATH:/usr/lib
$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib

再度makeしてみるも同じエラーになって、/usr/local/libも加えたりしてみたものの解消せず。根本的な解決になってないのだけど、makeファイルの中でカレントディレクトリが動的ライブラリの検索パスになっているので、シンボリックリンクをカレントディレクトリに作成することに。

$ ln -s /usr/lib/libSystem.dylib libSystem.dylib

otool

まだまだmakeは続く。で、ここでは、これもよくみるSymbol not found

$ make
...
/Applications/MATLAB_R2015a.app/bin/mex -v -cxx CC='g++' CXX='g++' LD='g++' -output structuredPrediction structuredPrediction.o -L. -lSPRegion -lDH -lRegionBPP -lgomp
dyld: Symbol not found: __ZN5boost13log2_mt_posix10basic_coreIcE11open_recordERKNS0_19basic_attribute_setIcEE
  Referenced from: /Applications/MATLAB_R2015a.app/bin/maci64/libmwfl.dylib
  Expected in: /usr/local/lib/libboost_log.dylib
 in /Applications/MATLAB_R2015a.app/bin/maci64/libmwfl.dylib
/Applications/MATLAB_R2015a.app/bin/mex: line 365: 87163 Trace/BPT trap: 5       $MATLAB/bin/maci64/mex $args
make: *** [structuredPrediction.mexa64] Error 133

otoolでlibmwfl.dylibの依存関係を調べて、

$ otool -L /Applications/MATLAB_R2015a.app/bin/maci64/libmwfl.dylib 
/Applications/MATLAB_R2015a.app/bin/maci64/libmwfl.dylib:
    @rpath/libmwfl.dylib (compatibility version 0.0.0, current version 0.0.0)
    @rpath/libcrypto.1.0.0.dylib (compatibility version 1.0.0, current version 1.0.0)
    @rpath/libmwresource_core.dylib (compatibility version 0.0.0, current version 0.0.0)
    @rpath/libmwi18n.dylib (compatibility version 0.0.0, current version 0.0.0)
    @rpath/libmwMATLAB_res.dylib (compatibility version 0.0.0, current version 0.0.0)
    @rpath/libboost_date_time.dylib (compatibility version 0.0.0, current version 0.0.0)
    @rpath/libboost_filesystem.dylib (compatibility version 0.0.0, current version 0.0.0)
    @rpath/libboost_log.dylib (compatibility version 0.0.0, current version 0.0.0)
    @rpath/libboost_regex.dylib (compatibility version 0.0.0, current version 0.0.0)
    @rpath/libboost_serialization.dylib (compatibility version 0.0.0, current version 0.0.0)
    @rpath/libboost_signals.dylib (compatibility version 0.0.0, current version 0.0.0)
    @rpath/libboost_system.dylib (compatibility version 0.0.0, current version 0.0.0)
    @rpath/libboost_thread.dylib (compatibility version 0.0.0, current version 0.0.0)
    @rpath/libtbb.dylib (compatibility version 0.0.0, current version 0.0.0)
    /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)

rpathになってて、どこのライブラリがリンクされてるかはわからなかったけど、よくよくエラーを見てみると、/Applications/MATLAB_R2015a.app/bin/maci64/libmwfl.dylibなのに、/usr/local/lib/libboost_log.dylibが使われているから?locateでlibboost_log.dylibの場所を探す。

$ locate libboost_log.dylib
/Applications/MATLAB_R2015a.app/bin/maci64/libboost_log.dylib
/usr/local/Cellar/boost/1.57.0/lib/libboost_log.dylib
/usr/local/Cellar/boost/1.59.0/lib/libboost_log.dylib
/usr/local/Cellar/boost/1.64.0_1/lib/libboost_log.dylib
/usr/local/lib/libboost_log.dylib

そういえば、/usr/local/libをLD_LIBRARY_PATHに設定してしまってたな。/usr/local/libは外して、makeするとようやくコンパイル出来た。

まとめ

これだけでは解決しないことも多いけど、locate, export, ln, otoolくらいで出来る場合も多い印象です。

openposeのjsonを解析する

昨日は、ナチョがウェストブロム戦で見せた奇跡のクリアをopenposeで関節推定してみました。openposeは、関節位置をファイル出力するオプションを用意しているので、jsonで出力して黒背景に関節位置を描画しましたが、その時の解析手順を簡単にまとめておきます。

jsonファイル出力

openpose実行時にwrite_keypoint_jsonを指定します。

$ ./build/examples/openpose/openpose.bin --image_dir ~/data/nacho --write_keypoint_json ~/data/results

ファイルの中身はこんな感じ。pose_keypointsが関節位置で、people以下に検出した人数分が出力されます。

{
        "version":1.0,
        "people":[
        {
            "pose_keypoints":[
                247.668,514.465,0.89905,247.702,527.27,0.87725,236.549,527.306,0.878132,233.307,541.693,0.918291,236.415,544.831,0.709778,258.863,527.235,0.795694,263.66,540.037,0.772329,269.998,554.436,0.744358,246.054,556.101,0.807442,246.055,575.247,0.484067,0,0,0,258.864,556.007,0.797664,260.464,573.657,0.435004,266.807,583.267,0.163514,246.067,511.293,0.856283,249.24,509.715,0.886759,241.254,514.496,0.671889,250.916,514.453,0.700287
            ],
            "face_keypoints":[
                
            ],
            "hand_left_keypoints":[
                
            ],
            "hand_right_keypoints":[
                
            ]
        }
    ]
}

pose_keypointsは(x座標, y座標, 信頼度) x 関節数18で、54個の値が含まれています。それから、関節位置の順番ですが、 openpose/poseParameters.hpp at master · CMU-Perceptual-Computing-Lab/openpose · GitHubに定義された通り(POSE_COCO_BODY_PARTS)になっていて、backgroundは関節位置には含まれませんので注意。さらに、関節位置の結合順序は、POSE_COCO_PAIRSに定義されてます。親切。

pythonjsonをパース

pythonは3.6.1です。シンプルにやると、

  • jsonをload
  • 検出された人数分のループ
    • 関節の全ペアのループ
    • ペアをcv2.lineで描画

たまに関節位置が求められなくて信頼度0.0になっているところだけ注意する必要があります。

import json
import numpy as np
import cv2

# jsonのロード
with open('nacho_0_keypoints.json', 'r') as f:
    data = json.load(f)

# 黒背景画像の用意
img_ = cv2.imread('original.jpg')
img = np.zeros_like(img_)

# 関節毎の描画色
colors = [(255.,     0.,    85.), (255.,     0.,     0.), (255.,    85.,     0.), (255.,   170.,     0.), (255.,   255.,     0.), (170.,   255.,     0.), (85.,   255.,     0.), (0.,   255.,     0.), (0.,   255.,    85.), (0.,   255.,   170.), (0.,   255.,   255.), (0.,   170.,   255.), (0.,    85.,   255.), (0.,     0.,   255.), (255.,     0.,   170.), (170.,     0.,   255.), (255.,     0.,   255.), (85.,     0.,   255.)]

# 検出された全員について
for d in data['people']:
     kpt = np.array(d['pose_keypoints']).reshape((18, 3))
     # 関節位置の全ペアについて
     for p in pairs:
         pt1 = tuple(list(map(int, kpt[p[0], 0:2])))
         c1 = kpt[p[0], 2]
         pt2 = tuple(list(map(int, kpt[p[1], 0:2])))
         c2 = kpt[p[1], 2]
         # 信頼度0.0の関節は無視
         if c1 == 0.0 or c2 == 0.0:
             continue
         # 関節の描画
         color = tuple(list(map(int, colors[p[0]])))
         img = cv2.line(img, pt1, pt2, color, 7)

cv2.imshow('nacho', img)

参照

以上のことは、下記を参照しています。

github.com

決定的瞬間のPose Estimation by OpenPose

これが誰か分かったあなたは立派なグーナーです。

f:id:satojkovic:20170930221642j:plain

答えはこちら。

'I was in the right place at the right time' | Interview | News | Arsenal.com