В этом примере показано, как выполнить получение изображений от веб-камеры и постобработать данные параллельно.
В этом примере клиент MATLAB получает системы координат от видеоустройства и затем разгружает постобработку, чтобы быть параллельным рабочим, которые фильтруют от шума от каждой системы координат с помощью нейронной сети шумоподавления. Системы координат затем записаны в видео.
В этом примере вы используете parfeval
выполнять постобработку в рабочих и parallel.pool.Constant
инстанцировать сети шумоподавления в рабочих, чтобы использоваться во время постобработки. Чтобы передать системы координат обратно от рабочих и гарантировать, что они написаны в порядке, этот пример использует OrderedDataQueue
объект.
Очистите предыдущие объекты получения изображений и извлеките информацию о видеоустройстве, в настоящее время соединенном с машиной.
objects = imaqfind;
delete(objects);
imaqreset;
deviceInfo = imaqhwinfo('winvideo')
deviceInfo = struct with fields:
AdaptorDllName: 'adaptor.dll'
AdaptorDllVersion: '6.1 (R2019b)'
AdaptorName: 'winvideo'
DeviceIDs: {[1]}
DeviceInfo: [1×1 struct]
Проверяйте, существует ли папка для выходного видео уже в текущем каталоге. Если никакая папка для выходного видео не существует, создайте тот.
if ~isfolder('OutputFolder') mkdir OutputFolder end
Чтобы записать видеоданные в файл AVI в выходной папке, создайте VideoWriter
объект.
videoOut = VideoWriter('OutputFolder/myVideo.avi');
Чтобы включить разгрузку постобработки рабочим, сначала запустите параллельный пул.
p = parpool('local');
Starting parallel pool (parpool) using the 'local' profile ... Connected to the parallel pool (number of workers: 6).
Создайте parallel.pool.Constant
объект создать сеть шумоподавления только однажды в рабочих и использовать его, чтобы фильтровать шум от систем координат.
C = parallel.pool.Constant(@() denoisingNetwork('dncnn'));
Чтобы передать постобработанные системы координат обратно от рабочих и написать им в порядке, используйте OrderedDataQueue
. Установите коллбэк писать системы координат в диск при помощи afterEach
.
Q = OrderedDataQueue; afterEach(Q,@(frame) writeVideo(videoOut,frame));
OrderedDataQueue
объект задан во вспомогательном файле к этому примеру. Если вы хотите использовать его в своем собственном коде, скопируйте и поместить его с остальной частью ваших файлов.
Создайте объект ввода видео. Установите объект выполнить захват в клиентской системе координат системой координат.
videoIn = videoinput('winvideo',1,'YUY2_800x600')
Summary of Video Input Object Using 'Microsoft® LifeCam Cinema(TM)'. Acquisition Source(s): input1 is available. Acquisition Parameters: 'input1' is the current selected source. 10 frames per trigger using the selected source. 'YUY2_800x600' video data to be logged upon START. Grabbing first of every 1 frame(s). Log data to 'memory' on trigger. Trigger Parameters: 1 'immediate' trigger(s) on START. Status: Waiting for START. 0 frames acquired since starting. 0 frames available for GETDATA.
videoIn.ReturnedColorSpace = 'RGB';
videoIn.FramesPerTrigger = Inf;
videoIn.FramesAcquiredFcnCount = 1;
Установите видео, пишущий частоту кадров в тот же уровень что касается видео чтения и откройте объект видеовыхода.
src = videoIn.Source; videoOut.FrameRate = str2double(src.FrameRate); open(videoOut);
Чтобы начать постобрабатывать операции после, каждая система координат получена, задайте FramesAcquiredFcn
коллбэк для ввода видео возражает и запускает захват.
videoIn.FramesAcquiredFcn = {@postProcessAndWrite,C,Q}; start(videoIn);
Создайте окно предварительного просмотра. Можно остановить видео, как только предварительный просмотр вручную закрывается при помощи waitfor
на фигуре обрабатывают hPreviewFig
. В данном примере остановите видео захват после 2 секунд.
hPreviewImg = preview(videoIn);
hPreviewFig = ancestor(hPreviewImg,'figure');
pause(2);
stop(videoIn);
Функция постобработки хранит будущую переменную в UserData
свойство видео объекта. Эта переменная представляет будущее выполнение видео операций записи. Чтобы закрыть видео средство записи после, все данные записаны в выходной файл, используйте afterAll
на этой будущей переменной.
postProcessFutures = videoIn.UserData; closeVideoFuture = afterAll(postProcessFutures,@() close(videoOut),0);
Операция постобработки в этом примере, может занять несколько минут. На Windows 10, центральном процессоре Intel® Xeon® W-2133 3.60 GHz, с 6 ядрами, постобработка заняла 4 минуты.
Можно использовать waitbar, чтобы отследить прогресс постобработки. Чтобы обновить waitbar после каждой операции постобработки концы, используйте afterEach
. Чтобы закрыть waitbar после всего конца операций, используйте afterAll
. Для получения дополнительной информации смотрите Пользовательский интерфейс Обновления Асинхронно Используя afterEach и afterAll.
h = waitbar(0,'Postprocessing...'); updateWaitbarFuture = afterEach(postProcessFutures, ... @(~) waitbar(sum(strcmp('finished',{postProcessFutures.State}))/numel(postProcessFutures),h), 1); afterAll(closeVideoFuture, @() close(h),0);
Блокируйте выполнение на клиентском сеансе до концов записи путем ожидания будущей переменной.
wait(closeVideoFuture);
Удалите объект ввода видео по окончании.
delete(videoIn);
После того, как видеофайл был создан, можно визуализировать результаты.
Используйте VideoReader
возразите, чтобы считать видеофайл.
vidObj = VideoReader('OutputFolder/MyVideo.avi');
Считайте некоторые системы координат при помощи readFrame
функция.
images = cell(1,5); times = .4:.4:2; for ii = 1:numel(times) vidObj.CurrentTime = times(ii); images{ii} = readFrame(vidObj); end
Чтобы визуализировать системы координат, используйте montage
функция.
montage(images,'Size',[1 5])
Задайте основную стандартную программу постобработки, которая выполняется после каждого захвата системы координат. Этот функциональный postProcessAndWrite
выбирает данные из объекта ввода видео и вызывает parfeval
запустить шумоподавление системы координат в параллельном рабочем.
function postProcessAndWrite(videoIn,~,C,Q) [frame,~,metadata] = getdata(videoIn,1); postProcessFuture = parfeval(@postProcess,0,frame,C,Q,metadata.FrameNumber); videoIn.UserData = [videoIn.UserData postProcessFuture]; end
Задайте функцию постобработки, которая будет выполняться в рабочем. В данном примере, чтобы упростить расчет, преобразуйте каждую систему координат в серый, и затем denoise это при помощи denoiseImage
функция. Функциональный postProcess
берет систему координат и сетевой объект шумоподавления, хранивший в Value
поле parallel.pool.Constant
возразите как входные параметры. Для получения дополнительной информации об изображениях шумоподавления с нейронной сетью шумоподавления смотрите, Получают Предварительно обученную Сеть Шумоподавления Изображений (Image Processing Toolbox).
function postProcess(frame,C,Q,frameNumber) grayFrame = im2double(rgb2gray(frame)); denoisedGrayFrame = denoiseImage(grayFrame,C.Value); denoisedGrayFrame = im2uint8(denoisedGrayFrame); send(Q,frameNumber,denoisedGrayFrame) end
parfeval
| parallel.pool.Constant
| imaqfind
(Image Acquisition Toolbox) | videoinput
(Image Acquisition Toolbox) | FramesAcquiredFcn
(Image Acquisition Toolbox) | VideoWriter
| afterAll
| afterEach
| denoiseImage
(Image Processing Toolbox)