dlib 68 Gesicht Wahrzeichen Punkte sind ungenau, wenn der Kopf der roll-Winkel NICHT zwischen -30 bis 30 Grad
Ich versuche zu erkennen, Gesichter und extrahieren Gesichtsbehandlung Sehenswürdigkeiten von iphone-Kamera(BGRA-format) mit dlib.
Bisher habe ich es zu erkennen Gesicht rects aus AVMetaData und zeichnen 68 dlib Sehenswürdigkeiten innerhalb dieser Grenzen auf das Bild. Bei einem detektierten Kopf-roll-Winkel (roll-Winkel werden die Daten extrahiert aus AVMetadata auch) ist approxiamtely zwischen -30 bis 30 Grad, alles funktioniert einwandfrei. Allerdings, wenn die erkannten Kopf rollt über 30 Grad, das Gesicht Sehenswürdigkeiten würde nicht richtig schließen überhaupt. Diese 68 Punkte würden nicht mehr drehen entlang der Kopf, sagen ich bin halt mein iphone im Querformat-Modus mit dem home-button auf der linken Seite und die front-Kamera auf, die 68-gezeichnet-dots Gesicht bleibt frontal.
Ich habe getestet, mit openGL(offscreen rendering) und openCV für das Rendern von video-Bilder, Sie alle erzeugen die gleichen Ergebnisse. Die rendering-Ansatz scheint irrelavant zu meinem problem.
Meine Fragen sind
- Wie kann ich richtig auszurichten, diese dlib generiert, 68 Punkte trotz Kopf roll-Winkel?
- Oder ist es event möglich, dlib, um genau zu erkennen, keine Gesichter, rollt über 30 Grad?
- (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;
}