Utilizar o atributo HeadPose
Neste guia, você aprenderá como usar o atributo HeadPose de um rosto detetado para habilitar alguns cenários-chave.
Importante
Os atributos faciais são previstos usando algoritmos estatísticos. Podem nem sempre ser precisas. Tenha cuidado ao tomar decisões com base em dados de atributos. Abster-se de usar esses atributos para anti-falsificação. Em vez disso, recomendamos o uso da deteção de vivacidade facial. Para obter mais informações, consulte Tutorial : Detetar vivacidade em rostos.
Rodar o retângulo facial
O retângulo facial, retornado a cada face detetada, marca a localização e o tamanho do rosto na imagem. Por padrão, o retângulo está sempre alinhado com a imagem (seus lados são verticais e horizontais); Isso pode ser ineficiente para enquadrar rostos angulados. Em situações em que você deseja cortar rostos de forma programática em uma imagem, é melhor poder girar o retângulo para cortar.
O aplicativo de exemplo Azure AI Face WPF (Windows Presentation Foundation) usa o atributo HeadPose para girar seus retângulos faciais detetados.
Explore o código de exemplo
Você pode girar programaticamente o retângulo facial usando o atributo HeadPose. Se você especificar esse atributo ao detetar rostos (consulte Chamar a API de deteção), poderá consultá-lo mais tarde. O método a seguir do aplicativo Azure AI Face WPF usa uma lista de objetos FaceDetectionResult e retorna uma lista de objetos Face . Aqui, Face é uma classe personalizada que armazena dados de rosto, incluindo as coordenadas de retângulo atualizadas. Novos valores são calculados para cima, esquerda, largura e altura, e um novo campo FaceAngle especifica a rotação.
/// <summary>
/// Calculate the rendering face rectangle
/// </summary>
/// <param name="faces">Detected face from service</param>
/// <param name="maxSize">Image rendering size</param>
/// <param name="imageInfo">Image width and height</param>
/// <returns>Face structure for rendering</returns>
public static IEnumerable<Face> CalculateFaceRectangleForRendering(IList<FaceDetectionResult> faces, int maxSize, Tuple<int, int> imageInfo)
{
var imageWidth = imageInfo.Item1;
var imageHeight = imageInfo.Item2;
var ratio = (float)imageWidth / imageHeight;
int uiWidth = 0;
int uiHeight = 0;
if (ratio > 1.0)
{
uiWidth = maxSize;
uiHeight = (int)(maxSize / ratio);
}
else
{
uiHeight = maxSize;
uiWidth = (int)(ratio * uiHeight);
}
var uiXOffset = (maxSize - uiWidth) / 2;
var uiYOffset = (maxSize - uiHeight) / 2;
var scale = (float)uiWidth / imageWidth;
foreach (var face in faces)
{
var left = (int)(face.FaceRectangle.Left * scale + uiXOffset);
var top = (int)(face.FaceRectangle.Top * scale + uiYOffset);
// Angle of face rectangles, default value is 0 (not rotated).
double faceAngle = 0;
// If head pose attributes have been obtained, re-calculate the left & top (X & Y) positions.
if (face.FaceAttributes?.HeadPose != null)
{
// Head pose's roll value acts directly as the face angle.
faceAngle = face.FaceAttributes.HeadPose.Roll;
var angleToPi = Math.Abs((faceAngle / 180) * Math.PI);
// _____ | / \ |
// |____| => |/ /|
// | \ / |
// Re-calculate the face rectangle's left & top (X & Y) positions.
var newLeft = face.FaceRectangle.Left +
face.FaceRectangle.Width / 2 -
(face.FaceRectangle.Width * Math.Sin(angleToPi) + face.FaceRectangle.Height * Math.Cos(angleToPi)) / 2;
var newTop = face.FaceRectangle.Top +
face.FaceRectangle.Height / 2 -
(face.FaceRectangle.Height * Math.Sin(angleToPi) + face.FaceRectangle.Width * Math.Cos(angleToPi)) / 2;
left = (int)(newLeft * scale + uiXOffset);
top = (int)(newTop * scale + uiYOffset);
}
yield return new Face()
{
FaceId = face.FaceId?.ToString(),
Left = left,
Top = top,
OriginalLeft = (int)(face.FaceRectangle.Left * scale + uiXOffset),
OriginalTop = (int)(face.FaceRectangle.Top * scale + uiYOffset),
Height = (int)(face.FaceRectangle.Height * scale),
Width = (int)(face.FaceRectangle.Width * scale),
FaceAngle = faceAngle,
};
}
}
Exibir o retângulo atualizado
A partir daqui, pode utilizar os objetos Face devolvidos no seu ecrã. As seguintes linhas de FaceDetectionPage.xaml mostram como o novo retângulo é renderizado a partir desses dados:
<DataTemplate>
<Rectangle Width="{Binding Width}" Height="{Binding Height}" Stroke="#FF26B8F4" StrokeThickness="1">
<Rectangle.LayoutTransform>
<RotateTransform Angle="{Binding FaceAngle}"/>
</Rectangle.LayoutTransform>
</Rectangle>
</DataTemplate>
Próximo passo
Consulte o aplicativo Azure AI Face WPF no GitHub para obter um exemplo prático de retângulos de face rotacionados.