私はCioaプラットフォームでViola Johnsの顔検出アルゴリズムを実装しようとしています(私はopenCVがすでにそうしたことを認識しています。 )。OpenCVカスケードを使用する - haartraning XMLファイルのみで作業する
私の最初の段階はCPUにアルゴリズムを実装することです。
私はopenCVライブラリを使用しています。私はopenCVが顔検出の仕方を知っていることを知っています。理解するために、私は基本的なものに戻りたいと思います。
私は、積分和表現と、openCV関数を使った二乗和積分表現を作成しました。
私はカスケードを通して反復しました。ステージ、クラスファイヤ、直腸を繰り返した。 各ウィンドウを正規化し、各分類子の合計を計算し、しきい値と比較しました。悲しいことに、何か不足しているようです。私は顔を見つけることができないからです。
カスケードXMLファイルをよりよく理解する必要があるようです。
ここは一例です。
<!-- tree 158 -->
<_>
<!-- root node -->
<feature>
<rects>
<_>3 6 2 2 -1.</_>
<_>3 6 1 1 2.</_>
<_>4 7 1 1 2.</_></rects>
<tilted>0</tilted></feature>
<threshold>2.3729570675641298e-003</threshold>
<left_val>0.4750812947750092</left_val>
<right_val>0.7060170769691467</right_val></_></_>
<_>
<!-- tree 159 -->
<!-- tree 159 -->
<_>
<!-- root node -->
<feature>
<rects>
<_>16 6 3 2 -1.</_>
<_>16 7 3 1 2.</_></rects>
<tilted>0</tilted></feature>
<threshold>-1.4541699783876538e-003</threshold>
<left_val>0.3811730146408081</left_val>
<right_val>0.5330739021301270</right_val></_></_></trees>
<stage_threshold>79.2490768432617190</stage_threshold>
<parent>16</parent>
<next>-1</next></_>
<_>
私はleft_valの意味とright_valが何であるかを理解したいのですが? 親の意味は次の値ですか? 各分類器正規化和を計算するにはどうすればよいですか? ここで間違っていることはありますか?私のコードが添付されています
基本的にこれは私がしばらくしていることですが、その質問に対する報酬を提供したいと思っていましたが、十分な評価がありません。どんな助けでも大歓迎です。あなたはいくつかの大きな変更を加える必要があり、事前に
Thnaks、 S
int RunHaarClassifierCascadeSum(CascadeClassifier * face_cascade, CvMat* image , CvMat* sum , CvMat* sqsum,
CvMat* tilted,CvSize *scaningWindowSize, int iteratorRow, int iteratorCol)
{
// Normalize the current scanning window - Detection window
// Variance(x) = E(x^2) - (E(x))^2 = detectionWindowSquereExpectancy - detectionWindowExpectancy^2
// Expectancy(x) = E(x) = sum_of_pixels/size_of_window
double detectionWindowTotalSize = scaningWindowSize->height * scaningWindowSize->width;
// calculate the detection Window Expectancy , e.g the E(x)
double sumDetectionWindowPoint1,sumDetectionWindowPoint2,sumDetectionWindowPoint3,sumDetectionWindowPoint4; // ______________________
sumDetectionWindowPoint1 = cvGetReal2D(sum,iteratorRow,iteratorCol); // |R1 R2|
sumDetectionWindowPoint2 = cvGetReal2D(sum,iteratorRow+scaningWindowSize->width,iteratorCol); // | | Sum = R4-R2-R3+R1
sumDetectionWindowPoint3 = cvGetReal2D(sum,iteratorRow,iteratorCol+scaningWindowSize->height); // |R3________________R4|
sumDetectionWindowPoint4 = cvGetReal2D(sum,iteratorRow+scaningWindowSize->width,iteratorCol+scaningWindowSize->height);
double detectionWindowSum = calculateSum(sumDetectionWindowPoint1,sumDetectionWindowPoint2,sumDetectionWindowPoint3,sumDetectionWindowPoint4);
const double detectionWindowExpectancy = detectionWindowSum/detectionWindowTotalSize; // E(x)
// calculate the Square detection Window Expectancy , e.g the E(x^2)
double squareSumDetectionWindowPoint1,squareSumDetectionWindowPoint2,squareSumDetectionWindowPoint3,squareSumDetectionWindowPoint4; // ______________________
squareSumDetectionWindowPoint1 = cvGetReal2D(sqsum,iteratorRow,iteratorCol); // |R1 R2|
squareSumDetectionWindowPoint2 = cvGetReal2D(sqsum,iteratorRow+scaningWindowSize->width,iteratorCol); // | | Sum = R4-R2-R3+R1
squareSumDetectionWindowPoint3 = cvGetReal2D(sqsum,iteratorRow,iteratorCol+scaningWindowSize->height); // |R3________________R4|
squareSumDetectionWindowPoint4 = cvGetReal2D(sqsum,iteratorRow+scaningWindowSize->width,iteratorCol+scaningWindowSize->height);
double detectionWindowSquareSum = calculateSum(squareSumDetectionWindowPoint1,squareSumDetectionWindowPoint2,squareSumDetectionWindowPoint3,squareSumDetectionWindowPoint4);
const double detectionWindowSquareExpectancy = detectionWindowSquareSum/detectionWindowTotalSize; // E(x^2)
const double detectionWindowVariance = detectionWindowSquareExpectancy - std::pow(detectionWindowExpectancy,2); // Variance(x) = E(x^2) - (E(x))^2
const double detectionWindowStandardDeviation = std::sqrt(detectionWindowVariance);
if (detectionWindowVariance<=0)
return -1 ; // Error
// Normalize the cascade window to the normal scale window
double normalizeScaleWidth = double(scaningWindowSize->width/face_cascade->oldCascade->orig_window_size.width);
double normalizeScaleHeight = double(scaningWindowSize->height/face_cascade->oldCascade->orig_window_size.height);
// Calculate the cascade for each one of the windows
for(int stageIterator=0; stageIterator< face_cascade->oldCascade->count; stageIterator++) // Stage iterator
{
CvHaarStageClassifier* pCvHaarStageClassifier = face_cascade->oldCascade->stage_classifier + stageIterator;
for (int CvHaarStageClassifierIterator=0;CvHaarStageClassifierIterator<pCvHaarStageClassifier->count;CvHaarStageClassifierIterator++) // Classifier iterator
{
CvHaarClassifier* classifier = pCvHaarStageClassifier->classifier + CvHaarStageClassifierIterator;
float classifierSum=0.;
for(int CvHaarClassifierIterator = 0; CvHaarClassifierIterator < classifier->count;CvHaarClassifierIterator++) // Feature iterator
{
CvHaarFeature * pCvHaarFeature = classifier->haar_feature;
// Remark
if (pCvHaarFeature->tilted==1)
break;
// Remark
for(int CvHaarFeatureIterator = 0; CvHaarFeatureIterator< CV_HAAR_FEATURE_MAX; CvHaarFeatureIterator++) // 3 Features iterator
{
CvRect * currentRect = &(pCvHaarFeature->rect[CvHaarFeatureIterator].r);
// Normalize the rect to the scaling window scale
CvRect normalizeRec;
normalizeRec.x = (int)(currentRect->x*normalizeScaleWidth);
normalizeRec.y = (int)(currentRect->y*normalizeScaleHeight);
normalizeRec.width = (int)(currentRect->width*normalizeScaleWidth);
normalizeRec.height = (int)(currentRect->height*normalizeScaleHeight);
double sumRectPoint1,sumRectPoint2,sumRectPoint3,sumRectPoint4; // ______________________
sumRectPoint1 = cvGetReal2D(sum,normalizeRec.x,normalizeRec.y); // |R1 R2|
sumRectPoint2 = cvGetReal2D(sum,normalizeRec.x+normalizeRec.width,normalizeRec.y); // | | Sum = R4-R2-R3+R1
sumRectPoint3 = cvGetReal2D(sum,normalizeRec.x,normalizeRec.y+normalizeRec.height); // |R3________________R4|
sumRectPoint4 = cvGetReal2D(sum,normalizeRec.x+normalizeRec.width,normalizeRec.y+normalizeRec.height);
double nonNormalizeRect = calculateSum(sumRectPoint1,sumRectPoint2,sumRectPoint3,sumRectPoint4); //
double sumMean = detectionWindowExpectancy*(normalizeRec.width*normalizeRec.height); // sigma(Pi) = normalizeRect = (sigma(Pi- rect) - sigma(mean))/detectionWindowStandardDeviation
double normalizeRect = (nonNormalizeRect - sumMean)/detectionWindowStandardDeviation; //
classifierSum += (normalizeRect*(pCvHaarFeature->rect[CvHaarFeatureIterator].weight));
}
}
// if (classifierSum > (*(classifier->threshold)))
// return 0; // That's not a face !
if (classifierSum > ((*(classifier->threshold))*detectionWindowStandardDeviation))
return -stageIterator; // That's not a face ! , failed on stage number
}
}
return 1; // That's a face
}