Выполните сбор изображений и параллельную обработку изображений

В этом примере показано, как выполнить сбор изображений из веб-камеры и последующую обработку данных параллельно.

В этом примере клиент 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));

The 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 ГГц с 6 ядрами для постобработки потребовалось 4 минуты.

Можно использовать waitbar для отслеживания прогресса постобработки. Чтобы обновить панель ожидания после концов каждой операции постобработки, используйте afterEach. Чтобы закрыть панель ожидания после конца всех операций, используйте 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

Определите функцию постобработки, которая должна выполняться в рабочем процессе. В данном примере, чтобы упростить расчеты, преобразуйте каждую систему координат в серый, а затем денуризируйте его с помощью denoiseImage функция. Функция postProcess принимает систему координат и деноизирующий сетевой объект, сохраненный в Value поле parallel.pool.Constant объект как входы. Для получения дополнительной информации о шумоподавлении изображений с помощью обесценивающей нейронной сети, смотрите Get Pretrained Image Denoising Network (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

См. также

| | | | | (Image Acquisition Toolbox) | (Image Acquisition Toolbox) | (Image Acquisition Toolbox) | (Набор Image Processing Toolbox)

Похожие примеры

Подробнее о