Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Artikel ini memperlihatkan cara membuat komponen Windows Runtime C++/WinRT asli yang mengonversi objek SoftwareBitmap ke jenis OpenCVMat. Ini memungkinkan Anda menggunakan algoritma pemrosesan gambar OpenCV yang luas pada bingkai yang diambil dengan API kamera Windows dan menampilkan hasilnya di aplikasi WinUI 3 Anda.
Overview
Kelas SoftwareBitmap adalah format gambar umum yang digunakan oleh API media Windows, sementara OpenCV menggunakan Mat kelas . Untuk menjembatani format ini, Anda membuat komponen runtime C++/WinRT yang:
- Menerima input
SoftwareBitmap. - Mengonversinya menjadi OpenCV
Mat. - Menerapkan pemrosesan gambar yang diinginkan.
- Mengembalikan hasil sebagai
SoftwareBitmap.
Karena OpenCV adalah pustaka C++ asli, Anda menggunakan proyek C++/WinRT Windows Runtime Component untuk membuat jembatan. Aplikasi C# WinUI 3 Anda mereferensikan komponen ini.
Menyiapkan proyek komponen C++/WinRT
Di Visual Studio, tambahkan proyek komponen Windows Runtime baru (C++/WinRT) ke solusi Anda. Beri nama sesuatu seperti
OpenCVBridge.Unduh paket OpenCV NuGet dengan menjalankan perintah berikut di Konsol Package Manager yang menargetkan proyek jembatan:
Install-Package OpenCV.Windows -ProjectName OpenCVBridgeAtau, unduh rilis OpenCV dari opencv.org dan konfigurasikan secara manual jalur penyertaan dan jalur pustaka proyek Anda.
Di proyek
pch.hjembatan , tambahkan header OpenCV:#include <opencv2/core.hpp> #include <opencv2/imgproc.hpp> #include <robuffer.h> #include <windows.foundation.h>
Membuat kelas runtime OpenCVHelper
Tentukan kelas runtime yang menyediakan metode untuk mengonversi antara SoftwareBitmap dan OpenCV Mat. Buat file OpenCVHelper.idlIDL :
// OpenCVHelper.idl
namespace OpenCVBridge
{
runtimeclass OpenCVHelper
{
OpenCVHelper();
void ProcessBitmap(
Windows.Graphics.Imaging.SoftwareBitmap input,
Windows.Graphics.Imaging.SoftwareBitmap output);
}
}
Menerapkan konversi
Dalam OpenCVHelper.cpp, terapkan konversi dari SoftwareBitmap ke Mat dan kembali:
#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
Kode di atas menggunakan IMemoryBufferByteAccess untuk mengakses data piksel mentah. Objek input dan output SoftwareBitmap harus menggunakan Bgra8 format piksel. Jika bingkai dari MediaFrameReader menggunakan format yang berbeda, konversikan terlebih dahulu dengan SoftwareBitmap.Convert.
Menggunakan komponen dari C#
Di aplikasi C# WinUI 3 Anda, tambahkan referensi proyek ke OpenCVBridge komponen. Kemudian panggil ProcessBitmap dari kode pemrosesan bingkai Anda:
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;
});
}
Menambahkan lebih banyak operasi pemrosesan
Anda dapat memperluas OpenCVHelper kelas dengan metode tambahan untuk operasi tertentu. Perbarui IDL dan implementasi:
// 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);
}
Konten terkait
Windows developer