Ubuntu server 12.04にNvidia CUDAをインストールしてOpenCVのgpuモジュールを利用する
1.ドライバーのインストール
リポジトリを追加してインストール。
sudo apt-add-repository ppa:ubuntu-x-swat/x-updates
sudo apt-get update
sudo apt-get install nvidia-current
2.CUDAのインストール
CUDAの公式サイトCUDA Downloads | NVIDIA Developer Zoneから、最新のものをDLする。最新のものは11.10になっているけど、12.04に入れても大丈夫かな?
wget http://developer.download.nvidia.com/compute/cuda/5_0/rel-update-1/installers/cuda_5.0.35_linux_64_ubuntu11.10-1.run
下記コマンドにてインストール。
sudo zsh ./cuda_5.0.35_linux_64_ubuntu11.10-1.run
Agreement的なものがでるけど、よく読んで"s"ボタンでスキッp"accept"と入力。
ドライバーはインストールしているので”n”を入力、後は"y"を入力。
下記出力結果。
=========== = Summary = =========== Driver: Not Selected Toolkit: Installed in /usr/local/cuda-5.0 Samples: Installed in /usr/local/cuda-5.0/samples (pristine) and /home/===/NVIDIA_CUDA-5.0_Samples (writable) * Please make sure your PATH includes /usr/local/cuda-5.0/bin * Please make sure your LD_LIBRARY_PATH * for 32-bit Linux distributions includes /usr/local/cuda-5.0/lib * for 64-bit Linux distributions includes /usr/local/cuda-5.0/lib64:/lib * OR * for 32-bit Linux distributions add /usr/local/cuda-5.0/lib * for 64-bit Linux distributions add /usr/local/cuda-5.0/lib64 and /lib * to /etc/ld.so.conf and run ldconfig as root * To uninstall CUDA, remove the CUDA files in /usr/local/cuda-5.0 * Installation Complete Please see CUDA_Getting_Started_Guide_For_Linux.pdf in /usr/local/cuda-5.0/doc/pdf for detailed information on setting up CUDA. ***WARNING: Incomplete installation! This installation did not install the CUDA Driver. A driver of version at least 304.54 is required for CUDA 5.0 functionality to work. To install the driver using this installer, run the following command, replacing <CudaInstaller> with the name of this run file: sudo <CudaInstaller>.run -silent -driver
ここで、
Driver: Not Selected Toolkit: Installed in /usr/local/cuda-5.0 Samples: Installation Failed. Missing required libraries.
となっていて、"Missing required library libglut.so"というログが残っている場合には、
sudo ln -s /usr/lib/x86_64-linux-gnu/libglut.so.3 /usr/lib/libglut
でうまくいくらしい。
もし、glutが入ってなければ下記コマンドでインストール。
sudo apt-get install freeglut3 freeglut3-dev
*参考How to Install OpenGL/Glut libraries in Ubuntu 12.04 | Singh Gurjot
インストール後、CUDAのパスを通す。
export PATH=/usr/local/cuda-5.0/bin:${PATH} export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/usr/local/cuda-5.0/lib64:/usr/local/cuda-5.0/lib
3.CUDAサンプルのビルド
NVIDIA_CUDA-5.0_Samplesにサンプルがインストールされるらしいので、試しにビルドしてみる。
cd ~/NVIDIA_CUDA-5.0_Samples make
ここで、
/usr/bin/ld: cannot find -lcuda
と言われたので、
LIBRARY_PATH=/usr/lib/nvidia-current:$LIBRARY_PATH
を追加。
*サンプルを全部ビルドしたい場合はOpen MPI 関連のパッケージも必要。
下記コマンドでインストール。
sudo apt-get install openmpi-bin openmpi-dev
4. OpenCVでgpuモジュールをビルド
cmakeのオプションをWITH_CUDA=ONにして実行。
下記のように怒られた。
CMake Error: The following variables are used in this project, but they are set to NOTFOUND. Please set them or make sure they are set and tested correctly in the CMake files: CUDA_nvcuvid_LIBRARY (ADVANCED) linked by target "opencv_gpu" in directory /home/XXX/opencv/OpenCV-2.4.3/modules/gpu -- Configuring incomplete, errors occurred!
下記のように対応。
sudo ln -s /usr/lib/nvidia-current/libnvcuvid.so /usr/lib/libnvcuvid.so
*参考opencv-users - [CUDA] cmake error when when running WITH_CUDA on linux
最終的な実行コマンドは下記の通り。
cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/usr/local/opencv -D WITH_TBB=ON -D BUILD_NEW_PYTHON_SUPPORT=ON -D WITH_V4L=ON -D INSTALL_C_EXAMPLES=ON -D INSTALL_PYTHON_EXAMPLES=ON -D BUILD_EXAMPLES=ON -D WITH_QT=ON -D WITH_OPENGL=ON WITH_CUDA=ON CUDA_nvcuvid_LIBRARY=/usr/local/cuda-5.0 ..
あとは、
make
make install
でインストール完了。
と思ったら、下記エラーが発生。
[ 22%] Built target opencv_ts Linking CXX executable ../../bin/opencv_perf_core ../../lib/libopencv_core.so.2.4.3: error: undefined reference to 'cuDeviceGetAttribute' collect2: ld はステータス 1 で終了しました make[2]: *** [bin/opencv_perf_core] エラー 1 make[1]: *** [modules/core/CMakeFiles/opencv_perf_core.dir/all] エラー 2 make: *** [all] エラー 2
取り急ぎ、CMakeCache.txt内のCUDA_CUDA_LIBRARY:FILEPATHを
CUDA_CUDA_LIBRARY:FILEPATH=/usr/lib/nvidia-current/libcuda.so
のように変更。
*参考 Compiling OpenCV 2.4.3 on Ubuntu 12.10 « AmmarkoV `s Personal Website
動かしてみる
ちょうどいいサンプルが、sample/gpu/hog.hppにあったのでビルドしてみる。
g++ hog.cpp `/usr/bin/pkg-config --cflags --libs opencv`
このサンプルはCPUとGPUの切り替えができる。
大体4倍ぐらい性能差が出ました。
*ここを参考に参考にさせて頂きました。
Nvidia drivers for Ubuntu 12.10 Quantal/Ubuntu 12.04 Precise/Ubuntu 11.10 Oneiric Ocelot/Linux Mint ~ Noobs on Ubuntu and Windows, HD Wallpapers, Tutorials
Flaskでpostされたjsonを受け取る
Flaskのrequestでデータを受け取るには
- request.data
- request.form
- request.json
等がある。
それぞれ、Content-Typeで受け取り方が切り替わるらしい。
request.jsonはContent-Typeをapplication/jsonに設定していれば
自動的にオブジェクトへパースしてデータを返してくれる。
POSTするデータはJSON.stringifyしてないと400エラーが出て怒られる。
なので、Javascript側ではajaxの設定を下記のようにする。
- Content-Typeをapplication/jsonに
- データはJSON.stringifyで文字列に
例)
$.ajax( { url:'/api/test', type:'POST', data:JSON.stringify(data), dataType: 'json', contentType: 'application/json' }) .done(function(data, textStatus, jqXHR ){ console.log("done"); console.log(data); }) .fail(function(jqXHR, textStatus, errorThrown){ console.log("failed"); });;
Python側では念の為にヘッダーのチェックを行う。
@app.route('/api/test', methods=['POST']) def face_info(): if request.headers['Content-Type'] != 'application/json': print(request.headers['Content-Type']) return flask.jsonify(res='error'), 400 print request.json return flask.jsonify(res='ok')
Android string.xmlの分割と多言語化
多言語化はフォルダ名をvalues-XX(XXは国コード"ja"とか"cn"とか)にして、同じようなリソースを置くことでAndroidが勝手に入れ替えてくれる。
また、言語ファイルをよく記述しているres/values/string.xmlは、他の名前で定義しても利用可能。
なので、string.xmlが大きくなりそうになったらファイルを分割するとスッキリする。
例えば、string_test.xml内で"hello"という文字列を定義すると、R.string.helloでアクセスできるようになる。
下記はサンプル。
res/values/string_test.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="hello">hello!</string> </resources>
res/values-ja/string_test.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="hello">こんにちわ!</string> </resources>
利用例)
Log.d("debug", getString(R.string.hello));
これで言語が日本語の際は"こんにちは!"、それ以外は"hello"と出力される。
AndroidのLogCat出力用テンプレート(メソッド名とか行番号とか表示したいよ!)
メソッド名とか行番号とかLogCatに出力したいなーと、ぐぐってみたらここを読んで、おぉー(・・)と思い作ってみました。
Eclipseのテンプレ設定にすると非常に便利かも!
下記コード。
private static final boolean ENABLE_LOG = true; private static void logd(String msg) { if(ENABLE_LOG) { Log.d(getTag(), msg); } } private static final String getTag() { StackTraceElement ste = Thread.currentThread().getStackTrace()[4]; String className = ste.getClassName(); className = className.substring(className.lastIndexOf(".") + 1); String methodName = ste.getMethodName(); int lineNum = ste.getLineNumber(); return className + "." + methodName + ":" + lineNum; }
logd()を使うと、
HogeActivity.foobar:11
のようなタグが出力されます。
これをEclipseの設定で下記のようにコピペすると、Classを作成した時にテンプレ付きで作成されます。
テンプレにすることの難点は、すべてのクラスにコレがくっついてくることです(´・ω・`)
まぁ消せばOKなんですけどね。
やっぱりコピペツールに登録しようかなー
なにかいい方法があれば教えて下さい
iOSで通信する際のUser-Agentを組み立てる
こういうフォーマットのUAがつくりたい!
<アプリ名>/
例)
MyApp/1.0 (iPhone5,2; 6.0; iOS; ja)
//format: MyApp/1.0 (iPhone5,2; 6.0; iOS; ja) - (NSString*)buildUserAgent { // モデル名取得 NSString *modelname = [self platformName]; // osのバージョン取得 float iOSVersion = [[[UIDevice currentDevice] systemVersion] floatValue]; // 言語設定取得 NSArray *langs = [NSLocale preferredLanguages]; //取得した配列から先頭の文字列を取得(先頭が現在の設定言語) NSString *currentLanguage = [langs objectAtIndex:0]; NSString* userAgent = [NSString stringWithFormat:@"MyApp/1.0 (%@; %0.2f; iOS; %@)", modelname, iOSVersion, currentLanguage]; return userAgent; } // デバイスの情報を返す - (NSString *)platformName { size_t size; sysctlbyname("hw.machine", NULL, &size, NULL, 0); char *machine = malloc(size); sysctlbyname("hw.machine", machine, &size, NULL, 0); NSString *platformName = [NSString stringWithCString:machine encoding:NSUTF8StringEncoding]; free(machine); return platformName; }
ちょっと決め打ち多いね^^;
あとはこの文字列をNSURLConnectionなりAFHTTPClientなりにセットしよう!
Macで"dyld: Library not loaded:"が出たら。。。
dyld: Library not loaded: lib/..... Referenced from: /Users/......./hoge Reason: image not found
これを.zshrcに書いとこう。
export DYLD_LIBRARY_PATH=/path/to/lib:$DYLD_LIBRARY_PATH
これで動くはず。
Xcodeでビルドした時の”duplicate symbols”エラーを回避する
FacebookSDKやAWSiOSSDKなど、いろんなライブラリをブチ込みまくると
ld: - duplicate symbols for architecture ---
と言うエラーがよく出る。
重複して使われているライブラリ(SBJsonとか)が出るとこのようなエラーがでてしまう。
くっそ!
そしてググりまくって回避方法を見つけました(`・ω・´)
今回はFacebookとAWSの.frameworkの衝突を回避する例を紹介します。
まず普通にビルドすると、
duplicate symbol _OBJC_CLASS_$_SBJsonParser in: .../Build/Products/Debug-iphoneos/libFacebook SDK.a(SBJsonParser.o) . . . . . XcodeWorkspace/aws-ios-sdk-1.4.3/AWSiOSSDK.framework/AWSiOSSDK(SBJsonWriter.o) ld: 6 duplicate symbols for architecture armv7 clang: error: linker command failed with exit code 1 (use -v to see invocation)
お、おぅ、となります。
○SBJsonParser.o
○SBJsonWriter.o
これらがFacebookSDKとAWSのSDKで使われてるから怒られる。たぶん。
なので、AWSiOSSDKの方からこれらを消してあげます。
まず下記コマンドで、どのアーキテクチャ用になってるかチェック。
$lipo -info AWSiOSSDK Architectures in the fat file: AWSiOSSDK are: armv7 (cputype (12) cpusubtype (11)) i386
armv7とi386のアーキテクチャ用にビルドされてるそうです。
下記コマンドで分解。
$lipo -thin armv7 AWSiOSSDK -output AWSiOSSDK_armv7 $lipo -thin i386 AWSiOSSDK -output AWSiOSSDK_i386
.oファイル検索
$ar -t AWSiOSSDK_armv7|grep SBJson SBJsonParser.o SBJsonStreamParser.o SBJsonStreamParserAccumulator.o SBJsonStreamParserAdapter.o SBJsonStreamParserState.o SBJsonStreamWriter.o SBJsonStreamWriterAccumulator.o SBJsonStreamWriterState.o SBJsonTokeniser.o SBJsonUTF8Stream.o SBJsonWriter.o
あったあった。
目的のファイル削除。
ar -dv AWSiOSSDK_armv7 SBJsonParser.o SBJsonWriter.o ar -dv AWSiOSSDK_i386 SBJsonParser.o SBJsonWriter.o
合体!
lipo -create AWSiOSSDK_armv7 AWSiOSSDK_i386 -output AWSiOSSDK
これでビルドすると。。。。
Building...... (´・ω・`)
Succeed!いぇーす!おめでとう!
*追記
armv7sのライブラリ抽出は下記で可能。
xcrun -sdk iphoneos lipo -thin armv7s AWSiOSSDK -output AWSiOSSDK_armv7s