dlib 68 точки ориентира лица неточны, когда угол крена головы НЕ находится в диапазоне от -30 до 30 градусов - PullRequest
0 голосов
/ 04 мая 2019

Я пытаюсь определить лица и извлечь лицевые ориентиры с камеры iphone (в формате BGRA) с помощью dlib.

До сих пор я сделал это, чтобы обнаружить морщины лица из AVMetaData и нарисовать 68 dlib ориентиров в пределах этих границ на изображении. Когда угол наклона обнаруженной головки (данные угла наклона извлекаются также из AVMetadata) составляет примерно от -30 до 30 градусов, все работает нормально. Однако, если обнаруженная головка поворачивается на 30 градусов, ориентиры на лице не будут совмещены должным образом. Эти 68 точек больше не будут вращаться вдоль головы, говоря, что я держу свой iphone в режиме альбомной ориентации с кнопкой «Домой» слева и фронтальной камерой, лицо с 68 нарисованными точками остается фронтальным.

Я тестировал openGL (рендеринг вне экрана) и openCV для рендеринга видеоизображений, все они дают одинаковые результаты. Подход к рендерингу кажется мне неуместным.

Мои вопросы

  1. Как правильно выровнять эти сгенерированные dlib 68 точек, несмотря на угол крена головы?
  2. Или, возможно, dlib точно обнаружит лица, которые перевернутся на 30 градусов?

- (NSMutableArray <NSMutableArray <NSValue *> *>*)detecitonOnSampleBuffer:(CMSampleBufferRef)sampleBuffer inRects:(NSArray<NSValue *> *)rects {

    dlib::array2d<dlib::bgr_pixel> img;
    dlib::array2d<dlib::bgr_pixel> img_gray;
    // MARK: magic
    CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
    CVPixelBufferLockBaseAddress(imageBuffer, kCVPixelBufferLock_ReadOnly);

    size_t width = CVPixelBufferGetWidth(imageBuffer);
    size_t height = CVPixelBufferGetHeight(imageBuffer);
    char *baseBuffer = (char *)CVPixelBufferGetBaseAddress(imageBuffer);

    // set_size expects rows, cols format
    img.set_size(height, width);

    // copy samplebuffer image data into dlib image format
    img.reset();


    long position = 0;
    while (img.move_next()) {
        dlib::bgr_pixel& pixel = img.element();

        // assuming bgra format here
        long bufferLocation = position * 4; //(row * width + column) * 4;
        char b = baseBuffer[bufferLocation];
        char g = baseBuffer[bufferLocation + 1];
        char r = baseBuffer[bufferLocation + 2];
        dlib::bgr_pixel newpixel(b, g, r);
        pixel = newpixel;

        position++;
    }

    // unlock buffer again until we need it again
    CVPixelBufferUnlockBaseAddress(imageBuffer, kCVPixelBufferLock_ReadOnly);



    // convert the face bounds list to dlib format
    std::vector<dlib::rectangle> convertedRectangles = [self convertCGRectValueArray:rects bound:CGSizeMake(height, width)];
    dlib::assign_image(img_gray, img);

    NSMutableArray *facesLandmarks = [NSMutableArray arrayWithCapacity:0];
    for (unsigned long j = 0; j < convertedRectangles.size(); ++j) {
        /* original codes start from here */
        dlib::rectangle oneFaceRect = convertedRectangles[j];

        // detect all landmarks
        dlib::full_object_detection shape = predictor(img, oneFaceRect);
        NSMutableArray *eachFaceLandmarks = [NSMutableArray arrayWithCapacity:0];
        for (int i = 0; i < shape.num_parts(); i++) {
            dlib::point p = shape.part(i);
            [eachFaceLandmarks addObject:[NSValue valueWithCGPoint:CGPointMake(p.x(), p.y())]];
        }

        //
        [facesLandmarks addObject:eachFaceLandmarks];
    }

    return facesLandmarks;
}

1 Ответ

0 голосов
/ 07 мая 2019

Честно говоря, мне не ясно с первым вопросом.

Относительно второго, основываясь на моем опыте в прошлом проекте. Мы можем определить, является ли лицо фронтальным или наклонным, используя линию между двумя центрами глаз. Если эта линия наклонена, мы можем сказать, что грань должна быть выровнена. Более подробную информацию можно найти в ссылке ниже, где вы можете найти очень четкие шаги и шаги Выравнивание лица

...