2013年6月30日日曜日

CPPを本格的に始める

データ型を重視した言語。

基本データ型



  1. int 整数型 4byte
  2. float 単精度浮動小数点型 4byte
  3. double 倍精度浮動小数点型 8byte
  4. char 文字型 1byte

コンパイルツール:cl


ex)
cl /c HelloWorld.c

/cはコンパイルのみ行うオプション。自動リンクを行わない。

リンカー:link 


書式:link オブジェクトファイル1 2 … N /OUT:EXEファイル名

プログラムの実行に必要なオブジェクトファイルが指定されていないと、以下のようにエラーとなる。

ex)
HelloWorld.obj : error LNK2019: 未解決の外部シンボル _printf が関数 _main で参照
されました。
LINK : error LNK2001: 外部シンボル "_mainCRTStartup" は未解決です。
HelloWorld.exe : fatal error LNK1120: 2 件の未解決の外部参照


objのシンボルテーブルを確認すると、何が足りないのか発見できる。


オブジェクトファイルの内容確認:dumpbin


ex)
dumpbin HelloWorld.obj /SYMBOLS

COFF SYMBOL TABLE
000 00CEEB9B ABS    notype       Static       | @comp.id
001 80000191 ABS    notype       Static       | @feat.00
002 00000000 SECT1  notype       Static       | .drectve
    Section length   2F, #relocs    0, #linenums    0, checksum
004 00000000 SECT2  notype       Static       | .debug$S
    Section length   68, #relocs    0, #linenums    0, checksum
006 00000000 SECT3  notype       Static       | .data
    Section length    D, #relocs    0, #linenums    0, checksum 9806FD4
008 00000000 SECT3  notype       Static       | $SG2940
009 00000000 SECT4  notype       Static       | .text
    Section length   14, #relocs    2, #linenums    0, checksum F829D91
00B 00000000 UNDEF  notype ()    External     | _printf
00C 00000000 SECT4  notype ()    External     | _main

上の_printfがUNDEFになっている。これが発見できなかったシンボル。


EXEファイルのスタートアップルーチン

スタートアップルーチン:_mainCRTStartup
EXEファイルの実行開始位置。main関数の呼び出し元。

以下で内容を確認できる。

C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\crt\src\crt0.c

この中で、_mainCRTStartupが__mainCRTStartupを呼び出し、_tmainを呼び出していることがわかる。引数は、mainの引数と同じ、引数の個数、コマンドライン引数の配列、環境変数の配列


規定のライブラリリンク

C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\lib\libcmt.lib
安全のために、上記libを任意のディレクトリにコピーしたあと、下記を実行すると、temp.txtにデフォルトオブジェクトの一覧を記述できる。

lib libcmt.lib /LIST:temp.txt
この中に、printf.objなどの普段何気なく使用するシンボルが並んでいる。

このようにlinkし、エラーとなったオブジェクトをlinkに加えと繰り返すことでリンクを完了させることができる。


次はEXEファイルの構成。


2013年6月21日金曜日

動画の輝度調整 ffmpeg

映像を明るくしたり暗くしたり、はっきりした色に調整する。

vf eq=brightness:contrast

brightness は輝度 -100 から 100 まで +1毎にRGBが2程度大きくなり明るくなる。
contrast はコントラスト比 -100 から 100 まで 配信用途では特に変更しない。

ffmpeg の出力例
ffmpeg -i in.mp4 vf mp=eq=3:0 out.mp4

2013年6月19日水曜日

OpenCV C++ のKeyPoint

特徴点情報を格納するeyPoint、以下の様な情報を保持します。

KeyPointメンバ 説明
pt 座標を表す構造体
size 検出時のBoxフィルタサイズ
angle 度単位で表される特徴方向
response 特徴の強さ
octave 検出されたオクターブ

2013年6月16日日曜日

phpからredisへアクセスする

ここでは、ローカルのredisにアクセスしてみます。

$redis = new Redis();
$redis->pconnect('127.0.0.1', 6379);
$redis->set('hello','world');
$hello = $redis->get('hello');

これだけで、$helloにredisから取得したhelloのvalueを代入出来ます。
簡単で素晴らしい。

2013年6月15日土曜日

redisのインストールと基本

redisは永続化可能なインメモリKVSの一種。
インストールしてみましょう。

# redis用のユーザーとディレクトリを追加
groupadd redis
useradd redis -g redis -M -s /sbin/nologin

mkdir -p /var/redis/{data,tmp}
mkdir -p /var/run/redis
mkdir -p /var/log/redis

chown -R redis:redis /var/redis/ /var/run/redis /var/log/redis

# Redisをダウンロードしてインストール
wget http://redis.googlecode.com/files/redis-2.6.12.tar.gz

tar zxvf redis-2.6.12.tar.gz
cd redis-2.6.12
make && make install

完了すると以下のコマンドが使えるようになります。

redis-check-aof   redis-cli
redis-benchmark   redis-check-dump  redis-server

redis-server
redisサーバ起動

サーバを起動するコマンドです。実行するとコンソールを呼び出せるようになります。

                _._
           _.-``__ ''-._
      _.-``    `.  `_.  ''-._           Redis 2.6.12 (c6d4084b/0) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._
 (    '      ,       .-`  | `,    )     Running in stand alone mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379
 |    `-._   `._    /     _.-'    |     PID: 3166
  `-._    `-._  `-./  _.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |           http://redis.io
  `-._    `-._`-.__.-'_.-'    _.-'
 |`-._`-._    `-.__.-'    _.-'_.-'|
 |    `-._`-._        _.-'_.-'    |
  `-._    `-._`-.__.-'_.-'    _.-'
      `-._    `-.__.-'    _.-'
          `-._        _.-'
              `-.__.-'
強制終了は Ctrl + C :データ保存されないこ多いので、redis-cliから終了しましょう。

redis-cli
コンソール呼び出し

サーバのシャットダウンはコンソールから shutdown するとデータ永続化されるので、こちらを
使いましょう。


扱えるデータ型は主に以下。


  • string
  • list
  • set
  • sorted-set
  • hash
いくつか見ていきましょう。

単純な文字列型を挿入、取得。

redis 127.0.0.1:6379> set test value
OK
redis 127.0.0.1:6379> get test
"value"
複数登録するときは、
redis 127.0.0.1:6379> mset test value name masazblog
OK
redis 127.0.0.1:6379> mget test name
1) "value"
2) "masazblog"

型を取得。

redis 127.0.0.1:6379> type test
string

カウンターを使う。

redis 127.0.0.1:6379> incr counter
(integer) 1
redis 127.0.0.1:6379> incr counter
(integer) 2
redis 127.0.0.1:6379> get counter
"2"
この数値計算は、DBデータにもそのまま使えます。
redis 127.0.0.1:6379> set score 111
OK
redis 127.0.0.1:6379> get score
"111"
redis 127.0.0.1:6379> incr score
(integer) 112
redis 127.0.0.1:6379> incrby score 10
(integer) 122
redis 127.0.0.1:6379> decr score
(integer) 121
redis 127.0.0.1:6379> decrby score 20
(integer) 101

key一覧の表示(正規表現が使えます)

redis 127.0.0.1:6379> keys *
1) "test"
2) "name"
3) "score"
4) "sroce"
redis 127.0.0.1:6379> keys s*
1) "score"
2) "sroce"


存在確認

redis 127.0.0.1:6379> exists score
(integer) 1 ←ある
redis 127.0.0.1:6379> exists tttt
(integer) 0 ←ない

期限付きkey
redis 127.0.0.1:6379> set age 24
OK
redis 127.0.0.1:6379> expire age 8 ←keyの有効期間8秒
(integer) 1
redis 127.0.0.1:6379> exists age
(integer) 1
redis 127.0.0.1:6379> exists age ←8秒すぎると無効
(integer) 0

List型 [key] [value]


追加:(l/r)push ←lは左から、rは右から
削除:(l/r)pop ←lは左から、rは右から

redis 127.0.0.1:6379> rpush mycolor pink ←末尾に追加していく
(integer) 1
redis 127.0.0.1:6379> rpush mycolor green
(integer) 2
redis 127.0.0.1:6379> rpush mycolor red
(integer) 3
redis 127.0.0.1:6379> rpush mycolor yellow
(integer) 4
redis 127.0.0.1:6379> rpush mycolor blue
(integer) 5
redis 127.0.0.1:6379> rpush mycolor purple
(integer) 6
redis 127.0.0.1:6379> lrange mycolor 0 5 ←要素の添字は0から。添字を指定して取得。
1) "pink"
2) "green"
3) "red"
4) "yellow"
5) "blue"
6) "purple"
redis 127.0.0.1:6379> lrange mycolor 0 -1 ←modの-1で指定することも可能。
1) "pink"
2) "green"
3) "red"
4) "yellow"
5) "blue"
6) "purple"
要素の削除
redis 127.0.0.1:6379> lrange mycolor 0 -1
1) "pink"
2) "green"
3) "red"
4) "yellow"
5) "blue"
redis 127.0.0.1:6379> lpop mycolor ←左端の要素削除
"pink"
redis 127.0.0.1:6379> lrange mycolor 0 -1
1) "green"
2) "red"
3) "yellow"
4) "blue"
redis 127.0.0.1:6379> lindex mycolor 2
"yellow"
redis 127.0.0.1:6379> ltrim mycolor 0 2
OK
redis 127.0.0.1:6379> lrange mycolor 0 -1
1) "green"
2) "red"
3) "yellow"


Set型

sadd:追加
srem:削除

一覧:smembers

和集合:sunion
積集合sinter
差集合:sdiff

redis 127.0.0.1:6379> sadd myset1 a
(integer) 1
redis 127.0.0.1:6379> sadd myset1 b
(integer) 1
redis 127.0.0.1:6379> sadd myset1 c
(integer) 1
redis 127.0.0.1:6379> smembers myset1
1) "c"
2) "b"
3) "a"
redis 127.0.0.1:6379> sadd myset1 d
(integer) 1
redis 127.0.0.1:6379> smembers myset1
1) "c"
2) "b"
3) "d"
4) "a"
redis 127.0.0.1:6379> srem myset1 d
(integer) 1
redis 127.0.0.1:6379> smembers myset1
1) "c"
2) "b"
3) "a"
redis 127.0.0.1:6379> sadd myset2 b
(integer) 1
redis 127.0.0.1:6379> sadd myset2 c
(integer) 1
redis 127.0.0.1:6379> sadd myset2 d
(integer) 1
redis 127.0.0.1:6379> sadd myset2 e
(integer) 1
redis 127.0.0.1:6379> smembers myset1
1) "c"
2) "b"
3) "a"
redis 127.0.0.1:6379> smembers myset2
1) "c"
2) "b"
3) "e"
4) "d"
redis 127.0.0.1:6379> sunion myset1 myset2
1) "b"
2) "c"
3) "e"
4) "a"
5) "d"
redis 127.0.0.1:6379> sinter myset1 myset2
1) "c"
2) "b"
redis 127.0.0.1:6379> sdiff myset1 myset2
1) "a"
redis 127.0.0.1:6379> sunionstore myunion myset1 myset2
(integer) 5
redis 127.0.0.1:6379> smembers myunion
1) "b"
2) "c"
3) "e"
4) "a"
5) "d"

すごい簡単で便利。
最後にDB選択と永続化、トランザクション的なものについて見て行きましょう。

データベース選択

0~15が用意されている。
redis 127.0.0.1:6379> select 0
redis 127.0.0.1:6379> select 1


データの保存

redis 127.0.0.1:6379> bgsave

データの保存先

redis起動ディレクトリの dump.rdb

データの保存を随時行いたい

AOF(同期書き込みサポート)を保存することになります。redis.confに以下の設定を行います。
appendonly yes
100倍くらい遅くなるので、安全を優先したい場合のみ使用しましょう。


トランザクション的なもの
複数の処理をまとめて行う。途中の終了した時のロールバックは無し。

multi
処理
処理

exec / discard

redis 127.0.0.1:6379> multi
OK
redis 127.0.0.1:6379> incr counter
QUEUED
redis 127.0.0.1:6379> incr visitor
QUEUED
redis 127.0.0.1:6379> exec
1) (integer) 1
2) (integer) 1
redis 127.0.0.1:6379> multi
OK
redis 127.0.0.1:6379> incr counter
QUEUED
redis 127.0.0.1:6379> incr visitor
QUEUED
redis 127.0.0.1:6379> discard
OK
redis 127.0.0.1:6379> mget counter visitor
1) "1"
2) "1"




2013年6月12日水曜日

OpenCVのインストールディレクトリを変更する

OpenCVのインストールディレクトリをデフォルトから変更する方法。

今回は「/opt/lib/x86_64/opencv」に変更します。

2.4.3と2.4.5では以下のコマンドで行けます。

$ cmake -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/opt/lib/x86_64/opencv -D BUILD_PYTHON_SUPPORT=ON -D WITH_TBB=ON -D WITH_GTK=ON .

2013年6月9日日曜日

sambaでシンボリックリンク先も辿りたいとき

/etc/samba/smb.confに以下を記述して再起動しましょう。

[global]

wide links = yes
unix extensions  = no


2013年6月7日金曜日

sshfsがXML例外で落ちるとき

以下の手順で復旧しました。

1. Download latest win-sshfs from http://code.google.com/p/win-sshfs/downloads/list.
2. Run the installer and De-install win-sshfs.
3. Delete folder C:\Program Files\win-sshfs if it still exists.
4. Make sure C:\Users\MyUser\AppData\Local\IsolatedStorage contains only one folder with 
   some random-crap name, then delete C:\Users\MyUser\AppData\Local\IsolatedStorage.
5. Restart, just because.
6. Run the installer again.  It shouldn't give you the option to Re/Un-install, 
   it should just install.
7. Restart, just because.
8. Reconfigure all the disks because the will all be GONE!

2013年6月2日日曜日

大量の画像サンプルの入手方法

Bing Search API on Azure を使用します。

Googleは取得出来る画像の枚数や制限が厳しいです。yahooはなぜかクレジッドカードの登録が必要なプランです。

https://datamarket.azure.com/dataset/bing/search

無料のプランを選択します。

もしくは、MITが提供している画像データを使ってみます。
これはデータセットをどんな風に用意するのかを勉強することも出来ます。

http://cbcl.mit.edu/software-datasets/

他には以下のようなデータセットもあります。

http://vasc.ri.cmu.edu/idb/html/car/index.html

http://www.vision.caltech.edu/html-files/archive.html

http://iris.usc.edu/Vision-Users/OldUsers/bowu/DatasetWebpage/dataset.html


ある物体の形状、例えば人や顔などを検出する場合は、データの準備が出来たら、大量に収集した画像のパターンを学習させます。
しかし、形状は同じだが内容が異なる、例えば本やCDのカバー、キャラクター(特徴的な形状)の場合は、様々な角度から見た画像を学習させる必要があります。

OpenCVには、ホモグラフィー変換を行う関数がついていて、自分でパターンを生成することも可能です。


もうひとつはOpenCVに付属しているopencv_createsamplesを使用する方法があります。

1つの画像からランダムにアフィン&ホモグラフィー変換した画像を、OpenCVで使用する独自の「.vec」ファイルで出力します。

引数は知っておく必要があります。

-img
学習の元画像を示します。

1枚の画像からではなく,集めたたくさんの学習画像から学習用正解ファイルを生成する場合,-imgの引数を-infoに変えて正解画像リストファイルを指定します。

-vec
出力ファイル名です。学習用画像データは全てこの1つのファイルにまとめられます。

-num
作成する学習サンプル画像の数です。positiveサンプルが少ないと分類が学習がうまくいかないことが多いです。少なくとも3000くらいは作成したほうが良いです。

-bgcolor
背景色を示します。ロゴなど、印刷されている媒体がはっきりしている場合には、背景色を指定します。そうでない場合は、以下のbgを指定します。

-bg
検出したいオブジェクトが,複雑な背景の中にある場合が予想されるとき指定します。negative画像で準備した画像リストファイルを指定するか、背景の風景が
似通っているならば、シュチュエーションにあった画像を指定します。

以下のwとhはサンプル画像の大きさです。検出出来る物体の最小サイズにもなります。
OpenCVでは顔の場合24x24、人の場合はもう少し大きくても良いと思います。
学習サンプル画像では,元の画像を回転させたものが生成されるため,遊びを持たせるために元画像よりも小さくする(例えば1/2のサイズ)を指定すると良いです。

-w
学習サンプル画像の横幅(ピクセル)を指定します。検出したい物体に合わせて調整が必要です。
-h
学習サンプル画像の縦幅(ピクセル)を指定します。

-show
このオプションを指定すると,実際にどのようなサンプル画像が生成されたかを見ることができます。
Waitkey状態で画像が1枚ずつ表示されます。押すことで,次のサンプル画像を見ることができます。画像の閲覧をやめる場合はESCキーを押すか,ウィンドウを閉じます。
事前にどのような画像が生成されるかを見ることで,その他のオプションのパラメータを最適化します。

次は、生成した画像を使ってBoostによる学習するコマンドです。