Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Den här artikeln visar hur du skapar en inbyggd C++/WinRT-Windows Runtime komponent som konverterar SoftwareBitmap-objekt till OpenCV-typenMat. På så sätt kan du använda OpenCV:s omfattande bildbearbetningsalgoritmer på bildrutor som avbildats med Windows kamera-API:er och visa resultatet i din WinUI 3-app.
Översikt
Klassen SoftwareBitmap är det vanliga bildformat som används av Windows medie-API:er, medan OpenCV använder Mat klassen. Om du vill överbrygga dessa format skapar du en C++/WinRT-körningskomponent som:
- Tar emot
SoftwareBitmapsom indata. - Konverterar den till en OpenCV
Mat. - Tillämpar önskad bildbearbetning.
- Returnerar resultatet som en
SoftwareBitmap.
Eftersom OpenCV är ett internt C++-bibliotek använder du ett C++/WinRT-Windows Runtime komponentprojekt för att skapa bryggan. Din C# WinUI 3-app refererar till den här komponenten.
Konfigurera C++/WinRT-komponentprojektet
I Visual Studio lägger du till ett nytt Windows Runtime komponentprojekt (C++/WinRT) i din lösning. Ge den ett namn i stil med
OpenCVBridge.Ladda ned OpenCV NuGet-paketet genom att köra följande kommando i Správca balíkov Console som är riktat mot bridgeprojektet:
Install-Package OpenCV.Windows -ProjectName OpenCVBridgeDu kan också ladda ned OpenCV-versionen från opencv.org och konfigurera projektets inkluderings- och bibliotekssökvägar manuellt.
I bridgeprojektets
pch.hlägger du till OpenCV-huvudena:#include <opencv2/core.hpp> #include <opencv2/imgproc.hpp> #include <robuffer.h> #include <windows.foundation.h>
Skapa OpenCVHelper-körningsklassen
Definiera en körningsklass som innehåller metoder för att konvertera mellan SoftwareBitmap och OpenCV Mat. Skapa IDL-filen OpenCVHelper.idl:
// OpenCVHelper.idl
namespace OpenCVBridge
{
runtimeclass OpenCVHelper
{
OpenCVHelper();
void ProcessBitmap(
Windows.Graphics.Imaging.SoftwareBitmap input,
Windows.Graphics.Imaging.SoftwareBitmap output);
}
}
Implementera konverteringen
I OpenCVHelper.cppimplementerar du konverteringen från SoftwareBitmap till Mat och tillbaka:
#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
Koden ovan använder IMemoryBufferByteAccess för att komma åt råa pixeldata. Indata- och utdataobjekten SoftwareBitmapBgra8 måste använda pixelformatet. Om bildrutor från MediaFrameReader använder ett annat format konverterar du dem först med SoftwareBitmap.Convert.
Använda komponenten från C#
I din C# WinUI 3-app lägger du till en projektreferens till komponenten OpenCVBridge . Anropa sedan ProcessBitmap från din kod för bildramsbearbetning:
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;
});
}
Lägga till fler bearbetningsåtgärder
Du kan utöka OpenCVHelper klassen med ytterligare metoder för specifika åtgärder. Uppdatera IDL och implementeringen:
// 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);
}
Relaterat innehåll
Windows developer