読者です 読者をやめる 読者になる 読者になる

CMakeとは

プログラム言語の文法を習うと、実際に実用的なプログラムを書くことになります。
このとき大抵の場合は、簡単に実用的なプログラムを書くための関数などが入ったライブラリというものを使います。
このライブラリはクロスプラットフォーム(様々な環境下で実行可能)であると便利であるため、各々がCMakeというツールを使って各々の環境でプログラムが動くようにビルドします。
ここで出てきたCMakeがよくわからずに戸惑ってしまう人も多いと思いますので、今回はCMakeについて勉強していきます。

CMakeとはなんぞや
先程の流れから鋭い人はわかると思いますが、CMakeは様々な環境下でビルドを自動化するツールです。
CMakeを実際に行う際には、CMakeLists.txtを作成し、これを読み込んでコンパイルします。つまり、コンパイルするための設定リストみたいなものです。

CMakeの導入
それではまずCMakeを自分のPCに導入するところから行きましょう。今回はWindowsでの導入を説明します。
CMakeのダウンロードページからダウンロードします。
ページに行きましたら、Release Candidateではなく、Latest Releaseのところからzipファイル(下図の黄色の部分)をダウンロードし、適当なところに解凍します。
f:id:takahiro-itazuri:20161026062241p:plain
これで導入は終わりです。とても簡単ですね。(もしコマンドプロンプトでcmakeを扱う際は、pathを通しておくことをお勧めします。)

実際にCMakeを使ってみよう
OpenCVVisual Studioでビルドする方法がこちらのサイトに載っていますので、参考にしてください。
この操作によって、各々の開発環境下で実行可能なライブラリを作成してくれてたということになります。

こちらの記事はとてもわかりやすく、参考にさせていただきました。
もっと詳しいことを聞きたいという方は気軽にコメントしてください。
それでは。

計算量について

計算量とはなんぞや
プログラミングを初めて少しすると、そのプログラムは重いとか、何fpsでしか動かないとか、省メモリだとかいう言葉を耳にすることがあると思います。
これは結局プログラムを実行した際に必要な資源がどれくらいなのかということを言っています。
プログラムを実行する際に必要な資源とは、時間とメモリです。
この資源を「計算量」といい、時間とメモリそれぞれに「時間計算量」と「空間計算量」という計算量の評価尺度があります。

時間計算量
時間計算量は、先程も述べたようにプログラムを実行する際に必要な時間のことを示します。
しかし、これでは漠然としすぎていてよくわかりません。そこで、数学や物理を勉強したことある人はオーダーというものを見たことがあると思います。
記号でいうとOというものです。これはサイズnのデータが渡されたときにどの程度の計算量を必要とするかを示しています。
例としてはO(n^2)とかO(n \log n)という風に書きます。
詳しい定義については後日記述します。

空間計算量
空間計算量は、プログラムを実行する際に必要なメモリ量を示します。
こちらも時間計算量と同じようにオーダー記法を用いてよく示されます。

最近ビッグデータやIoTなどと騒がれていますが、このような膨大なデータを扱う際にはなるべく省資源で実行可能なプログラムが好まれます。
皆さんもぜひ計算量を意識したプログラムを書きましょう。

コマンドラインとは

忙しくてなかなか更新できませんでした。お久しぶりです。
今回はプログラムを組んでいると、必ず出会うコマンドライン。今日はコマンドラインの話をします。

コマンドラインとはなんぞや
プログラムを始めたばかりの人はやりたいことはあるけど、知らない言葉ばっか。結局本旨と関係ないところでつまいずいて諦めてしまうということもあると思います。僕も最初はそうでした(今もそうですが)。
無駄話は置いておいて、コマンドラインとはずばりこの黒い画面のことです。
f:id:takahiro-itazuri:20161010115958p:plain
おお、プログラマーっぽい(笑)。皆さんは今パソコンでマウスを動かしてクリックして、、、とかやっています(これをグラフィカルユーザーインターフェースと言います)が、昔はすべてこの黒い画面にコマンド(これをキャラクタユーザーインターフェースと言います)というものを打ってパソコンを使っていたそうです。Linuxを使っている方とかは使い慣れているかもしれませんが、筆者は一般のWindowsユーザーだったため、これが出たらパソコンは壊れるんだと思っていました。実はこの画面が突然でてきた時はなんらかのプログラムをアプリケーションが回していたんですね。安心。
話を戻しますと、Windowsユーザーの方はVisual StudioMacの人はXcode?とかのIDE(統合開発環境)でプログラムを実行していると思います。ここで実行するときはなんか再生ボタンみたいなやつを押すと、コンパイルして、実行してくれたと思います。実は、これはIDEが書いたスクリプトから実行ファイルを作成してくれて、それを実行していたのです。
ためしに、Visual Studioコンパイルをしてみると、プロジェクトのディレクトリ(ファイルの置いてある場所)の「x64 or x86」の「Debug or Release」に行くと「(プロジェクト名).exe」というファイルがあります。これが実行ファイルというものです。
それではこれをどのように実行するのか次に見ていきましょう。

実行しよう!
先ほどexeファイルを発見しました!まずコマンドラインを出し方です。この黒い画面出せるの?と思った方!いないですかね、、、。出せるんですよ。
Windowsでは「Windowsマーク」+「R」を押すと
f:id:takahiro-itazuri:20161010121612p:plain
こんな画面が出てきます。ここに書いてあるように「cmd」と入力して、「Enter」を押してみてください。おおお!出たぞ!黒いの!そんなに感動はないですかね。
これが出たら次に、exeのあるディレクトリに移動します。移動するときのコマンドは「cd」というものです。

C:\Users\username> 

という風にきっと今書かれていると思います。usernameはあなたがパソコンにつけた名前が入ってると思います。これは今、Cドライブという記憶装置の中のUserの中のusernameというディレクトリに今いますということです。
それでは移動しますよ!

C:\Users\username> cd (行きたいディレクトリ)

と入力すると、行きたいディレクトリに移動できます。ディレクトリって手で入力するの?と思いません?僕は思いました。そんな必要はないのですよ。
こういう画面
f:id:takahiro-itazuri:20161010122422p:plain
のこういう部分
f:id:takahiro-itazuri:20161010122453p:plain
ありますよね。ここに触ると
f:id:takahiro-itazuri:20161010122704p:plain
青くなった!ここで「Ctrl」+「C」(コピーのコマンド)を押して、黒い画面に戻って、「Ctrl」+「V」(ペーストのコマンド)を押すと(いわゆるコピペ)ディレクトリがコピーできます!

やっと、ここまで来た、、、。あとはexeファイルを実行するだけ!

C:\(行きたかったディレクトリ)> (実行したファイル).exe

とすると実行できます!
意外と最後は簡単にだった、、、。

今日はここまでにして、実際これがどう役に立つのかはまた今度にしましょう!

pythonでwaveファイルを扱おう

今回は音声ファイルの王道のwaveファイルをpythonで扱ってみましょう。
早速コードを見ながら行きましょう。

#waveファイルを扱うためのモジュールをimport
import wave

#音声ファイルを開く
fWave = wave.open('filename.wav', 'rb') #'rb'は読み込み専用

#音声ファイルのプロパティーを取得
fs = fWave.getframerate()      #フレームレート
n = fWave.getnframes()         #総フレーム数
channel = fWave.getnchannels() #チャンネル数

#データを取得するスタート時間と何秒分取得するかを指定
start = 100  #100秒をスタート時間とする
length = 200 #200秒間

#スタート時間からスタートフレームを計算し、その位置へ移動
n_frames = int(start * fs)
fWave.setpos(n_frames)

#データの取得
n_frames = int(length * fs)
Data = fWave.readframes(n_frames)

#データの型を変換する
import numpy as np
Data = np.frombuffer(Data, dtype='int16') / 32768.0 #-1.0 ~ 1.0に正規化する

以上のような感じでwaveファイルを読み込むことができます。
簡単に説明すると、wavファイルを読み書きする専用のwaveというモジュールがあります。
データを取得するときは最初の位置とどのくらいの長さの音声データを取得するかを与えれば、データを取得できます。
またそのデータはバイナリで書かれているので、実際にデータを扱う際は、データの型を変換してあげる必要があります。
もしスタート位置を指定しなければ、スタート位置はデフォルトで0に設定され、データを取得した分だけ、スタート位置がずれていくようになっています。

カメラキャリブレーション1

今回はカメラキャリブレーションについてです。
今まで音声処理が多かったですが、筆者は本当は画像処理屋さんです(笑)

カメラキャリブレーション(camera calibration)とは

カメラキャリブレーションとはカメラのレンズによる歪みを補正したり、カメラの内部パラメータや外部パラメータを推定することを言います。
要するに、カメラの情報を取得しようということです。

カメラパラメータ

まずカメラのパラメータってどんなものがあるかを見ていきます。
外部パラメータ(extrinsic parameter)
1.世界座標系におけるレンズの中心座標
世界座標というのは実世界での座標ということです。
たとえば机の角を原点にした座標系であったり、教室の中心を原点にしたものであったり、、、。
このように原点を取って、カメラの中心が見ている座標はどこかということです。
もちろん実世界は3次元なので(超弦理論とか時空間が歪んだものは考えないでください。筆者はそれがわからくて物理を諦めています。)、カメラの中心が見ているところも3次元の点です。
2.レンズの光軸方向
カメラの中心が見ているところが必要なのはわかりましたが、そこからカメラがどこから見ているのかということもカメラ外部のパラメータです。
カメラの位置を直接与えればよいのですが、実際はレンズの光軸の向き、つまりカメラがどっちの方向を向いているかというころを用います。
なぜかというと、おそらく数式にするときに行列を回転成分に分離することがあるからだと思います。
内部パラメータ(intrinsic parameter)
1.焦点距離
焦点距離はレンズのお話でおなじみですよね!割愛します!
2.画像中心
次に実際の画像の中心がどこに当たるのかというものです。
先ほどレンズの中心座標の画像内バージョンみたいなものですね。
画像は二次元でよくuv座標系とか言ったりします。
xyだと混同しやすいからでしょうね。
3.アスペクト比
画像処理をやっている人は皆さんご存知だと思います。
アスペクト比というのは画像の縦横比のことです。
知らなかった人はこれを機に覚えてください(意外と日常で使われているときもあったりします)。
スキュー歪み
スキュー歪みというのは長方形が平行四辺形になるような歪みのことです。
イメージがわかない人はググってみてください。

と以上のようにカメラパラメータを紹介してきました。
まとめますと外部パラメータが6個、内部パラメータが5個あるということがわかりました。
つまり未知数が11個なので、その未知数がわかるように方程式を解いていこうということです。
今回はとりあえずここまでにして、次回以降に実際のキャリブレーションの仕方を書きたいと思います。

パワースペクトル密度

音声処理を初めて半月、まだまだ知らないことだらけ、、、。

今日はパワースペクトル密度についてです。

なんか物理でやったような、、、。

パワースペクトル密度とは

パワースペクトル密度とは信号が周波数についてどのように分布しているかだそうです。

なんとなく字面からわかる気もする。

つまり、パワースペクトルの密度であって、パワースペクトルっているのは信号をフーリエ変換したスペクトルの振幅の二乗な訳です。

したがって、信号をフーリエ変換して得られたスペクトルの振幅を二乗したパワースペクトルが、周波数について(パワースペクトルでいう横軸)についてどのように分布しているかということらしい。

ここで信号{ \displaystyle f(t)}に対して、フーリエ変換

{ \displaystyle F(\omega)=\frac{1}{\sqrt{T}}\int_{0}^{T} f(t)\exp(-i \omega t)dt}

で、パワースペクトル密度は

{ \displaystyle PSD(\omega) = lim_{T \to \infty}E \left( |F(\omega)|^2 \right)}

です。ここで言う \displaystyle E\left(\cdot \right)とは期待値です。期待値とは確率実現値を確率の重みで平均した値である。

FFTによる周波数分解能の差を改善できます。

なぜなら密度を考えているので、どんな周波数分解能のFFTを用いても、単位周波数幅あたりのパワー値(つまり[W/Hz])として表現されるからです。

と今回はこんなところで。 違っていたらコメントいただけると幸いです。

音声処理の基本を色々

先日から音声処理を色々やっていると書かせていただいています。
ですが、環境構築の話ばっかりで肝心な音声処理を書いてないじゃないかということで、今回は音声処理をするに当たって基礎的な部分をまとめてみようと思います。

音声処理をするための言語

音声処理をするにあたって適している言語をまずまとめたいと思います。
ちょっと雑談をします。
筆者の場合は、C++を主言語としていて、本当はC++で音声処理をしたかったのですが、自分で書いたプログラムはやはりスピードが遅くて諦めて、色々なものを試すことに至りました。
是非C++でも音声処理が簡単にできるライブラリがほしいところです。誰か作ってください、早急に。
このように現状でC++で良い音声処理のライブラリは筆者の知る限りないので、C++を使っている人は次に紹介するものでプログラムを組むことをおすすめします。
python
筆者も実際使わせていただいているpython。超高級言語で、気軽にプログラムが書けます。
利点

  • 簡単に音声処理ができるライブラリがある。(numpy, wave, ffmpegなど)
  • 無料

欠点

  • pythonで書き慣れるまで少し時間がかかる

matlab
筆者はほとんど使ったことがありません。理由は欠点を参照。
利点

  • とっても簡単
  • 行列演算が得意
  • 機能がとても豊富

欠点

  • 有料

有料なことだけが傷なmatlabですが、学生であれば少し安く使えるらしい。研究室で買ってもらえる人は使ってみるといいでしょう

SPTKやSoX
利点

欠点

  • 既存のものを組み合わせていく感じなので、プログラムを書く点ではなんとも、、、

以上が思い当たる言語です。最終的にC++のプログラムを書きたい人(筆者)はC++からpythonmatlabコマンドラインにアクセスするようにすればOKです。強引ですね。はい。

音声処理の基礎

ファイル形式
おそらく音声処理を始めるに当たって、まず音ってどういうデータなんだとなりますよね。
筆者が音声処理をするときに使うファイルの形式は「.wav」(以下wavファイル)です。
wavファイルはRIFF形式というバイナリファイルの形式で書かれています。RIFFファイルとはチャンクに分かれていて、チャンクごとに色々な情報が入っています。(アバウトすぎてすみません。時間があるときに触れようと思います。)
wavファイルの場合、fmtチャンクというものにwavファイル自体の形式(ファイルサイズやサンプリングレートなど)が書いてあり、dataチャンクに実際の音のデータが入っています。
他にもmp3とか音声を保存したファイル形式はありますが、プログラムを書くときはwavファイルが一般的です。

音声データ
wavファイルが使われているのはわかったけど、いまいち納得いかないと思いますので、そのファイルがどんなデータを持っているのか説明します。

  • チャンネル数

1チャンネルのときをモノラル、2チャンネルのときをステレオといいます。
両耳で同じ音が流れるのをモノラル、それぞれ違う音が流れるのがステレオと考えていいでしょう。

  • サンプリングレート

音を聞いていると連続に聞こえていますが、実は離散的なデータになっています。そこで、1秒間をどれくらいに区切って音をデータ化しているかがサンプリングレートです。

  • データ

実際のデータはサンプリングされたデータがバイナリで入っています。そこでwavファイルの読み込みでは16bit(モノラルの場合)ずつデータを読み込んで数字に変えていきます。

FFT
FFTとは高速離散フーリエ変換の略でDFT(離散フーリエ変換)を高速にしたものです。
しかしながら、何分もの長い音に対してFFTをすると、magnitudeやphaseが雑然としてわかりにくいので、短時間に区切った短時間フーリエ変換(STFT)が行われます。
短く区切ったことによる弊害があり、フーリエ変換はもともと無限の長さの信号に対して行う処理なので、区切った波形が繰り返されているものとして処理をします。
すると、区切った部分が不連続になり、本来の波形にない高周波な成分がでてきてしまいます。
そこで窓関数というものをかけます。

窓関数
窓関数には色々種類があり、たとえばハミング窓、ハニング窓、カイザー窓などがあります。しかし、音声処理でよく用いられるのはハミング窓ですので、よくわからない人はハミング窓を使いましょう。
で、この窓関数が何をしているかというと、STFTでの問題は端の部分ということだったので、端の方にかけて減衰させてやるのが窓関数です。
実際にこの窓関数をかけると余計は高周波成分がでにくくなります。