В этом примере показано, как выполнить алгоритм подсчета ячеек для большого количества изображений с помощью инструментария обработки изображений с помощью MATLAB ® MapReduce и Datastore. MapReduce - метод программирования для анализа наборов данных, не вписывающихся в память. В примере также используется Server™ MATLAB Parallel для запуска параллельных программ MapReduce на кластерах Hadoop ®. В примере показано, как протестировать алгоритм в локальной системе на подмножестве образов перед перемещением в кластер Hadoop.
Загрузите BBBC005v1 набор данных из коллекции Benchmark Broad Bioimage. Этот набор данных представляет собой аннотированный набор биологических изображений, предназначенный для тестирования и проверки. Набор изображений предоставляет примеры синтетических изображений в фокусе и вне фокуса, которые могут использоваться для проверки метрик фокуса. Набор данных содержит почти 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). w1 определяет используемое пятно. Например, найдите количество изображений в наборе данных, которые используют w1 пятно.
d = dir('C:\Temp\BBBCdata\BBBC005_v1_images\*w1*');
numel(d)ans = 9600
Просмотрите файлы в наборе данных BBBC и протестируйте алгоритм для небольшого подмножества файлов с помощью приложения «Процессор пакетной обработки изображений». Пример проверяет простой алгоритм, который сегментирует ячейки на изображениях. (В примере используется модифицированная версия этого алгоритма сегментации ячеек для создания алгоритма подсчета ячеек, используемого в реализации MapReduce.)
Откройте приложение Процессор пакетной обработки изображений. На панели инструментов MATLAB на вкладке Приложения в разделе Обработка изображений и компьютерное видение щелкните Процессор пакетной обработки изображений. Вы также можете открыть приложение из командной строки с помощью imageBatchProcessor команда.
В приложении Процессор пакетной обработки изображений щелкните Загрузить изображения и перейдите в папку, в которой был сохранен загруженный набор данных.

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

Укажите имя функции, реализующей алгоритм сегментации ячеек. Чтобы указать существующую функцию, введите ее имя в поле Имя функции или щелкните значок папки, чтобы просмотреть и выбрать функцию. Для создания новой функции пакетной обработки щелкните Создать. Приложение открывает шаблон пакетной функции в редакторе MATLAB ®. В этом примере создайте новую функцию, содержащую следующий код сегментации изображения. Щелкните Сохранить, чтобы создать пакетную функцию. Приложение обновляется для отображения имени функции, созданной в разделе «Пакетная функция» панели инструментов приложения.
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
Выберите миниатюру изображения, отображаемого в приложении, и нажмите Обработать выбранные, чтобы выполнить тестовый запуск алгоритма. В этом примере выберите только изображение с помощью "w1"stain (идентифицируется в имени файла). Алгоритм сегментации лучше всего работает с этими изображениями.

Проверьте результаты выполнения алгоритма, чтобы убедиться, что алгоритм сегментации обнаружил правильное количество ячеек в изображении. Имена изображений содержат число ячеек в C номер. Например, изображение с именем SIMCEPImages_A05_C18_F1_s05_w1.TIF содержит 18 ячеек. Сравните это число с результатами, полученными в командной строке образца изображения.
После проверки того, что код сегментации работает так, как ожидалось на одном изображении, установите небольшую тестовую версию в локальной системе масштабной обработки, которую вы хотите выполнить. Перед запуском платформы обработки необходимо протестировать ее на тысячах файлов.
Сначала создайте хранилище данных образа с помощью ImageDatastore функция, содержащая небольшое подмножество изображений. MapReduce использует хранилище данных для обработки данных в небольших фрагментах, которые по отдельности вписываются в память. Перейдите в папку, содержащую изображения, и создайте хранилище данных изображений. Потому что алгоритм сегментации ячеек реализован в cellSegmenter.m лучше всего работает с пятном тела клетки, выберите только файлы с индикатором w1 в именах файлов.
localimds = imageDatastore(fullfile('/your_data/broad_data/BBBC005_v1-images','*w1*'));
Даже ограничение выбора файлом с "w1"в их именах хранилище данных изображения по-прежнему содержит более 9000 файлов. Далее подбирайте список изображений, выбирая каждый 100-й файл из тысяч файлов в наборе данных.
localimds.Files = localimds.Files(1:100:end);
После создания хранилища данных изображения преобразуйте образец подмножества изображений в файлы последовательности Hadoop, формат, используемый кластером Hadoop. Обратите внимание, что на этом этапе данные просто изменяются из одного формата хранения в другой без изменения значения данных. Дополнительные сведения о файлах последовательности см. в разделе Начало работы с MapReduce (MATLAB).
Чтобы преобразовать хранилище данных изображения в файл последовательности Hadoop, создайте функцию «map» и функцию «reduct», которую вы передаете mapreduce функция. Для преобразования файлов изображений в файлы последовательности Hadoop функция отображения должна быть функцией no-op. В этом примере функция отображения просто сохраняет данные изображения как есть, используя имя файла в качестве ключа.
function identityMap(data, info, intermKVStore) add(intermKVStore, info.Filename, data); end
Создайте функцию сокращения, которая преобразует файлы изображений в хранилище данных с ключевым значением, поддерживаемое файлами последовательности.
function identityReduce(key, intermValueIter, outKVStore) while hasnext(intermValueIter) add(outKVStore, key, getnext(intermValueIter)); end end
Звонить mapreduce, прохождение карты и сокращение функций. В примере сначала вызывается mapreducer для указания места обработки. Для тестирования настройки и выполнения обработки в локальной системе укажите 0.
mapreducer(0);
При локальном запуске mapreduce создает хранилище данных с ключевым значением, поддерживаемое MAT-файлами.
localmatds = mapreduce(localimds, @identityMap, @identityReduce,'OutputFolder', pwd);
После создания подмножества файлов изображений для тестирования и преобразования их в хранилище данных с ключевым значением можно протестировать алгоритм. Измените исходный алгоритм сегментации ячеек, чтобы вернуть количество ячеек. (Приложение «Процессор пакетной обработки изображений», в котором этот пример впервые протестировал алгоритм, может возвращать только обработанные изображения, а не такие значения, как количество ячеек.)
Измените функцию сегментации ячеек, чтобы вернуть количество ячеек и удалить отображение изображения.
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 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. Чтобы выполнить эту команду, замените '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';
Преобразование изображений в хранилище данных с ключевым значением.
seqds = mapreduce(imageDS, @identityMap, @identityReduce,'OutputFolder', seqFolder);
Запустите алгоритм подсчета ячеек для всего набора данных, хранящегося в файловой системе Hadoop, с помощью платформы MapReduce. Единственное изменение от запуска платформы в локальной системе заключается в том, что теперь расположения ввода и вывода находятся в файловой системе Hadoop.
Сначала укажите местоположение вывода для подсчета ошибок.
output = 'hdfs://hadoop01glnxa64:54310/user/broad_data/BBBC005_focus_vs_errorCount';
Запустите алгоритм на платформе Mapreduction. Используйте 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
