Image Control не показывает кадры веб-камеры, снятые с помощью OpenCVsharp

Я написал код ниже в своем коде XAML, чтобы показать кадры веб-камеры, полученные как Mat с помощью метода Opencvsharp VideoCapture.Read() в моем элементе управления изображением с именем View.

Mat mat = new Mat();
VideoCapture videoCapture = new VideoCapture(2);

while (true)
{
    videoCapture.Read(mat);
    viewer.Source = mat.ToBitmapImage();
    if (btn_stop.IsPressed)
    {
        break;
    }
}
videoCapture.Release();

Как вы можете видеть, я использовал конвертер для преобразования формы Mat в BitmapImage, чтобы я мог использовать его в качестве источника изображения для моего элемента управления. вот преобразователи, которые я использовал:

static class Converters
{
    public static BitmapImage ToBitmapImage(this Bitmap bitmap)
    {
        BitmapImage bi = new BitmapImage();
        MemoryStream ms = new MemoryStream();
        bi.BeginInit();
        bitmap.Save(ms, ImageFormat.Bmp);
        ms.Seek(0, SeekOrigin.Begin);
        bi.StreamSource = ms;
        bi.EndInit();
        bi.Freeze();
        return bi;
    }

    public static BitmapImage ToBitmapImage(this Mat mat)
    {
        return BitmapConverter.ToBitmap(mat).ToBitmapImage();
    }
}  

Просто этот код ничего не показывает в моем элементе управления изображением, и приложение зависает. Я знаю, что этот код генерирует слишком много мусора, и я ничего не могу с этим поделать. Любые идеи о моей проблеме? Я также изменил свой код с помощью инструкций, приведенных в этой ссылке, как показано ниже:

viewer.Source = (BitmapSource)new ImageSourceConverter().ConvertFrom(mat.ToBytes());  

а также эти преобразователи:

public static BitmapImage ToBitmapImage(this Mat mat)
        {
            BitmapImage image = new BitmapImage();
            image.BeginInit();
            image.StreamSource = new System.IO.MemoryStream(mat.ToBytes());
            image.EndInit();
            return image;
        }

public static BitmapImage ToBitmapImage(this Mat mat)
        {
            using (var ms = new System.IO.MemoryStream(mat.ToBytes()))
            {
                var image = new BitmapImage();
                image.BeginInit();
                image.CacheOption = BitmapCacheOption.OnLoad;
                image.StreamSource = ms;
                image.EndInit();
                return image;
            }
        }

ни один из них не работал для меня.


person Alireza0772    schedule 29.01.2018    source источник
comment
Также установите bi.CacheOption = BitmapCacheOption.OnLoad;   -  person Clemens    schedule 29.01.2018
comment
@Clemens Я использовал все инструкции, которые вы и другие упомянули в ссылке, которую вы указали, что мой вопрос является точной копией! ни один из них не работал для меня. я отредактирую свой вопрос и напишу изменения!   -  person Alireza0772    schedule 30.01.2018
comment
Ваш цикл while (true) блокирует поток пользовательского интерфейса. Вместо этого используйте таймер, например. DispatcherTimer.   -  person Clemens    schedule 30.01.2018
comment
да, это сработало. Tnx @Clemens   -  person Alireza0772    schedule 30.01.2018


Ответы (1)


Вот ответ в соответствии с комментарием Clemens:
Просто создайте объект DispatcherTimer в конструкторе MainWindow и используйте событие Tick для обновления пользовательского интерфейса:

DispatcherTimer Timer = new DispatcherTimer();  
Timer.Tick += Timer_Tick;  
Timer.Interval = TimeSpan.FromMilliseconds(30);  
Timer.Start();

private void Timer_Tick(object sender, EventArgs e)
{
    if (videoCapture.Read(frame))
    {
        view.Source = OpenCvSharp.Extensions.BitmapSourceConverter.ToBitmapSource(frame);
    }
}
person Alireza0772    schedule 14.10.2018