Задача сделать снимки с веб-камеры без дисплея - PullRequest
0 голосов
/ 26 февраля 2019

Я хочу делать снимки с веб-камеры в Windows с помощью DirectShow.Эти снимки будут сохранены на диск без отображения этих изображений.Я хочу запустить процесс снимка, который делает снимок каждую секунду, пока я не остановлю его, пока основной процесс продолжается.

Поэтому я выбираю И еще один элемент управления веб-камерой для DirectShow, чтобы использовать его сC #, и демонстрация работает нормально.
Но у меня возникла проблема, когда я использую обертку в своей задаче, я получаю типичную ошибку потоков The calling thread cannot access this object because a different thread owns it.

Код вызова выглядит так:

Task.Run(() =>
{
    using (var cam1 = new SnapshotCam(camList.First(), "person", webCameraControl))
    {
        // Act
        Bitmap image = null;
        if (!cam1._wcc.IsCapturing)
        {
            cam1._wcc.StartCapture(cam1._cameraId);
            Task.Delay(500).Wait();
        }
        image = cam1._wcc.GetCurrentImage();
        // Assert
        Assert.NotNull(image);
    }
}).Wait();

Трудным для меня объектом является webCameraControl, хранящийся в cam1._wcc: этот объект наследуется от System.Windows.Controls.UserControl и может быть присоединен к пользовательскому интерфейсу.Но в моем случае у меня нет никакого пользовательского интерфейса, снимки должны быть сделаны в «безголовом» стиле.

Так что проблема начинается, когда я хочу использовать _wcc -объект.Я уже пытался вызвать _wcc.Dispatcher для соответствующего потока, но не удалось.

Как я могу вызвать приведенный выше код в собственной задаче / потоке, независимом от остальной части кода?

Ответы [ 2 ]

0 голосов
/ 27 февраля 2019

Проблема, с которой вы столкнулись, связана с многопоточностью, но в конечном итоге это был неудачный выбор библиотеки для захвата с веб-камеры.Вам не нужно отображать кадры камеры, но библиотека реализует фотоснимки путем рендеринга видеопотока на устройство Direct3D (вид презентации, даже если он «невидим») с копированием последнего известного кадра по запросу.

Возможно, вам лучше выбрать DxSnap пример приложения из пакета DirectShow.NET.Даже если он не идеален:

  • он извлекает данные кадра с помощью Sample Grabber без необходимости отображения фильтра
  • показывает, как точно передавать данные между потоками, см. Здесь
  • вы избежите чрезмерных осложнений благодаря многослойной библиотеке внешнего управления

См. Также:

0 голосов
/ 26 февраля 2019

Если у вас нет пользовательского интерфейса, то вам, вероятно, не нужно заключать код в Task.Run, если только вы не пытаетесь сделать что-то одновременно во время его работы - и поскольку вы не используете await, он не't / look / like это так.

Если вы хотите сохранить его в Task.Run, то в своей форме вы будете использовать метод Invoke, который позволит вам получить доступ к элементу управления камерой в правильном потоке, однако я неПосмотрите, как это решит проблему асинхронного запуска.

Если вы не используете элемент управления в качестве фактического элемента пользовательского интерфейса, я не понимаю, почему вы не можете создать его в отдельном потоке и использовать в этом потоке, хотя это не звучит таккак он предназначен для использования.

...