В этом примере показано, как выполнить алгоритм подсчета клеток на большом количестве изображений с помощью 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
Просмотрите файлы в наборе данных 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 ячеек. Сравните этот номер с результатами, возвращенными в командной строке для демонстрационного изображения.
После уверения, что ваш код сегментации работает как ожидалось над одним изображением, настраивает небольшую тестовую версию в вашей локальной системе крупного масштаба, обрабатывающего вас, хотят выполнить. Необходимо протестировать среду обработки прежде, чем запустить его на тысячах файлов.
Во-первых, создайте 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);
Если вы создали 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);
После создания подмножества файлов изображений для тестирования и преобразования их к 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
Теперь, когда вы проверили обработку своего алгоритма на подмножестве ваших данных, запустите свой алгоритм на полном наборе данных на кластере 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. Чтобы запустить эту команду, замените '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
среда выполнения, чтобы указать на удаленный кластер.
mapreducer(cluster);
Преобразуйте все данные изображения в файлы последовательности 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