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 eine systemeigene C++/WinRT-Windows-Runtime Komponente erstellen, die SoftwareBitmap-Objekte in den OpenCV-Typ Mat konvertiert. Auf diese Weise können Sie die umfangreichen Bildverarbeitungsalgorithmen von OpenCV für Frames verwenden, die mit den Windows Kamera-APIs aufgenommen wurden, und die Ergebnisse in Ihrer WinUI 3-App anzeigen.
Übersicht
Die SoftwareBitmap Klasse ist das gängige Bildformat, das von Windows Medien-APIs verwendet wird, während OpenCV die Mat Klasse verwendet. Um diese Formate zu überbrücken, erstellen Sie eine C++/WinRT-Laufzeitkomponente, die:
- Akzeptiert eine
SoftwareBitmapEingabe. - Wandelt sie in ein OpenCV
Mat-Element um. - Wendet die gewünschte Bildverarbeitung an.
- Gibt das Ergebnis als ein
SoftwareBitmap.
Da OpenCV eine systemeigene C++-Bibliothek ist, verwenden Sie ein C++/WinRT-Windows-Runtime Component-Projekt, um die Brücke zu erstellen. Ihre C# WinUI 3-App verweist auf diese Komponente.
Einrichten des C++/WinRT-Komponentenprojekts
Fügen Sie in Visual Studio Ihrer Lösung ein neues Windows-Runtime Component -Projekt (C++/WinRT) hinzu. Nennen Sie es etwa wie
OpenCVBridge.Laden Sie das OpenCV NuGet-Paket herunter, indem Sie den folgenden Befehl in der Paket-Manager Konsole für das Brückenprojekt ausführen:
Install-Package OpenCV.Windows -ProjectName OpenCVBridgeAlternativ können Sie die OpenCV-Version von opencv.org herunterladen und die Einschließen- und Bibliothekspfade Ihres Projekts manuell konfigurieren.
Fügen Sie im Bridge-Projekt
pch.hdie OpenCV-Header hinzu:#include <opencv2/core.hpp> #include <opencv2/imgproc.hpp> #include <robuffer.h> #include <windows.foundation.h>
Erstellen der OpenCVHelper-Laufzeitklasse
Definieren Sie eine Laufzeitklasse, die Methoden zum Konvertieren zwischen SoftwareBitmap und OpenCV Matbereitstellt. Erstellen Sie die IDL-Datei OpenCVHelper.idl:
// OpenCVHelper.idl
namespace OpenCVBridge
{
runtimeclass OpenCVHelper
{
OpenCVHelper();
void ProcessBitmap(
Windows.Graphics.Imaging.SoftwareBitmap input,
Windows.Graphics.Imaging.SoftwareBitmap output);
}
}
Implementieren der Konvertierung
Implementieren Sie in OpenCVHelper.cpp die Konvertierung von SoftwareBitmap zu Mat und zurück:
#include "pch.h"
#include "OpenCVHelper.h"
#include "OpenCVHelper.g.cpp"
#include <opencv2/imgproc.hpp>
using namespace winrt;
using namespace Windows::Graphics::Imaging;
namespace winrt::OpenCVBridge::implementation
{
void OpenCVHelper::ProcessBitmap(
SoftwareBitmap const& input,
SoftwareBitmap const& output)
{
// Lock the input buffer for reading
auto inputBuffer = input.LockBuffer(
BitmapBufferAccessMode::Read);
auto inputRef = inputBuffer.CreateReference();
uint8_t* inputData = nullptr;
uint32_t inputSize = 0;
winrt::check_hresult(
inputRef.as<::Windows::Foundation::
IMemoryBufferByteAccess>()->GetBuffer(
&inputData, &inputSize));
auto inputDesc =
inputBuffer.GetPlaneDescription(0);
// Create a Mat from the input data (use Stride for correct row size)
cv::Mat inputMat(
inputDesc.Height,
inputDesc.Width,
CV_8UC4,
inputData,
inputDesc.Stride);
// Lock the output buffer for writing
auto outputBuffer = output.LockBuffer(
BitmapBufferAccessMode::Write);
auto outputRef = outputBuffer.CreateReference();
uint8_t* outputData = nullptr;
uint32_t outputSize = 0;
winrt::check_hresult(
outputRef.as<::Windows::Foundation::
IMemoryBufferByteAccess>()->GetBuffer(
&outputData, &outputSize));
auto outputDesc =
outputBuffer.GetPlaneDescription(0);
cv::Mat outputMat(
outputDesc.Height,
outputDesc.Width,
CV_8UC4,
outputData,
outputDesc.Stride);
// Apply image processing - example: blur
cv::GaussianBlur(inputMat, outputMat, cv::Size(15, 15), 5);
}
}
Note
Der obige Code verwendet IMemoryBufferByteAccess, um auf die Rohpixeldaten zuzugreifen. Die Eingabe- und Ausgabeobjekte SoftwareBitmap müssen das Bgra8 Pixelformat verwenden. Wenn Frames aus MediaFrameReader einem anderen Format stammen, konvertieren Sie sie zuerst mit SoftwareBitmap.Convert.
Verwenden der Komponente von C#
Fügen Sie in Ihrer C#WinUI 3-App einen Projektverweis auf die OpenCVBridge Komponente hinzu. Rufen Sie dann ProcessBitmap in Ihrem Frame-Verarbeitungscode auf:
using OpenCVBridge;
using Windows.Graphics.Imaging;
private readonly OpenCVHelper _openCVHelper = new();
private void ProcessFrameWithOpenCV(
SoftwareBitmap inputBitmap)
{
// Ensure the bitmap is in Bgra8 format
if (inputBitmap.BitmapPixelFormat != BitmapPixelFormat.Bgra8)
{
inputBitmap = SoftwareBitmap.Convert(
inputBitmap, BitmapPixelFormat.Bgra8);
}
// Create an output bitmap with the same dimensions
var outputBitmap = new SoftwareBitmap(
BitmapPixelFormat.Bgra8,
inputBitmap.PixelWidth,
inputBitmap.PixelHeight,
BitmapAlphaMode.Premultiplied);
// Process with OpenCV
_openCVHelper.ProcessBitmap(inputBitmap, outputBitmap);
// Display the result
DispatcherQueue.TryEnqueue(async () =>
{
var source =
new Microsoft.UI.Xaml.Media.Imaging
.SoftwareBitmapSource();
await source.SetBitmapAsync(outputBitmap);
OutputImage.Source = source;
});
}
Hinzufügen weiterer Verarbeitungsvorgänge
Sie können die OpenCVHelper Klasse um zusätzliche Methoden für bestimmte Vorgänge erweitern. IdL und Implementierung aktualisieren:
// Add to OpenCVHelper.idl
void ApplyCannyEdges(
Windows.Graphics.Imaging.SoftwareBitmap input,
Windows.Graphics.Imaging.SoftwareBitmap output,
Double threshold1,
Double threshold2);
// Implementation
void OpenCVHelper::ApplyCannyEdges(
SoftwareBitmap const& input,
SoftwareBitmap const& output,
double threshold1,
double threshold2)
{
// ... lock buffers as above ...
cv::Mat grayMat;
cv::cvtColor(inputMat, grayMat, cv::COLOR_BGRA2GRAY);
cv::Mat edges;
cv::Canny(grayMat, edges, threshold1, threshold2);
cv::cvtColor(edges, outputMat, cv::COLOR_GRAY2BGRA);
}
Verwandte Inhalte
Windows developer