Наличие платформы для аннотирования данных изображения имеет важное значение для 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].

Цитаты



Мы использовали набор живых/мертвых изображений заражения C.elegans версии 1, предоставленный Фредом Осубелем и доступный в коллекции Broad Bioimage Benchmark Collection [«Ljosa et al., Nature Methods , 2012]».

Первоначально опубликовано на https://www.dabbleofdevops.com.