Использование OpenCV Cascade - Работа исключительно с haartraning XML-файлом - PullRequest
0 голосов
/ 19 февраля 2012

Я пытаюсь реализовать алгоритм обнаружения лиц Viola Johns на платформе Cuda (я знаю, что openCV уже сделал это, я делаю это для моей школы ... :)).

Мой первыйЭтап заключается в реализации алгоритма на процессоре.

Я использую библиотеку openCV, я знаю, что openCV знает, как выполнять распознавание лиц, Чтобы понять, я хотел бы вернуться к базовым и сделать это по-своему.

Iсоздал представление интегральной суммы и интегральное представление squere sum с использованием функции openCV.

Я перебрал каскад.перебрал этапы, классификаторы и тезисы.Нормализовало каждое окно, вычислило сумму каждого классификатора и сравнило с порогом. К сожалению, мне кажется, что я что-то упустил.потому что я не могу обнаружить лица.

Похоже, мне нужно лучше понять XML-файл cascade.

вот пример:

          <!-- 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?в чем смысл родителя, следующие значения?Как рассчитать каждый классификатор нормализованной суммы?Здесь я что-то не так делаю?см. мой код в приложении

в основном это то, чем я занимаюсь некоторое время, я хотел предложить вознаграждение за этот вопрос, но у меня недостаточно рейтинга.Любая помощь будет принята с благодарностью.
Спасибо заранее, 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 Ответ

1 голос
/ 09 марта 2012

Вы должны сделать некоторые большие изменения. Прежде всего, классификатор-> порог является порогом для каждого признака. классификатор-> альфа указывает на массив, состоящий из 2 элементов - left_val и right_val (на мой взгляд). Вы должны поставить что-то вроде этого после цикла классификатора-

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

затем сравните stage_sum с CvHaarStageClassifier :: threshold, который является порогом стадии, переберите stage_classifiers [i]. Если он пропустит их все, то будет гранью! 'parent' и 'next' здесь бесполезны, если вы используете haarcascade_frontalface_alt.xml, это просто каскад на основе пня, а не на основе дерева.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...