Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
In diesem Artikel wird gezeigt, wie Sie die Open Source maschinelles Sehen Library (OpenCV) verwenden, eine systemeigene Codebibliothek, die eine Vielzahl von Bildverarbeitungsalgorithmen bereitstellt, mit der MediaFrameReader-Klasse, die Medienframes aus mehreren Quellen gleichzeitig lesen kann. Der Beispielcode in diesem Artikel führt Sie durch das Erstellen einer einfachen App, die Frames von einem Farbsensor abruft, jeden Frame mithilfe der OpenCV-Bibliothek weicht und dann das verarbeitete Bild in einem XAML-Bildsteuerelement anzeigt.
Hinweis
OpenCV.Win.Core und OpenCV.Win.ImgProc werden nicht regelmäßig aktualisiert und bestehen nicht die Store-Compliance-Prüfungen, daher sind diese Pakete nur zum Experimentieren gedacht.
Dieser Artikel baut auf dem Inhalt von zwei anderen Artikeln auf:
Verarbeiten von Medienframes mit MediaFrameReader – Dieser Artikel enthält ausführliche Informationen zur Verwendung von MediaFrameReader zum Abrufen von Frames aus einer oder mehreren Medienframequellen und beschreibt im Detail den großteil des Beispielcodes in diesem Artikel. Insbesondere stellt process media frames with MediaFrameReader die Codeauflistung für eine Hilfsklasse, FrameRenderer, bereit, die die Darstellung von Medienframes in einem XAML Image-Element behandelt. Der Beispielcode in diesem Artikel verwendet auch diese Hilfsklasse.
Verarbeiten von Softwarebitmaps mit OpenCV – Dieser Artikel führt Sie durch das Erstellen eines systemeigenen Codes Windows-Runtime Komponente OpenCVBridge, das hilft, zwischen dem SoftwareBitmap-Objekt, das von mediaFrameReader verwendet wird, und dem von der OpenCV-Bibliothek verwendeten Mat-Typ zu konvertieren. Im Beispielcode in diesem Artikel wird davon ausgegangen, dass Sie die Schritte zum Hinzufügen der OpenCVBridge-Komponente zu Ihrer UWP-App-Lösung ausgeführt haben.
Zusätzlich zu diesen Artikeln finden Sie unter " Camera Frames + OpenCV Sample " im GitHub-Repository von Windows Universal Samples ein vollständiges, end-to-End-Arbeitsbeispiel des in diesem Artikel beschriebenen Szenarios.
Um schnell mit der Entwicklung zu beginnen, können Sie die OpenCV-Bibliothek in ein UWP-App-Projekt einschließen, indem Sie NuGet-Pakete verwenden, aber diese Pakete bestehen möglicherweise nicht den App-Zertifizierungsprozess, wenn Sie Ihre App an den Store übermitteln. Daher wird empfohlen, den OpenCV-Bibliotheksquellcode herunterzuladen und die Binärdateien selbst zu erstellen, bevor Sie Ihre App übermitteln. Informationen zur Entwicklung mit OpenCV finden Sie unter https://opencv.org
Implementieren der systemeigenen OpenCVHelper-komponente Windows-Runtime
Führen Sie die Schritte in Process-Softwarebitmaps mit OpenCV aus, um die OpenCV-Hilfskomponente Windows-Runtime zu erstellen, und fügen Sie Ihrer UWP-App-Lösung einen Verweis auf das Komponentenprojekt hinzu.
Suchen nach verfügbaren Framequellgruppen
Zunächst müssen Sie eine Medienframequellgruppe finden, aus der Medienframes abgerufen werden. Rufen Sie die Liste der verfügbaren Quellgruppen auf dem aktuellen Gerät ab, indem Sie MediaFrameSourceGroup.FindAllAsync aufrufen. Wählen Sie dann die Quellgruppen aus, die die für Ihr App-Szenario erforderlichen Sensortypen bereitstellen. In diesem Beispiel benötigen wir einfach eine Quellgruppe, die Frames von einer RGB-Kamera bereitstellt.
var frameSourceGroups = await MediaFrameSourceGroup.FindAllAsync();
var selectedGroupObjects = frameSourceGroups.Select(group =>
new
{
sourceGroup = group,
colorSourceInfo = group.SourceInfos.FirstOrDefault((sourceInfo) =>
{
// On Xbox/Kinect, omit the MediaStreamType and EnclosureLocation tests
return sourceInfo.SourceKind == MediaFrameSourceKind.Color;
})
}).Where(t => t.colorSourceInfo != null)
.FirstOrDefault();
MediaFrameSourceGroup selectedGroup = selectedGroupObjects?.sourceGroup;
MediaFrameSourceInfo colorSourceInfo = selectedGroupObjects?.colorSourceInfo;
if (selectedGroup == null)
{
return;
}
Initialisieren des MediaCapture-Objekts
Als Nächstes müssen Sie das MediaCapture-Objekt initialisieren, um die im vorherigen Schritt ausgewählte Framequellgruppe zu verwenden, indem Sie die SourceGroup-Eigenschaft der MediaCaptureInitializationSettings festlegen.
Hinweis
Die von der OpenCVHelper-Komponente verwendete Technik, die in Prozess-Softwarebitmaps mit OpenCV ausführlich beschrieben wird, erfordert, dass sich die Bilddaten im CPU-Speicher und nicht im GPU-Speicher befinden. Daher sollten Sie "MemoryPreference.CPU" für das Feld "MemoryPreference" der MediaCaptureInitializationSettings angeben.
Rufen Sie nach der Initialisierung des MediaCapture-Objekts einen Verweis auf die RGB-Framequelle ab, indem Sie auf die MediaCapture.FrameSources-Eigenschaft zugreifen.
mediaCapture = new MediaCapture();
var settings = new MediaCaptureInitializationSettings()
{
SourceGroup = selectedGroup,
SharingMode = MediaCaptureSharingMode.ExclusiveControl,
MemoryPreference = MediaCaptureMemoryPreference.Cpu,
StreamingCaptureMode = StreamingCaptureMode.Video
};
try
{
await mediaCapture.InitializeAsync(settings);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine("MediaCapture initialization failed: " + ex.Message);
return;
}
var colorFrameSource = mediaCapture.FrameSources[colorSourceInfo.Id];
Initialisieren des MediaFrameReader
Erstellen Sie als Nächstes einen MediaFrameReader für die RGB-Framequelle, die im vorherigen Schritt abgerufen wurde. Um eine gute Bildfrequenz aufrechtzuerhalten, sollten Sie Frames verarbeiten, die eine niedrigere Auflösung haben als die Auflösung des Sensors. In diesem Beispiel wird das optionale BitmapSize-Argument der MediaCapture.CreateFrameReaderAsync-Methode bereitgestellt, um anzufordern, dass frames, die vom Frameleser bereitgestellt werden, auf 640 x 480 Pixel geändert werden.
Registrieren Sie nach dem Erstellen des Framereaders einen Handler für das FrameArrived-Ereignis. Erstellen Sie dann ein neues SoftwareBitmapSource-Objekt , das von der FrameRenderer-Hilfsklasse verwendet wird, um das verarbeitete Bild darzustellen. Rufen Sie dann den Konstruktor für den FrameRenderer auf. Initialisieren Sie die Instanz der OpenCVHelper-Klasse, die in der OpenCVBridge-Windows-Runtime Komponente definiert ist. Diese Hilfsklasse wird im FrameArrived-Handler verwendet, um jeden Frame zu verarbeiten. Starten Sie schließlich den Frameleser, indem Sie StartAsync aufrufen.
BitmapSize size = new BitmapSize() // Choose a lower resolution to make the image processing more performant
{
Height = 480,
Width = 640
};
mediaFrameReader = await mediaCapture.CreateFrameReaderAsync(colorFrameSource, MediaEncodingSubtypes.Argb32, size);
mediaFrameReader.FrameArrived += ColorFrameReader_FrameArrived_OpenCV;
imageElement.Source = new SoftwareBitmapSource();
_frameRenderer = new FrameRenderer(imageElement);
await mediaFrameReader.StartAsync();
Behandeln des FrameArrived-Ereignisses
Das FrameArrived-Ereignis wird ausgelöst, wenn ein neuer Frame vom Frame-Reader verfügbar ist. Rufen Sie TryAcquireLatestFrame auf, um den Frame abzurufen, sofern vorhanden. Abrufen der SoftwareBitmap aus mediaFrameReference. Beachten Sie, dass für die in diesem Beispiel verwendete CVHelper-Klasse Bilder das BRGA8-Pixelformat mit prämultipliziertem Alpha verwenden müssen. Wenn der an das Ereignis übergebene Frame ein anderes Format aufweist, konvertieren Sie die SoftwareBitmap in das richtige Format. Erstellen Sie als Nächstes eine SoftwareBitmap , die als Ziel des Weichzeichnervorgangs verwendet werden soll. Die Quellbildeigenschaften werden als Argumente für den Konstruktor verwendet, um eine Bitmap mit übereinstimmendem Format zu erstellen. Rufen Sie die Hilfsklasse Blur-Methode auf, um den Frame zu verarbeiten. Übergeben Sie schließlich das Ausgabebild des Weichzeichnervorgangs an PresentSoftwareBitmap, die Methode der FrameRenderer-Hilfsklasse, die das Bild im XAML-Bildsteuerelement anzeigt, mit dem es initialisiert wurde.
private void ColorFrameReader_FrameArrived_OpenCV(MediaFrameReader sender, MediaFrameArrivedEventArgs args)
{
var mediaFrameReference = sender.TryAcquireLatestFrame();
if (mediaFrameReference != null)
{
SoftwareBitmap openCVInputBitmap = null;
var inputBitmap = mediaFrameReference.VideoMediaFrame?.SoftwareBitmap;
if (inputBitmap != null)
{
//The XAML Image control can only display images in BRGA8 format with premultiplied or no alpha
if (inputBitmap.BitmapPixelFormat == BitmapPixelFormat.Bgra8
&& inputBitmap.BitmapAlphaMode == BitmapAlphaMode.Premultiplied)
{
openCVInputBitmap = SoftwareBitmap.Copy(inputBitmap);
}
else
{
openCVInputBitmap = SoftwareBitmap.Convert(inputBitmap, BitmapPixelFormat.Bgra8, BitmapAlphaMode.Premultiplied);
}
SoftwareBitmap openCVOutputBitmap = new SoftwareBitmap(BitmapPixelFormat.Bgra8, openCVInputBitmap.PixelWidth, openCVInputBitmap.PixelHeight, BitmapAlphaMode.Premultiplied);
// operate on the image and render it
openCVHelper.Blur(openCVInputBitmap, openCVOutputBitmap);
_frameRenderer.PresentSoftwareBitmap(openCVOutputBitmap);
}
}
}
Zugehörige Themen
- Kamera
- Allgemeine Foto-, Video- und Audioaufnahme mit „MediaCapture“
- Verarbeiten von Medienframes mit „MediaFrameReader“
- Verarbeiten von Softwarebitmaps mit OpenCV
- Beispiel für Kameraframes
- Beispiel für Kameraframes + OpenCV