В этом примере показано, как выполнить алгоритм подсчета клеток на большом количестве изображений с помощью Image Processing Toolbox с MATLAB ® MapReduce и Datastore. MapReduce является методом программирования для анализа наборов данных, которые не помещаются в памяти. Пример также использует MATLAB Parallel Server™, чтобы запустить параллельные программы MapReduce на кластерах Hadoop ®. Пример показывает, как протестировать алгоритм на локальной системе на подмножестве изображений перед перемещением его в кластер Hadoop.
Загрузите набор BBBC005v1 данных из Broad Bioimage Benchmark Collection. Этот набор данных представляет собой аннотированный набор биологических изображений, предназначенный для проверки и валидации. Набор изображений предоставляет примеры синтетических изображений внутри и вне фокуса, которые могут использоваться для валидации метрик особого внимания. Набор данных содержит почти 20 000 файлов. Для получения дополнительной информации смотрите это введение в набор данных.
В системной подсказке в системе Linux используйте wget
Команда для загрузки zip- файла, содержащей набор данных BBBC. Перед запуском этой команды убедитесь, что в вашем целевом местоположении достаточно пространство для хранения zip- файла (1,8 ГБ) и извлеченных изображений (2,6 ГБ).
wget https://data.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
) и фильтровали Гауссовым низкочастотным фильтром диаметром 1 и сигмой диаметром 0,25 x для моделирования размытия особого внимания (F1
). The 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 and Компьютерное Зрение, нажмите Image Batch Processor. Открыть приложение из командной строки можно также с помощью imageBatchProcessor
команда.
В приложении Image Batch Processor нажмите Загрузить изображения и перейдите к папке, в которой вы хранили загруженный набор данных.
Приложение Image Batch Processor отображает миниатюры изображений в папке на левой панели и версию текущего выбранного изображения с более высоким разрешением на вкладке Input Image. Просмотрите некоторые изображения, чтобы ознакомиться с набором данных.
Укажите имя функции, которая реализует алгоритм сегментации камер. Чтобы указать существующую функцию, введите ее имя в поле Имя функции или щелкните значок папки, чтобы просмотреть и выбрать функцию. Чтобы создать новую функцию пакетной обработки, щелкните Создать. Приложение открывает шаблон пакетной функции в редакторе MATLAB ®. В данном примере создайте новую функцию, содержащую следующий код сегментации изображений. Для создания пакетной функции нажмите кнопку Сохранить. Приложение обновляется, чтобы отобразить имя функции, которую вы создали в разделе 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
"в их именах хранилище данных по-прежнему содержит более 9000 файлов. Подставьте список изображений далее, выбирая каждый 100-й файл из тысяч файлов в наборе данных.
localimds.Files = localimds.Files(1:100:end);
Как только вы создали image datastore, преобразуйте образец подмножества изображений в файлы последовательности Hadoop, формат, используемый кластером Hadoop. Обратите внимание, что этот шаг просто изменяет данные с одного формата хранения на другой, не меняя значение данных. Для получения дополнительной информации о файлах последовательности смотрите Начало работы с MapReduce (MATLAB).
Чтобы преобразовать изображение datastore в файл последовательности Hadoop, создайте функцию «map» и функцию «reduce», которые вы передаете в mapreduce
функция. Чтобы преобразовать файлы изображений в файлы последовательности Hadoop, функция map должна быть функцией no-op. В данном примере функция map просто сохраняет данные изображения как есть, используя его имя файла в качестве ключа.
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
, передача вашей карты и сокращение функций. Пример сначала вызывает mapreducer
функция для определения места выполнения обработки. Чтобы протестировать настройку и выполнить обработку в локальной системе, задайте 0
.
mapreducer(0);
При локальном запуске mapreduce
создает хранилище datastore с ключевым значением, поддерживаемое MAT-файлами.
localmatds = mapreduce(localimds,
@identityMap, @identityReduce,'OutputFolder'
, pwd);
После создания подмножества файлов изображений для проверки и преобразования их в key-value 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
Создайте функцию map, которая вычисляет количество ошибок для определенного изображения. Эта функция получает фактическое количество камер для изображения из имени файла, кодирующего (C
number) и сравнивает его с количеством камер, возвращаемым алгоритмом сегментации.
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. Это похоже на то, что вы сделали в своей локальной системе, когда преобразовали подмножество изображений для прототипирования. Вы можете повторно использовать карту и уменьшить функции, которые вы использовали ранее. Используйте внутренний кластер 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