Gesichter automatisch weichzeichnen: Privatsphäre mit AWS & .NET
In der heutigen digitalen Welt ist der Schutz der persönlichen Privatsphäre wichtiger denn je. In diesem Beitrag bauen wir eine .NET-Anwendung, die mit AWS Rekognition Gesichter in Bildern erkennt und diese Bereiche anschließend mithilfe einer Bildverarbeitungsbibliothek automatisch weichzeichnet. Die Erkennung kann Gesichter übersehen, und das Weichzeichnen garantiert weder Anonymität noch die Einhaltung von Datenschutzvorschriften. Prüfen Sie die Ergebnisse, bevor Sie sie weitergeben, und senden Sie Bilder nur dann an AWS, wenn Sie dazu berechtigt sind.
Ihr .NET-Projekt einrichten
Verwenden Sie .NET 8 oder neuer. Erstellen Sie zunächst eine neue .NET-Konsolenanwendung. Öffnen Sie Ihr Terminal und führen Sie aus:
dotnet new console -n FaceBlurAutomation
cd FaceBlurAutomation
Fügen Sie als Nächstes die erforderlichen NuGet-Pakete hinzu. Wir verwenden das AWS SDK (Amazon.Rekognition) zur Gesichtserkennung und SixLabors.ImageSharp zur Bildverarbeitung:
dotnet add package AWSSDK.Rekognition --version 4.0.100.13
dotnet add package SixLabors.ImageSharp --version 2.1.13
Dieses Beispiel bleibt auf der Patch-Linie 2.1 von ImageSharp; verwenden Sie eine gepatchte Version
statt 2.1.3. Konfigurieren Sie die Zugangsdaten über die
Standardkette der Zugangsdaten-Anbieter des SDK,
etwa über ein lokales AWS-Profil oder eine IAM-Rolle. Die Identität benötigt die Berechtigung rekognition:DetectFaces.
Legen Sie die Region in Ihrem Profil oder mit AWS_REGION fest, zum Beispiel us-east-1. Der Client unten nutzt
diese Konfiguration, ohne Zugangsdaten einzubetten. Rekognition-Anfragen verursachen AWS-Kosten.
AWS Rekognition verstehen
AWS Rekognition bietet leistungsstarke Werkzeuge für die Bildanalyse. Die API DetectFaces liefert
detaillierte Informationen zu Gesichtsmerkmalen, einschließlich Bounding Boxes, die relativ zu den
Bildabmessungen angegeben sind. Mit diesen Angaben können wir Gesichter lokalisieren und
Nachbearbeitungseffekte wie das Weichzeichnen anwenden. DetectFaces liefert höchstens die 100 größten
Gesichter und kann daher nicht belegen, dass jedes Gesicht in einem Bild gefunden wurde.
Gesichtserkennung und Weichzeichnen implementieren
Nachfolgend finden Sie ein vollständiges C#-Beispiel, das ein Bild lädt, Gesichter erkennt und jeden
erkannten Bereich mithilfe von ImageSharp weichzeichnet. Ersetzen Sie Program.cs durch diesen Code und führen Sie dotnet run -- input.jpg output.png aus.
Wählen Sie dabei ein Bild, das mindestens 80 Pixel breit und hoch ist, sowie eine Ausgabedatei, die
noch nicht existiert:
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using Amazon.Rekognition;
using Amazon.Rekognition.Model;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Processing;
namespace FaceBlurAutomation;
public class Program
{
public static async Task Main(string[] args)
{
try
{
if (args.Length < 2)
{
throw new ArgumentException("Usage: FaceBlurAutomation <inputImagePath> <outputImagePath>");
}
string inputImagePath = args[0];
string outputImagePath = args[1];
if (!File.Exists(inputImagePath))
{
throw new FileNotFoundException("Input image file not found", inputImagePath);
}
using var rekognitionClient = new AmazonRekognitionClient();
await ProcessImageAsync(inputImagePath, outputImagePath, rekognitionClient);
Console.WriteLine($"Processed image saved to {outputImagePath}");
}
catch (Exception ex)
{
Console.Error.WriteLine($"Error: {ex.Message}");
Environment.Exit(1);
}
}
private static async Task ProcessImageAsync(
string inputPath, string outputPath, IAmazonRekognition rekognitionClient)
{
if (!string.Equals(Path.GetExtension(outputPath), ".png", StringComparison.OrdinalIgnoreCase))
{
throw new ArgumentException("Choose a .png output path", nameof(outputPath));
}
if (File.Exists(outputPath))
{
throw new IOException("Choose an output file that does not already exist");
}
using var image = await SixLabors.ImageSharp.Image.LoadAsync(inputPath);
// Send exactly the oriented pixels that we will blur, without EXIF orientation metadata.
image.Mutate(ctx => ctx.AutoOrient());
image.Metadata.ExifProfile = null;
using var imageStream = new MemoryStream();
await image.SaveAsPngAsync(imageStream);
if (imageStream.Length > 5 * 1024 * 1024)
{
throw new InvalidDataException("The normalized PNG exceeds Rekognition's 5 MB Bytes limit");
}
imageStream.Position = 0;
var detectRequest = new DetectFacesRequest
{
Image = new Amazon.Rekognition.Model.Image
{
Bytes = imageStream
},
Attributes = new List<string> { "DEFAULT" }
};
var detectResponse = await rekognitionClient.DetectFacesAsync(detectRequest);
var faces = detectResponse.FaceDetails ?? new List<FaceDetail>();
if (faces.Count == 0)
{
Console.WriteLine("No faces detected; the output is unblurred and needs manual review");
}
foreach (var faceDetail in faces)
{
var box = faceDetail.BoundingBox;
if (box?.Left is not float left || box.Top is not float top
|| box.Width is not float width || box.Height is not float height
|| !float.IsFinite(left) || !float.IsFinite(top)
|| !float.IsFinite(width) || !float.IsFinite(height)
|| width <= 0 || height <= 0)
{
throw new InvalidDataException("Rekognition returned an invalid face bounding box");
}
// Edge faces can extend outside the image. Round outward, then clamp to its bounds.
int x1 = (int)Math.Floor(Math.Clamp((double)left * image.Width, 0, image.Width));
int y1 = (int)Math.Floor(Math.Clamp((double)top * image.Height, 0, image.Height));
int x2 = (int)Math.Ceiling(Math.Clamp(((double)left + width) * image.Width, 0, image.Width));
int y2 = (int)Math.Ceiling(Math.Clamp(((double)top + height) * image.Height, 0, image.Height));
if (x2 <= x1 || y2 <= y1)
{
throw new InvalidDataException("A face bounding box does not intersect the image");
}
var faceRegion = new Rectangle(x1, y1, x2 - x1, y2 - y1);
image.Mutate(ctx => ctx.GaussianBlur(10, faceRegion));
}
using var output = new FileStream(outputPath, FileMode.CreateNew, FileAccess.Write);
await image.SaveAsPngAsync(output);
}
}
So funktioniert es
- Wir laden das Bild, richten es aus, codieren es als PNG und übergeben es an
DetectFacesAsync. Das normalisierte PNG muss das Limit von 5 MB für direkte Bytes einhalten. Das separate Limit von 15 MB für S3-Objekte gilt für dieses Beispiel nicht. - Rekognition liefert eine Liste mit Gesichtsdetails, die jeweils eine normalisierte Bounding Box für den erkannten Gesichtsbereich enthalten.
- Wir rechnen diese Koordinaten in Pixel desselben ausgerichteten Bildes um. Bounding Boxes können über einen Rand hinausragen, daher begrenzen wir sie und verwerfen ungültige oder nicht überlappende Boxen.
- Für jedes erkannte Gesicht wenden wir einen Gaußschen Weichzeichner an. Der feste Weichzeichnungsradius muss nach Prüfung des Ergebnisses möglicherweise angepasst werden.
- Abschließend speichern wir eine neue PNG-Datei, ohne eine vorhandene Datei zu überschreiben.
Fehlerbehandlung und Tests
Das Beispiel enthält eine Fehlerbehandlung für gängige Szenarien:
- Fehlende oder ungültige Befehlszeilenargumente
- Nicht vorhandene Eingabedateien
- Fehler des AWS-Dienstes
- Fehler bei der Bildverarbeitung
- Fälle, in denen keine Gesichter erkannt werden
Fehler des Dienstes und der Bildverarbeitung werden an Main weitergereicht, wodurch das Programm mit
einem Fehlerstatus endet. Es wird keine Ausgabe geschrieben, wenn die Gesichtserkennung fehlschlägt
oder eine ungültige Bounding Box liefert. Geben Sie in einer Serveranwendung einen allgemeinen
Fehler an die Aufrufer zurück und halten Sie bereinigte Diagnoseinformationen in den Server-Logs
vor, statt Ausnahmemeldungen offenzulegen. Wenden Sie Limits für die Eingabegröße und die
decodierten Pixel an, bevor Sie Uploads aus nicht vertrauenswürdigen Quellen annehmen.
Ihre Anwendung erweitern
Dieses einfache Beispiel lässt sich auf verschiedene Arten erweitern:
- Binden Sie es an eine Web-API an, um von Nutzern hochgeladene Bilder zu verarbeiten.
- Nutzen Sie einen Speicherdienst wie Amazon S3 für Eingabe- und Ausgabebilder.
- Kombinieren Sie diese Technik mit anderen Werkzeugen zur Bildanalyse, um eine umfassende Suite zum Schutz der Privatsphäre aufzubauen.
Zusammenfassung
Sie haben nun eine .NET-Anwendung gebaut, die mit AWS Rekognition Gesichter erkennt und einen Weichzeichnungseffekt anwendet, um sichtbare Gesichtsdetails zu reduzieren. Dieser Ansatz zeigt, wie sich cloudbasierte Bildanalyse mit modernen .NET-Bibliotheken kombinieren lässt, um Herausforderungen aus der Praxis zu meistern.
Übrigens nutzt auch Transloadit ähnliche AWS-Techniken zur Bildanalyse in seinem Robot /image/describe, um Workflows der Bildverarbeitung zu verbessern.
