デジカメの仕組み

0.シャッターに相当する電子回路が電子の流れをコントロール
1.レンズが被写体から光を集める
2.撮影素子(CCD)が画像を電子的に捉える
3.画像処理エンジンで画像は電子データに変換され、様々な画質処理が行われる
4.メモリーカードなどの記録メディアに電子データとして保存される

フィルムカメラとの違いは、臭化銀(AgBr)の電子反応ではなく、撮影素子でデータを捉えているところか。

### 撮影素子とは?
撮影素子とは、被写体の光を画像データに変換する
イメージセンサーと呼ばれ、ほぼ全てのデジカメに内臓されている

CANON EOS Kiss X5
撮影素子:高感度・高解像度大型単板CMOSセンサー

– 撮影素子サイズ
-> イメージセンサーサイズ、画像センサーサイズと呼ばれる
-> 単位はインチ(2.54cm)で1/4〜2/3インチが一般的
※撮影素子のサイズが大きいほど多く光を集めて色を詳細に表現できる。撮影素子とレンズで画質が決まる

– 走査方式
デジタルデータを画像としてディスプレイに表示する方法
インターレース方式:1枚の画像を横長に細かく分割、奇数段目・偶数段目の2回に分けて転送表示
プログレッシブ方式:分割した部分をまとめて1回で転送表示

– イメージセンサー(個体撮影素子) Charge Coupled Device
CMOSセンサー:其々のピクセルが独立して電荷の増幅やデジタル変換する回路をもち、デジタル信号としてデータを出力
CCDセンサー:其々のピクセルの電荷は隣接するピクセルに一斉に転送され、バケツリレーのように順次外部に信号を出力する
表現力や画質はCCD(デジカメ主流だった、高価)が、読み出しの速さ消費電力ではCMOS(スマホ主流で普及)の方が優れている

– 撮影素子の働き
被写体からの光線をレンズなどの光学系によって撮影素子の受光平面に結像させ、その像の光による明暗を電荷量に光電変換し、それを順次読み出して電気信号に変換する
-> 外部光電効果:固体の表面にある電子が光子のエネルギーを受けて真空中に放出される現象
-> 内部光電効果:エネルギーの低い方にある電子が、光子のエネルギーにより高いほうに励起される現象
-> CCDイメージ・センサの材料にSi単体結晶(シリコン)が使われる

1枚のシリコン基板上に形成された多数の受光素子の並びで光電変換を行う
CCDはMOSキャパシタを近接して並べた構造が基本
半導体素子の一種で、シリコン基板表面の酸化膜上に多数の電極を設けて、MOS構造
の各電極に隣同士で異なる電圧を与えることにより電位の井戸を作り出す

イメージセンサー自作は完全に電子回路の世界だな。
とりあえずRaspberry Piは買い物リストに追加や。

フィルムカメラの原理

フィルムカメラに光子が入ると、光エネルギーの塊は感光乳剤と呼ばれるプラスチックでカバーされた部分にぶつかる
※感光乳剤は紫外線で固まる乳剤(脂肪、脂肪油または水に不溶性の医薬品を水中に微細均等に分散し乳状とした液剤)。臭化銀(AgBr)などの粒子をゼラチンの中に一様に分散させた乳液状の薬剤。紫外線を当てなければ水で流せる
※感光乳剤は「ジアゾ感光材」と「着色剤」を混ぜ合わせる
※可視光線よりも波長の短いものが紫外線 紫外線の中でみ、波長が長いものからA、B、Cと大別されている
※UV-A(315-400nm)、UV-B(280-315nm)、UV-C(100-280nm)

### 感光剤(AgBr)の特徴
AgBrに光が当たると電子が飛び出す。飛び出た電子が銀イオン(Ag+)に取り込まれると中世の銀原子(Ag)となる。生成した銀原子が数個(n個)集まって、銀原子のクラスターを生成(Agn)。
この銀原子のクラスターを潜像と呼び、還元試薬によるフィルム現像の家庭で、銀原子クラスターが触媒となって潜像の周りで銀イオンの還元が速く進行し、銀原子の数が増加して目に見えるような像が生成さレル。

### フィルム
フィルムストリップをコーディングしているものはサスペンションのようなもの
ハロゲン化銀結晶が浮遊して凝固している(ゼラチン)
光子がフィルムストリップ上で臭化銀結晶にぶつかると、負電荷の臭化物イオンから電子を取り除く。そして、格子の結晶の中の電子が離脱の状態になるまで動き回る。結果的に銀イオンと合わさって中性電荷の銀原子になる。

### 現像とは
現像液が残ったハロゲン化銀結晶と反応する。現像液が還元剤を含む。還元剤は、化学反応の間に他の物質に電子を与えることのできる化学物質。
ネガ像では、光と影の情報が逆になる。
未現像のフィルムを光に当ててはいけない

潜像の状態から像を浮き出すのを現像液

現像を停止させるのを停止液
感光部分をフィルムを長期保存可能な状態に像を固定化するのを定着液という

光が臭化銀(AgBr)に当たった時に電子が飛び出る性質と銀粒子の変化で現像を作っているのか。化学反応の世界なんだな。プログラミングとは違う世界の話ですな。

OpenCVの映像処理

OpenCVでは画像を独自の多次元配列構造体に格納する(iplimage形式)
カメラ映像もしくはビデオファイルから取得した映像もフレーム単位の画像として処理される

映像も連続した画像というイメージか。紙芝居とビデオ映像は別物だと思っていたけど、原理は基本的には同じか。

モーションテンプレート

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

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

カメラキャリブレーションとは?
-> 画像中の位置や距離を計測したい時などに、画像の歪みなどを直すこと
-> 例えば車間距離の測定など
-> 基準となる物体を画像中に取り込んでおき、この特徴点をベースに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関数などを用いる
ヒストグラムを利用して画像同士の類似度を計算する

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