Процесс большой набор изображений Используя MapReduce Framework и Hadoop

В этом примере показано, как выполнить алгоритм подсчета клеток на большом количестве изображений с помощью Image Processing Toolbox с MapReduce MATLAB® и Datastore. MapReduce является методом программирования для анализа наборов данных, которые не умещаются в памяти. Пример также использует MATLAB Parallel Server™, чтобы идти параллельно программы MapReduce на кластерах Hadoop®. Пример показывает, как протестировать ваш алгоритм в локальной системе на подмножестве изображений прежде, чем переместить его в кластер Hadoop.

Загрузите выборочные данные

Загрузите набор данных BBBC005v1 из Широкого Набора Сравнительного теста Биоизображений. Этот набор данных является аннотируемым биологическим набором изображений, спроектированным для тестирования и валидации. Набор изображений обеспечивает примеры в - и расфокусированные синтетические изображения, которые могут использоваться в валидации метрик особого внимания. Набор данных содержит почти 20 000 файлов. Для получения дополнительной информации смотрите это введение в набор данных.

При системном приглашении в системе Linux используйте wget команда, чтобы загрузить zip-файл, содержащий набор данных BBBC. Прежде, чем запустить эту команду, убедитесь, что ваше целевое местоположение имеет достаточно пробела, чтобы содержать zip-файл (1,8 Гбайт) и извлеченные изображения (2,6 Гбайт).

wget http://www.broadinstitute.org/bbbc/BBBC005/BBBC005_v1_images.zip

При системном приглашении в системе Linux извлеките файлы из zip-файла.

unzip BBBC005_v1_images.zip

Исследуйте имена файла образа в этом наборе данных. Имена создаются в определенном формате, чтобы содержать полезную информацию о каждом изображении. Например, имя файла BBBC005_v1_images/SIMCEPImages_A05_C18_F1_s16_w1.TIF указывает, что изображение содержит 18 ячеек (C18) и был отфильтрован с Гауссовым фильтром lowpass с диаметром 1 и сигма 0.25x диаметр, чтобы симулировать размытость особого внимания (F1). w1 идентифицирует используемую окраску. Например, найдите количество изображений в наборе данных, которые используют w1 окраска.

d = dir('C:\Temp\BBBCdata\BBBC005_v1_images\*w1*');
numel(d)
ans = 9600

Загрузите файлы изображений в Image Batch Processor

Просмотрите файлы в наборе данных BBBC и протестируйте алгоритм на небольшом подмножестве файлов с помощью приложения Image Batch Processor. Пример тестирует простой алгоритм, который сегментирует ячейки в изображениях. (Пример использует модифицированную версию этого алгоритма сегментации ячейки, чтобы создать алгоритм подсчета клеток, используемый в реализации MapReduce.)

Откройте приложение Image Batch Processor. От панели инструментов MATLAB, на вкладке Apps, в разделе Image Processing и Computer Vision, нажимают Image Batch Processor. Можно также открыть приложение из командной строки с помощью imageBatchProcessor команда.

В приложении Image Batch Processor нажмите Load Images и перейдите к папке, в которой вы сохранили загруженный набор данных.

Миниатюры отображений приложения Image Batch Processor изображений в папке на левой панели и версии более высокого разрешения в настоящее время выбранного изображения во вкладке Input Image. Просмотрите некоторые изображения, чтобы познакомиться с набором данных.

Задайте функцию сегментации

Задайте имя функции, которое реализует ваш алгоритм сегментации ячейки. Чтобы задать существующую функцию, введите ее имя в поле Имени функции или кликните по значку папки, чтобы просмотреть и выбрать функцию. Чтобы создать новую функцию пакетной обработки данных, нажмите New. Приложение открывает пакетный шаблон функции в редакторе MATLAB®. В данном примере создайте новую функцию, содержащую следующий код сегментации изображений. Нажмите Save, чтобы создать пакетную функцию. Обновления приложения, чтобы отобразить имя функции вы создали в разделе Batch Function панели инструментов приложения.

function imout = cellSegmenter(im)  % A simple cell segmenter 
    % Otsu thresholding
    bw = imbinarize(im);
    
    % Show thresholding result in app
    imout = imfuse(im,bw);
    
    % Find area of blobs
    stats = regionprops('table',bw,{'Area'});
    
    % Average cell diameter is about 33 pixels (based on random inspection)
    cellArea = pi*(33/2)^2;
    
    % Estimate cell count based on area of blobs
    cellsPerBlob = stats.Area/cellArea;
    cellCount = sum(round(cellsPerBlob));
    disp(cellCount);
end

Протестируйте свою функцию сегментации на демонстрационном изображении

Выберите миниатюру изображения, отображенного в приложении, и нажмите Process Selected, чтобы выполнить тестовый прогон вашего алгоритма. В данном примере выберите только изображение с “w1” окраска (идентифицирующийся в имени файла). Алгоритм сегментации работает лучше всего с этими изображениями.

Исследуйте результаты выполнения вашего алгоритма, чтобы проверить, что ваш алгоритм сегментации нашел правильное количество ячеек в изображении. Имена изображений содержат количество клеток в C номер. Например, изображение под названием SIMCEPImages_A05_C18_F1_s05_w1.TIF содержит 18 ячеек. Сравните этот номер с результатами, возвращенными в командной строке для демонстрационного изображения.

Протестируйте свою среду MapReduce локально

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

Во-первых, создайте datastore изображений, с помощью ImageDatastore функция, содержа небольшое подмножество ваших изображений. MapReduce использует datastore, чтобы обработать данные в маленьких фрагментах, которые индивидуально помещаются в память. Переместитесь в папку, содержащую изображения, и создайте datastore изображений. Поскольку алгоритм сегментации ячейки реализован в cellSegmenter.m работает лучше всего с окраской клеточного тела, выберите только файлы с индикатором w1 в их именах файлов.

localimds = imageDatastore(fullfile('/your_data/broad_data/BBBC005_v1-images','*w1*'));

Даже ограничивая выбор файлом с "w1"на их имена хранилище данных изображения все еще содержит более чем 9 000 файлов. Подмножество список изображений далее, выбирая каждый 100-й файл из тысяч файлов в наборе данных.

localimds.Files = localimds.Files(1:100:end);

Повторно группируйте демонстрационный набор в файл последовательности Hadoop

Если вы создали datastore изображений, преобразуйте демонстрационное подмножество изображений в файлы последовательности Hadoop, формат, используемый кластером Hadoop. Обратите внимание на то, что этот шаг просто изменяет данные от одного формата устройства хранения данных до другого, не изменяя значение данных. Для получения дополнительной информации о файлах последовательности, смотрите Начало работы с MapReduce (MATLAB).

Чтобы преобразовать datastore изображений в файл последовательности Hadoop, создайте функцию “карты” и “уменьшать” функцию, которую вы передаете mapreduce функция. Чтобы преобразовать файлы изображений в файлы последовательности Hadoop, функция карты не должна быть никакой-op функцией. В данном примере функция карты просто сохраняет данные изображения как есть, с помощью его имени файла в качестве ключа.

function identityMap(data, info, intermKVStore)
     add(intermKVStore, info.Filename, data);
end

Создайте уменьшать функцию, которая преобразует файлы изображений в datastore значения ключа, поддержанный файлами последовательности.

function identityReduce(key, intermValueIter, outKVStore)
    while hasnext(intermValueIter)
        add(outKVStore, key, getnext(intermValueIter));
    end
end

Вызовите mapreduce, передача ваших map и reduce функций. Пример сначала вызывает mapreducer функция, чтобы задать, где обработка происходит. Чтобы протестировать ваш набор и выполнить обработку в вашей локальной системе, задайте 0.

mapreducer(0);

Когда запущено локально, mapreduce создает datastore значения ключа, поддержанный MAT-файлами.

localmatds = mapreduce(localimds, @identityMap, @identityReduce,'OutputFolder', pwd);

Протестируйте свою среду MapReduce локально

После создания подмножества файлов изображений для тестирования и преобразования их к datastore значения ключа, вы готовы протестировать алгоритм. Измените свой алгоритм сегментации первоначальной ячейки, чтобы возвратить количество клеток. (Приложение Image Batch Processor, где этот пример сначала протестировал алгоритм, может только возвратить обработанные изображения, не значения, такие как количество клеток.)

Измените функцию сегментации ячейки, чтобы возвратить количество клеток и демонтировать отображение изображения.

function cellCount = cellCounter(im)
    % Otsu thresholding
    bw = imbinarize(im);
   
    % Find area of blobs
    stats = regionprops('table',bw,{'Area'});
    
    % Average cell diameter is about 33 pixels (based on random inspection)
    cellArea = pi*(33/2)^2;
    
    % Estimate cell count based on area of blobs
    cellsPerBlob = stats.Area/cellArea;
    cellCount = sum(round(cellsPerBlob));
end

Создайте функцию карты, которая вычисляет, ошибка значат определенное изображение. Эта функция получает фактическое количество клеток для изображения от кодирования имени файла (C номер), и сравнивает его с количеством клеток, возвращенным алгоритмом сегментации.

function mapImageToMisCountError(data, ~, intermKVStore)
    % Extract the image
    im = data.Value{1};
    % Call the cell counting algorithm
    actCount = cellCounter(im);
    % The original file name is available as the key
    fileName = data.Key{1};
    [~, name] = fileparts(fileName);
    % Extract expected cell count and focus blur from the file name
    strs = strsplit(name, '_'); 
    expCount  = str2double(strs{3}(2:end)); 
    focusBlur = str2double(strs{4}(2:end)); 
    diffCount = abs(actCount-expCount);
    % Note: focus blur is the key 
    add(intermKVStore, focusBlur, diffCount);
end

Создайте уменьшать функцию, которая вычисляет среднюю погрешность в количестве клеток для каждого значения особого внимания.

function reduceErrorCount(key, intermValueIter, outKVStore)
    focusBlur = key;
    % Compute the sum of all differences in cell count for this value of
    % focus blur
    count = 0;
    totalDiff = 0;
    while hasnext(intermValueIter)
        diffCount = getnext(intermvalueIter);
        count = count + 1;
        totalDiff = totalDiff+diffCount;
    end
    % Average
    meanDiff = totalDiff/count;
    add(outKVStore, focusBlue, meanDiff);
end

Запустите mapreduce задание в вашей локальной системе.

focusErrords = mapreduce(localmatds, @mapImageToMisCountError, @reduceErrorCount);

Соберите результаты.

focusErrorTbl = readall(focusErrords);

Получите значения средней погрешности.

averageErrors = cell2mat(focusErrorTbl.Value);

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

function plot_errors()
bar(focusErrorTbl.Key, averageErrors);
ha = gca;
ha.XTick = sort(focusErrorTbl.Key);
ha.XLim  = [min(focusErrorTbl.Key)-2 max(focusErrorTbl.Key)+2];
title('Cell counting result on a test data set');
xlabel('Focus blur');
ylabel('Average error in cell count');
end

Запустите среду MapReduce на кластере Hadoop

Теперь, когда вы проверили обработку своего алгоритма на подмножестве ваших данных, запустите свой алгоритм на полном наборе данных на кластере Hadoop.

Загрузите данные в файловую систему Hadoop

Загрузите все данные изображения в файловую систему Hadoop и запустите вашу среду MapReduce на кластере Hadoop, с помощью следующих команд интерпретатора. Чтобы запустить эту команду, замените your_data с местоположением на вашем компьютере.

hadoop fs -mkdir /user/broad_data/

hadoop fs -copyFromLocal /your_data/broad_data/BBBC005_v1_images /user/broad_data/BBBC005_v1_images

Настройте доступ к кластеру MATLAB Parallel Server

Настройте доступ к кластеру MATLAB Parallel Server. Чтобы запустить эту команду, замените 'your/hadoop/install' с местоположением на вашем компьютере.

setenv('HADOOP_HOME','/your/hadoop/install');

cluster = parallel.cluster.Hadoop;

cluster.HadoopProperties('mapred.job.tracker') = 'hadoop01glnxa64:54311';

cluster.HadoopProperties('fs.default.name') = 'hdfs://hadoop01glnxa64:54310';

disp(cluster);

Измените среду выполнения Mapreduce в удаленный кластер

Измените mapreduce среда выполнения, чтобы указать на удаленный кластер.

mapreducer(cluster);

Преобразуйте все данные изображения в файлы последовательности Hadoop

Преобразуйте все данные изображения в файлы последовательности Hadoop. Это похоже на то, что вы сделали в своей локальной системе, когда вы преобразовали подмножество изображений для прототипирования. Можно снова использовать map и reduce функции, которые вы использовали ранее. Используйте внутренний кластер Hadoop.

broadFolder = 'hdfs://hadoop01glnxa64:54310/user/broad_data/BBBC005_v1_images';

Выберите только окраску клеточного тела (w1) файлы для обработки.

w1Files = fullfile(broadFolder, '*w1*.TIF');

Создайте ImageDatastore представление всех этих файлов

imageDS = imageDatastore(w1Files);

Задайте выходную папку.

seqFolder = 'hdfs://hadoop01glnxa64:54310/user/datasets/images/broad_data/broad_sequence';

Преобразуйте изображения в datastore значения ключа.

seqds = mapreduce(imageDS, @identityMap, @identityReduce,'OutputFolder', seqFolder);

Запустите алгоритм подсчета клеток на целом наборе данных

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

Во-первых, задайте выходное местоположение для ошибочного количества.

output = 'hdfs://hadoop01glnxa64:54310/user/broad_data/BBBC005_focus_vs_errorCount';

Запустите свой алгоритм на среде Mapreduce. Используйте tic и toc функции, чтобы записать, сколько времени это берет, чтобы обработать набор изображений.

tic;

focusErrords = mapreduce(seqds, @mapImageToMisCountError, @reduceErrorCount,'OutputFolder',output);

toc

Соберите результаты.

focusErrorTbl = readall(focusErrords);

averageErrors = cell2mat(focusErrorTbl.Value);

Постройте результаты, как прежде.

function reduceErrorCountAll(key, intermValueIter, outKVStore)
    bar(focusErrorTbl.Key, averageErrors);
    ha = gca;
    ha.XTick = sort(focusErrorTbl.Key);
    ha.XLim  = [min(focusErrorTbl.Key)-2 max(focusErrorTbl.Key)+2];
    title('Cell counting result on the entire data set');
    xlabel('Focus blur');
    ylabel('Average error in cell count');
end

Смотрите также

|

Похожие темы