2012-02-19 3 views
0

私は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 
    } 

答えて

1

。まず、classifier-> thresholdは、各フィーチャのしきい値です。 classifier-> alphaは、left_valとright_valという2つの要素からなる配列を指しています(私の理解では)。あなたは

a = classifier->alpha[0] 
b = classifier->alpha[1] 
t = *(classifier->threshold) 
stage_sum += classifierSum < t ? a : b 

が、その後CvHaarStageClassifierでstage_sumを比較LOOP-分級した後、このようなものを置く必要があります::段階のしきい値であるしきい値を、stage_classifiersをループ[i]は、それはその顔を、それらのすべてを渡し.IF! haarcascade_frontalface_alt.xmlを使用している場合、ここでは「parent」と「next」は役に立ちません。これはちょうど切り株ベースのカスケードであり、ツリーベースではありません。

関連する問題