私はViola-Jonesの顔検出アルゴリズムの適応を実装してきました。この手法は、画像内に24x24ピクセルのサブフレームを配置し、その後、可能な限りすべてのサイズですべての位置に長方形のフィーチャを配置することに依存しています。
これらの機能は、2つ、3つ、または4つの長方形で構成できます。次の例を示します。
彼らは、網羅的なセットが180kを超えると主張しています(セクション2)。
検出器の基本解像度が24x24であることを考えると、長方形の特徴の網羅的なセットは非常に大きく、180,000を超えます。Haarベースとは異なり、長方形フィーチャのセットは不完全であることに注意してください。
以下の記述は本書に明示的に記載されていないため、私の側の仮定です。
- 2つの長方形のフィーチャが2つ、3つの長方形のフィーチャが2つ、4つの長方形のフィーチャが1つだけあります。この背後にある論理は、強調表示された長方形間の違いを観察しているということです。色や輝度などを明示的に観察しているわけではありません。
- フィーチャタイプAを1x1ピクセルブロックとして定義することはできません。少なくとも1x2ピクセルである必要があります。また、タイプDは少なくとも2x2ピクセルである必要があり、このルールは他の機能にも適用されます。
- 中央のピクセルは分割できないため、フィーチャタイプAを1x3ピクセルブロックとして定義することはできません。それ自体からそれを差し引くことは、1x2ピクセルブロックと同じです。このフィーチャタイプは、偶数の幅に対してのみ定義されます。また、フィーチャタイプCの幅は3で割り切れる必要があり、このルールは他のフィーチャにも適用されます。
- 幅や高さが0のフィーチャを定義することはできません。したがって、xとyを24からフィーチャのサイズを引いた値まで繰り返します。
これらの仮定に基づいて、私は網羅的なセットを数えました:
const int frameSize = 24;
const int features = 5;
// All five feature types:
const int feature[features][2] = {{2,1}, {1,2}, {3,1}, {1,3}, {2,2}};
int count = 0;
// Each feature:
for (int i = 0; i < features; i++) {
int sizeX = feature[i][0];
int sizeY = feature[i][1];
// Each position:
for (int x = 0; x <= frameSize-sizeX; x++) {
for (int y = 0; y <= frameSize-sizeY; y++) {
// Each size fitting within the frameSize:
for (int width = sizeX; width <= frameSize-x; width+=sizeX) {
for (int height = sizeY; height <= frameSize-y; height+=sizeY) {
count++;
}
}
}
}
}
結果は162,336です。
Viola&Jonesが話す「180,000以上」を概算するために私が見つけた唯一の方法は、仮定#4を削除し、コードにバグを導入することです。これには、4行をそれぞれ次のように変更することが含まれます。
for (int width = 0; width < frameSize-x; width+=sizeX)
for (int height = 0; height < frameSize-y; height+=sizeY)
その結果、180,625になります。(これにより、フィーチャがサブフレームの右および/または下部に接触するのを効果的に防ぐことができます。)
もちろん、質問です。実装に誤りがありましたか?サーフェスがゼロのフィーチャを検討することは意味がありますか?それとも私はそれを間違った方法で見ていますか?