モーションテンプレート

モーションテンプレートとは?
-> 映像の中から動き(モーション)の方向などを抽出する方法
-> 動きを履歴として残したものをが増加する。そして、履歴画像から輝度変化の勾配を計算し、全体としてどのように移動したかを線分で表す
-> 応用範囲が広く、ジェスチャ認識やボールの軌跡を視覚的に表示したりすることができる

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

カメラキャリブレーションとは?
-> 画像中の位置や距離を計測したい時などに、画像の歪みなどを直すこと
-> 例えば車間距離の測定など
-> 基準となる物体を画像中に取り込んでおき、この特徴点をベースに3次元位置を複製し、歪みを計算して補正する
-> オブジェクトの測定、検出に使われるだけでなく、ロボット工学のナビゲーションシステムや3次元シーン再構築などに使用される

### カメラキャリブレーションのロジック
– カメラの相対位置とキャリブレーションパターンのプロット
– 再投影誤差の計算
– パラメータ推定誤差の計算

カメラの外部パラメーターと内部パラメーターを使用してカメラ行列を計算する
外部パラメーターは、3次元のワールド座標系から 3次元のカメラ座標系への剛体変換
内部パラメーターは、3次元のカメラ座標から 2次元のイメージ座標への射影変換

外部パラメータは回転Rと変換tで構成
内部パラメータは焦点距離、光学的中心、せん断係数が含まれる

物体追跡

### SSD
入力された動画に対してフレーム単位で検出を行い、フレームごとのBoundingBoxを取得できる
Nフレーム経過した後、N個のBoundingBoxが得られるので、BoundBoxを解析すれば物体の動きとしてTrajectoryを取得できる。これまでの物体の動きはもちろん、ある程度予測することができる

### 物体追跡技術
画像上に興味のある場所(Region of Interest)を予め定義しておき、次のフレーム領域の中で定義されたROIの特徴と一番類似している領域を検索するのが物体追跡

低画質、早い動きだったり、カメラの角度が変わると、検出精度が落ちやすい
精度を保つためにはRaw品質が良い、圧縮、ピンぼけ、縮小は画像が劣化する

### CNNを利用するTracking手法
Tensorflow実装、GPUリアルタイム処理
Trackingの基本は、探索領域xの中で、ターゲットzに一番類似している領域を見つけること
教師データとしてzをニューラルネットワークに入力する
score mapが生成され、x領域の中にzとの類似度を探し、最も類似している領域が対象となる

なるほど、ここにきてニューラルネットワークの活用法がわかってきました。

オプティカルフロー抽出

– 映像中から、映っている物体の動きを抽出するのをオプティカルフローと呼ぶ
– 特徴点抽出とピクセル値の変化から、映像フレーム間における注目ピクセル(特徴点)の移動を計算する
– 移動前と移動後の特徴点を線分で結ぶとオプティカルフローが得られる

### 勾配法
時間変化と空間的な濃度勾配を基礎に置く

### ブロックマッチング法
画像中のある大きさの領域をテンプレートとし、次のフレームの画像内のある評価関数に基づき探索する

### 勾配法の原理
画像は2次元、流体は3次元
画像には奥行き方向成分の情報が欠落している為、移動ベクトルを一意的に求めることができないが、前提条件(仮定)を補うことで、一意的な解を推定する

▼前提条件
(1)移動前後の明るさは普遍
E'(x+u, y+v) = E(x,y)
(2)画像は滑らかである(時間的、空間的に微分可能)
(3)移動量はわずかである
(4)近傍画素も同じ動きをする
画像ピラミッドを使って小さいものから推定する

特徴点抽出

– 物体の形状でも特徴的な箇所だけ注目して検出する方法
– 特徴点は、画像の中の線の端点や交差点、角が用いられる
– 抽出された輪郭線はチェーンコード化され、内側と外側の輪郭が区別される

### 基本
・edge: 差異を認識できる境界がある
・corner: edgeが集中する点
・flat: edgeでもcornerでもない、特徴が何も認識できない点
-> 再現性、識別性が必要

## 特徴点検出の手順
edge検出 -> corner検出 の流れになる

### edgeの検出
輝度が大きく変化している点(水平方向と垂直方向の2方向): Magnitudeと呼ぶ
-> 輝度の変化率を計算する
-> スムージングとは、変化量を計算する際に、周辺部分も考慮する方法
-> 周辺の対象範囲と重み付けの定義にはPrewitt, Sobel, Gaussianなどがある

### Cornerの検出
– Harris Corner Detectorが良く使用される。行列の特性を利用した手法
-> 固有ベクトル: 変化量の方向性を表す、edgeの向き
-> 固有値が大きい: 変化量を良く説明できる

変化量をまとめた行列の固有ベクトルからedgeの向き、固有値の大きさから変化量の大きさがわかる
複数の固有ベクトルがある場合、複数のedgeがある、すなわちcornerとなる

変化量を二次微分してI(x)” = 0となる点が特徴点

なんやろう、頭蒸発しそうだ。。

テンプレートマッチング

– 画像から、「標識」など特定の物体を検出する際に、テンプレートマッチングと呼ばれる手法が良く使用される
– 予め指定パターンの画像を用意し、このパターンと画像部分を照らし合わせながら探索する
– 具体的には入力画像の一部分とテンプレート画像の類似度を求め、類似度が最も大きい場所を探索する
– 類似度の計算方法には「SSD」「SAD」「NCC」などがある

### SSD(Sum of Squared Difference)
画素値の差分の二乗和(二乗誤差)で類似度を評価する
この値が宰相になる場所が類似度が高いことになる
SSD(dx, dy) = (w-1)Σx=0 * (h-1)Σy=0(I(dx + x, dy + y)- T(x,y))^2

### SAD(Sum of Absolute Difference)
SADでは、画素値の差分の絶対値の和で類似度を評価する
この場合も、値が最小になる場所が類似度が高くなる
SSD(dx, dy) = (w-1)Σx=0 * (h-1)Σy=0|I(dx + x, dy + y)- T(x,y))|
※SSDに比べ、計算量が少なく、外れ値の影響を受けにくい。ただし、照明の影響を受けやすい

### NCC(Normalized Cross Correlation)
正規化相互相関で類似度を評価する
NCC(dx,dy) = ΣΣ[I(dx + x, dy +y)T(x,y)]/√ΣΣ[I(dx+x,dy+y)]^2√ΣΣ[T(x,y)]^2
最大値1.0に最も近くなった走査位置が類似する
※照明の影響を受けにくいが、計算量が多い
※画像をベクトルとみなして内積を計算する為、ベクトルのながさ(照明)に影響を受けない

SSD,SADは画像のテンプレート画像と入力画像のサイズの違いをどうやって評価しているかわからんな。
(w-1)Σx=0 * (h-1)Σy=0でシグマが二つ並んだ二重和だから、Σでx=0→横幅のmax(w-1)まで、かつ、y=0→縦幅のmax(h-1)まで計算してるって理解で合っている?
SADとSSDはわかるが、NCCの二乗をルートで割ったので割る値を求めているのか良くわからんな。NCCはベクトルだから向きが回転しててもOKってこと?

ヒストグラム(histogram)

ヒストグラムとは?
-> 統計で度数分布を示すグラフの一つ。横軸に階級、縦軸に度数をとり、各階級の度数を長方形の柱で示す。

define('cherry', 'cherry.jpg');

$img = imagecreatefromjpeg(cherry);
$imagex = imagesx($img);
$imagey = imagesy($img);

$histogramR = array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
$histogramG = array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
$histogramB = array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);

for($y = 0; $y < $imagey; $y++){
	for($x = 0; $x < $imagex; $x++){
		$rgb = imagecolorat($img, $x, $y);
		$r = ($rgb >> 16) & 0xFF;
		$g = ($rgb >> 8) & 0xFF;
		$b = $rgb & 0xFF;
		$histogramR[(int)($r/16)]++;
		$histogramG[(int)($g/16)]++;
		$histogramB[(int)($b/16)]++;
	}
}

function writeHistogram($value, $char){
	echo $value;
	for($i=0; $i<$value; $i++){
		echo $char;
	}
}

echo 'Red <br>';
foreach($histogramR as $countR){
	writeHistogram($countR/100, 'r');
	echo '<br>';
}

Red
53.32rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
41.12rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
446.61rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
470.27rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
505.77rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
263.59rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
238.95rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
178.22rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
118.97rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
86.47rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
72.66rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
65.12rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
56.57rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
46.29rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
39.89rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
48.98rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr

OpenCVでは一次元ヒストグラムでは横軸が明度、縦軸が明度のピクセル数
二次元ヒストグラムでは、横軸が色相、縦軸が彩度、グラフの各点の明るさがピクセル数の数を示す。
cvCreateHist関数などを用いる
ヒストグラムを利用して画像同士の類似度を計算する

なるほど、写真からカテゴライズする時などはヒストグラムを使うのか。
顔認証にもヒストグラムは使われているのでしょうか。。。

モルフォロジー(morphological)変換

モルフォロジー変換とは、画像中の幾何学的な構造を解析したり処理したりする時に用いられる数学的手法の一つ
数理形態学(mathematical morphology)と呼ぶ
1960年G.Matheron, J.Serraによって提起
ノイズ除去、テクスチャ解析、エッジ検出など各種の画像処理に用いられる
モルフォロジー変換にはdilate(膨張)、erode(縮退)、open、closeという基礎的な演算処理があり、OpenCVでは関数で提供されている
dilateは微小領域を削除する為、ノイズの除去などに使用される
delationは入力画像の前景を広げる効果があり、erodionは入力画像の前景を狭める効果がある

### アルゴリズム
– 多次元空間における集合論として展開される
– サイジング n x n(縦横がそれぞれn画素)の2次元デジタル画像を入力すると、フィルタ画素のサイズを r x rとすると、モルフォロジー演算に要する計算量はO(n^2r^2)となる
– 大きなフィルタを小さなフィルタに分割して繰り返し処理を行う方法やフィルタを1次元フィルタに分解して処理する方法、距離変換アルゴリズムを用いてモルフォロジー演算を行う手法などが提案されている
– n x nの2値画像I{Iij}において、F = {(i,j)| Iij = 1}を前景、B = {(i,j)| Iij = 0}を背景と呼ぶ
– 物体と背景の隣接時に、0 -> 1にするのがdelate, 1 -> 0にするのがerode

基本的な原理はわかりました。

傾き補正

撮影時のカメラの傾きから、画像自体が傾いて撮られる事が良くある
そのような場合、ハフ変換で直線を得た後に、その傾きの角度から画像を補正する事ができる
文字認識の前処理としてよく使われる

二値化 -> エッジ検出 -> ハフ変換 -> 傾き補正 -> 文字認識 の流れか?
回転させながら行検出するアルゴリズムもあるみたいですね。

傾いている対象が長方形の場合、輪郭を走査して、最小二乗法の直線近似で、誤差のある点を除きながら直線を求めることもできる。反復法で誤差を収束させるので、速度に難がある

補正する対象が何かや、求めるパフォーマンスによって、採用するアルゴリズムが変わってくるというのは面白い
OpenCVと機械学習はかなり繋がっていますね。

ハフ(Hough)変換

ハフ変換(Hough)は、画像から直線や曲線を抽出し、それを数式で表現したい時に用いられるアルゴリズム
通常はエッジ検出を行った後の画像に対してハフ変換を行う(二値化した後にゴミを除去し、細線化処理を行う)
OpenCVには、直線を検出するcvHoughLine2や、円を検出するcvHoughCirclesが用意されている

### ハフ変換のアルゴリズム
– 座標軸を変換する
– ρ=x∗cosθ+y∗sinθとしてρとθで表す。ρかθのどちらかの値が決まれば、直線を求めることができる
– θは0≦θ<π
– 元画像に存在する点の数の中で、多く交差する箇所が求めたい直線になる

– 円を検出したい場合は(x−p)^2+(y−q)^2=r^2を使用する

エッジ検出した点それぞれのρ、θをプロットした曲線のうち、多くの線が重なり合っている点(ρ、θが同じ)の中から、最も直線が存在する可能性が高い組み合わせを探す処理を行っている

なるほど、θが同じだから、直線とみなすわけですね。
角度が同じものを直線とみなすので、抽出する直線の数が多ければ、実態の直線よりも幾何学的なアウトプットになりそうです。