C#のOpenCvSharpでMatとBitmapSourceを変換する

C#でOpenCvSharpを使ったWPFアプリを作るときに、OpenCVのMAT形式とWPFのBitmapSourceを相互に変換する必要があります。

目次

  1. 環境
  2. MATをBitmapSourceに変換する
    1. ToBitmapSourceメソッド
    2. BitmapSourceへの変換を試してみる
  3. BitmapSourceをMatに変換する
    1. ToMatメソッド
    2. Matへの変換を試してみる

環境

本投稿で試した環境は下記です。

  • Windows10

  • Visual Studio Express 2017 for Windows Desktop

  • OpenCvSharp4

OpenCvSharp4にはMATとBitmapSourceを相互に変換する拡張機能があるのですが、本体とは別にOpenCvSharp4.WpfExtensionsとして提供されています。

ということで、WPFアプリを作る場合は、NuGetでプロジェクトにOpenCvSharp4.WpfExtensionsもインストールします。

MATをBitmapSourceに変換する

BitmapSourceConverterクラスのToBitmapSourceメソッドで変換をします。

ToBitmapSourceメソッド

dst = OpenCvSharp.WpfExtension.BitmapSourceConverter.ToBitmapSource(src)

変数

内容

src

OpenCvSharp.Mat

変換元のOpenCVのMAT形式のデータ

dst

BitmapSource

変換後のBitmapSource形式のビットマップデータ

BitmapSourceへの変換を試してみる

プロ生ちゃん の画像をMat形式で読み込んで、Imageコントロールに表示してみます。

サンプル画像

XAMLです。

<Window x:Class="test.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:test"
        mc:Ignorable="d"
        Title="MainWindow" Height="300" Width="300">
    <Grid>
        <Image Name="imgView" Stretch="None" />
    </Grid>
</Window>

ウィンドウにImageコントロールを付けただけです。

コードはこのようにします。

using System.Windows.Media.Imaging;
using OpenCvSharp;
using OpenCvSharp.WpfExtensions;

namespace test
{
    public partial class MainWindow : System.Windows.Window
    {
        public MainWindow()
        {
            InitializeComponent();

            Mat src = new Mat("test.png", ImreadModes.Color);
            BitmapSource bmpsrc = BitmapSourceConverter.ToBitmapSource(src);
            imgView.Source = bmpsrc;

            src.Dispose();
        }
    }
}

実行するとこのようなウィンドウが表示されます。

Imageコントロールで表示した例

OpenCVのデータをImageコントロールに表示できました。

BitmapSourceをMatに変換する

逆に、BitmapSourceをMatに変換してみます。

ToMatメソッド

dst = OpenCvSharp.WpfExtensions.BitmapSourceConverter.ToMat(src);

変数

内容

src

BitmapSource

変換元のBitmapSource形式のビットマップデータ

dst

OpenCvSharp.Mat

変換後のOpenCVのMat形式のデータ

Matへの変換を試してみる

サンプル画像を読み込んでBitmapSourceにしたものを、Mat形式に変換してOpenCvSharpのimshowメソッドで表示してみます。

XAMLはこのようにしました。Imageコントロールに読み込んだBitmapSourceをそのまま表示します。

<Window x:Class="test.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:test"
        mc:Ignorable="d"
        Title="MainWindow" Height="300" Width="300">
    <Grid>
        <Image Name="imgView" Stretch="None" />
    </Grid>
</Window>

コードはこのようにしました。

using System.Windows.Media.Imaging;
using OpenCvSharp;
using OpenCvSharp.WpfExtensions;
using System.IO;

namespace test
{
    public partial class MainWindow : System.Windows.Window
    {
        public MainWindow()
        {
            InitializeComponent();

            Stream fs = new FileStream("test.png", FileMode.Open, FileAccess.Read, FileShare.Read);
            PngBitmapDecoder decoder = new PngBitmapDecoder(fs, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
            BitmapSource bmpsrc = decoder.Frames[0];
            imgView.Source = bmpsrc;

            Mat src = BitmapSourceConverter.ToMat(bmpsrc);
            Cv2.ImShow("Test", src);
        }
    }
}

サンプル画像がPNGなので、デーコーダーを通しています。

実行すると、このようにウィンドウが2つ表示されます。大きい方はアプリでImageコントロールに表示しているもので、小さい方はimshowメソッドで表示したものです。大きさが異なるのはHiDPIの影響だと思います。

Matへの変換結果

公開日

広告