Наличие платформы для аннотирования данных изображения имеет важное значение для HCS. Здесь я продемонстрирую аннотирование изображений C Elegans из Broad.
Вот уже несколько лет я пытаюсь найти инструмент, который мне действительно нравится, для аннотирования изображений HCS с помощью веб-интерфейса. Я использовал несколько инструментов, в том числе настольное приложение под названием LabelImg, и наконец нашел инструмент, который отвечает всем требованиям, под названием LabelStudio!
Label Studio — это инструмент для аннотирования изображений, аудио и текста. Здесь мы сконцентрируемся на изображениях как на средстве выбора.
Я прохожу процесс в этом видео.
Получить данные
Вы можете, конечно, использовать свои собственные данные, но для этого урока я буду использовать общедоступный C. elegans из Broad BioImage Benchmark Collection.
mkdir data
cd data
wget https://data.broadinstitute.org/bbbc/BBBC010/BBBC010_v2_images.zip
unzip BBBC010_v2_images.zip
Изображения HCS часто очень темные при открытии в средстве просмотра системы. Чтобы использовать их для остальной части конвейера, нам нужно будет выполнить двухэтапный процесс преобразования: сначала с помощью bftools для преобразования из tif в png, а затем с помощью Imagmagick для коррекции уровней.
cd .. # be in your project root here
# Use the bftools docker image and drop into a shell
mkdir data/tif
mkdir data/png
mkdir data/corrected-png
docker run -it -v $(pwd)/data:/home/bf/data openmicroscopy/bftools bash
cd /home/bf/data
find $(pwd) -name '*tif' | sed 's/\.tif//g' | xargs -I {} bfconvert -nogroup {}.tif {}.png
# ctrl+d to exit the container
Теперь мы будем использовать ImageMagick, чтобы применить коррекцию автоуровня, чтобы мы могли видеть, что мы помечаем!
docker run -it --rm -v $(pwd)/data:/data \
continuumio/miniconda3 bash
# On the image
conda install -c conda-forge -y imagemagick
cd /data
find $(pwd) -name '*tif' | xargs -I {} basename {} | sed 's/\.tif//g' | xargs -I {} convert -auto-level /data/{}.png /data/{}-autolevel.png
mv *.tif tif/
mv *auto*.png corrected-png/
mv *.png png/
# Ctrl+D to exit
Если вы похожи на меня и собираете образы докеров, чтобы избежать установки чего-либо на свой компьютер, вам нужно будет время от времени их очищать.
# This will remove ALL DOCKER containers from your system
# Use with caution!
docker container stop $(docker container ls -aq)
docker system prune -f -a
Если вам нужно очистить изображения, удалите папки data/png
и data/tif
. Мы не будем их использовать.
Запуск LabelStudio
LabelStudio работает на основе проектов, и каждый проект состоит из задач. В данном случае задачей является маркировка изображения. Итак, что нам нужно сделать, это указать ему каталог изображений, и он настроит проект для нас.
Различные конфигурации маркировки
LabelStudio может поддерживать несколько различных типов аннотаций к изображениям. Лучшее место, где можно узнать больше об этом, — перейти на их страницу шаблонов и начать изучать их игровую площадку.
Я предполагаю, что вы используете семантическую сегментацию, маркировку полигонов или ограничивающие рамки. В качестве быстрого отказа от ответственности интерфейс семантической сегментации был немного глючным, когда я пробовал его. На момент написания он помечен как «Новый» и находится в активной разработке. Вероятно, к тому времени, как вы это прочитаете, все будет решено.
Для меня это не было проблемой, потому что я лично обнаружил, что могу получить ту же функциональность, используя инструмент Polygon Labeling для обводки формы. Я также обнаружил, что инструмент «Многоугольник» проще в использовании, и когда у вас есть контур многоугольника, вы можете преобразовать его в маску.
Семантическая сегментация против ограничивающих рамок
Семантическая сегментация — это когда вы назначаете каждому пикселю изображения то, что не хотите помечать. На маркировку уходит больше времени, и вам нужны более значительные вычислительные ресурсы для обучения ваших моделей, но вы будете иметь большую точность.
Использование ограничительной рамки немного ускоряет маркировку и начало работы, но вы теряете точность, особенно когда у вас много перекрывающихся объектов.
Это лучше объяснить на примерах:
Ярлыки полигонов
Семантические ярлыки
Ограничивающие рамки
Инициализировать и запустить скрипт
Возьмите это и назовите init-labelproject.sh
.
#!/usr/bin/env bash
# init-labelproject.sh
docker run --rm -it \
-e PORT=${PORT} \
-v $(pwd)/${TYPE}:/label-studio/${TYPE} \
-v $(pwd)/data:/label-studio/data \
-v $(pwd)/conf:/label-studio/conf \
--name label-studio-${TYPE} \
heartexlabs/label-studio:latest label-studio \
init ${TYPE} --force \
--port ${PORT} \
--input-path=/label-studio/data/corrected-png \
--label-config=/label-studio/conf/${TYPE}-config.xml \
--input-format=image-dir
Возьмите это и назовите run-labelstudio.sh
.
#!/usr/bin/env bash
# run-labelstudio.sh
docker run --rm -it \
-p ${PORT}:${PORT} \
-e PORT=${PORT} \
-v $(pwd)/${TYPE}:/label-studio/${TYPE} \
-v $(pwd)/data:/label-studio/data \
-v $(pwd)/conf:/label-studio/conf \
--name label-studio-${TYPE} \
heartexlabs/label-studio:latest label-studio \
start ./${TYPE} --port ${PORT}
Как только вы их запустите chmod 777 *sh
, давайте назовем несколько червей!
Настройте свой проект и запустите веб-интерфейс
Возьмите желаемую конфигурацию ниже и запустите веб-интерфейс.
mkdir conf
# Make sure each of the xml files are in the conf dir!
cd conf
Конфигурация ограничивающей рамки
Возьмите это и поместите в conf/object-config.xml
.
<View style="display: flex">
<View style="width: 100px">
<Header value="Pick label" />
<RectangleLabels name="tag" toName="img">
<Label value="Alive" background="blue"></Label>
<Label value="Dead" background="orange"></Label>
</RectangleLabels>
</View>
<View>
<Image name="img" value="$image" showMousePos="true" zoom="true" zoomControl="true" />
</View>
</View>
Конфигурация многоугольника
Возьмите это и поместите в conf/polygon-config.xml
.
<View style="display: flex">
<View style="width: 100px">
<Header value="Pick label" />
<PolygonLabels name="tag" toName="img" strokewidth="2" pointstyle="circle" pointsize="small" showInline="false">
<Label value="Alive" background="blue"></Label>
<Label value="Dead" background="orange"></Label>
</PolygonLabels>
</View>
<View>
<Image name="img" value="$image" showMousePos="true" zoom="true" zoomControl="true" />
</View>
</View>
Семантическая конфигурация
Возьмите это и поместите в conf/semantic-config.xml
.
<View style="display: flex">
<View style="width: 100px">
<Header value="Pick label" />
<BrushLabels name="tag" toName="img">
<Label value="Alive" background="blue" />
<Label value="Dead" background="orange" />
</BrushLabels>
</View>
<View>
<Image name="img" value="$image" showMousePos="true" zoom="true" zoomControl="true" />
</View>
</View>
Ограничительная рамка
Чтобы запустить интерфейс ограничительной рамки, используйте эти команды:
export TYPE="object"
export PORT="8080"
mkdir $TYPE
# you only need to run the init script once for setup
./init-labelproject.sh
./run-labelstudio.sh
И откройте localhost:8080
в своем браузере.
Полигон
Для запуска полигонального интерфейса используйте эти команды -
export TYPE="polygon"
export PORT="8081"
mkdir $TYPE
# you only need to run the init script once for setup
./init-labelproject.sh
./run-labelstudio.sh
И откройте localhost:8081
в своем браузере.
Семантическая сегментация (кисть)
Для запуска семантического интерфейса используйте эти команды -
export TYPE="semantic"
export PORT="8082"
mkdir $TYPE
# you only need to run the init script once for setup
./init-labelproject.sh
./run-labelstudio.sh
И откройте localhost:8082
в своем браузере.
Настройка интерфейса маркировки
LabelStudio дает вам некоторый контроль над интерфейсом маркировки. Вы также можете добавлять простые формы непосредственно через конфигурацию с помощью Управляющих тегов.
Чего я хотел, так это возможности пометить образ как завершенный, то есть все черви были помечены, или как недействительный, чтобы исключить его из обучения. Я смог добавить это со следующей конфигурацией.
<View>
<!-- Begin Display the image-->
<View style="padding: 25px;
box-shadow: 2px 2px 8px #AAA;">
<Image name="img" value="$image" showMousePos="true" zoom="true" zoomControl="true"/>
</View>
<!-- End Display the image-->
<!-- Begin display labels-->
<View style=" padding: 25px;
box-shadow: 2px 2px 8px #AAA;">
<View style="">
<Header value="Choose Phenotype"/>
<PolygonLabels name="tag" toName="img" strokewidth="2" pointstyle="circle" pointsize="small"
showInline="false">
<Label value="Alive" background="blue"></Label>
<Label value="Dead" background="orange"></Label>
</PolygonLabels>
</View>
<View style="">
<Header value="Check when the image is complete. If the image is not suitable for training choose invalid instead."/>
<Choices name="complete" toName="img" choice="single">
<Choice alias="complete" value="Complete"/>
<Choice alias="invalid" value="Invalid"/>
</Choices>
</View>
</View>
<!-- End display labels-->
</View>
Вы можете немного поиграть с этим, чтобы получить точный макет, который вы хотите. Ширина, высота и другие переменные CSS настраиваются в конфигурации. Обязательно перезапустите сервер, чтобы увидеть новую конфигурацию!
Каждый элемент управления имеет имя name
, которое должно быть уникальным, и пункт назначения toName
.
<Choices name="complete" toName="img" choice="single">
# ...
<Image name="img" value="$image"
# ...
<PolygonLabels name="tag" toName="img"
Обработка вывода маркировки
Каждый вывод будет в вашем project-dir/completions
, и в этом каталоге будет один файл json для каждого изображения. Вы увидите путь completions
, а затем будет массив results
. Выходной формат и точные характеристики могут меняться в зависимости от вашей конфигурации, поэтому обязательно проверьте это с вашими собственными конфигурациями.
Вот пример вывода метки полигона. Я добавил комментарии, и это больше не допустимый json, поэтому не пытайтесь его анализировать. ;-)
{
## Corresponds to the name on the Polygon Control
"from_name": "tag",
## Randomly generated ID
"id": "bUgnJpbBgC",
## Height and Width of the Image
"original_height": 520,
"original_width": 696,
## Task Variable
"source": "$image",
## The to portion of the control
"to_name": "img",
## Control Type
"type": "polygonlabels",
"value": {
## Points of the polygon
## These can be read into a matplotlib.Path object for parsing
"points": [
[
71.25434944790884,
27.052753770458885
],
[
68.9321022931952,
28.148466100859682
],
... More labels
],
"polygonlabels": [
## ITS ALIVE!
## This is one of the phenotypes
## The phenotypes were either alive or dead
"Alive"
]
}
},
А вот пример «формы», которую мы создали с полным/недействительным.
{
# This is the name from the control
"from_name": "complete",
"id": "PZru1lZMeo",
"to_name": "img",
"type": "choices",
"value": {
"choices": [
## This image as marked as invalid!
## Don't use it for training!
"invalid"
]
}
}
Именно тогда все становится интереснее, потому что теперь, когда у вас есть настраиваемый интерфейс с анализируемым выводом, вы можете начать создавать надежные конвейеры для обучения.
Дополнительные идеи
Когда вы запустите интерфейс и начнете маркировку, вы увидите, что LabelStudio выдает ваши данные в {polygon,object,semantic}/completions/*.json
. Это просто файлы данных, и вы можете использовать их для обучения моделей для Tensorflow, PyTorch или Keras.
Допустим, вы используете модель Tensorflow MaskRCNN. Вы можете использовать LabelStudio для маркировки изображений, преобразования файлов JSON в TFRecord и обучения. Затем вы можете взять свою несовершенную модель, пометить ее набором изображений, затем вручную очистить новые изображения, промыть и повторить.
Если у вас есть какие-либо вопросы, пожалуйста, не стесняйтесь обращаться ко мне по адресу [email protected].
Цитаты
Первоначально опубликовано на https://www.dabbleofdevops.com.