HumanSignal / label-studio-frontend

Data labeling react app that is backend agnostic and can be embedded into your applications — distributed as an NPM package
https://labelstud.io/
Apache License 2.0
421 stars 316 forks source link

How to send multiple tasks to Label Studio or Update tasks dynamically (using in Vue 3) #1260

Open surya9teja opened 1 year ago

surya9teja commented 1 year ago

Hi, I am using Label Studio in my Vue 3 project. The project setup looks as follow

Component LabelStudioHelper.vue

<template>
    <div id="label-studio"></div>
</template>

<script>
import LabelStudio from "@heartexlabs/label-studio";

export default {
    props: {
        config: {
            type: String,
            required: true
        },
        interfaces: {
            type: Array,
            required: false,
            default: () => [
                "panel",
                "update",
                "submit",
                "controls",
                "infobar",
                "topbar",
                "side-column",
                "annotations:history",
                "annotations:tabs",
                "annotations:menu",
                "annotations:current",
                "edit-history",
            ]
        },
        task: {
            type: Object,
            required: true
        },
        onLabelStudioLoad: {
            type: Function,
            required: false,
            default: (ls) => { }
        },
        onSubmitAnnotation: {
            type: Function,
            required: false,
            default: (ls, annotation) => { }
        },
        onUpdateAnnotation: {
            type: Function,
            required: false,
            default: (ls, annotation) => { }
        },
    },
    data() {
        return {
            labelStudio: null,
        };
    },
    mounted() {
        const labelStudio = new LabelStudio('label-studio', {
            config: this.config,
            interfaces: this.interfaces,
            task: this.task,
            user: {
                pk: 1,
                firstName: 'John',
                lastName: 'Doe',
            },

        });
        labelStudio.on("labelStudioLoad", (LS) => {
            // Perform an action when Label Studio is loaded
            const c = LS.annotationStore.addAnnotation({
                userGenerate: true
            });
            LS.annotationStore.selectAnnotation(c.id);
        });

        labelStudio.on("updateAnnotation", (LS, annotation) => {
            // Perform an action when an annotation is updated
            console.log(annotation.serializeAnnotation())
        });

        labelStudio.on("nextTask", (LS) => {
            // Perform an action when the next task button is clicked
            console.log("Next task button clicked")
        });

        labelStudio.on("submitAnnotation", (LS, annotation) => {
            // Retrieve an annotation in JSON format
            console.log(annotation.serializeAnnotation())
        });
        this.labelStudio = labelStudio;
    },
}
</script>

<style>
@import '@heartexlabs/label-studio/build/static/css/main.css';
</style>

Parent annotation.vue

<template>
    <div>
        <button @click="Next_Image">Next Image</button>
        <LabelStudioHelper :task="task" :config="config" :interfaces="interfaces" />
    </div>
</template>

<script>
import LabelStudioHelper from "@/components/LabelStudioHelper.vue";
import data from "@/components/data.json";

export default {
    components: { LabelStudioHelper },
    data() {
        return {
            task: {
                annotations: [],
                id: 1,
                data: {
                    image: 'https://picsum.photos/id/237/400/550'
                }
            },
            config: `
            <View>
                <Image name="img" value="$image"></Image>
                <RectangleLabels name="tag" toName="img">
                    <Label value="Picture"></Label>
                    <Label value="Table"></Label>
                </RectangleLabels>
            </View>`,
            interfaces: [
                "panel",
                "update",
                "controls",
                "side-column",
                "annotations:delete",
                "submit",
                "infobar",
                "topbar",
                "annotations:history",
                "annotations:tabs",
                "annotations:menu",
                "annotations:current",
                "edit-history"
            ],
        };
    },
}
</script>

The above setup works perfectly for one image, But I want to initialize the LabelStudio with multiple images or dynamically update the images for annotation. So I have create a json file with tasks list and try to pass that json object to the task prop in LabelStudio but It throwing error.

data.json

[
    {
        "id": 1,
        "data": {
            "image": "https://htx-misc.s3.amazonaws.com/opensource/label-studio/examples/images/nick-owuor-astro-nic-visuals-wDifg5xc9Z4-unsplash.jpg"
        },
        "annotations": [],
        "predictions": []
    },
    {
        "id": 2,
        "data": {
            "image": "https://htx-misc.s3.amazonaws.com/opensource/label-studio/examples/images/history-in-hd-e5eDHbmHprg-unsplash.jpg"
        },
        "annotations": [],
        "predictions": []
    },
    {
        "id": 3,
        "data": {
            "image": "https://htx-misc.s3.amazonaws.com/opensource/label-studio/examples/images/soroush-karimi-crjPrExvShc-unsplash.jpg"
        },
        "annotations": [],
        "predictions": []
    }
]

Passing of data.json to labelstudio in annotation.vue

import LabelStudioHelper from "@/components/LabelStudioHelper.vue";
import data from "@/components/data.json";

export default{
components: { LabelStudioHelper },
    data() {
        return {
            task: { data }
            },
            config: `
            <View>
                <Image name="img" value="$image"></Image>
                <RectangleLabels name="tag" toName="img">
                    <Label value="Picture"></Label>
                    <Label value="Table"></Label>
                </RectangleLabels>
            </View>`,
            interfaces: [
                "panel",
                "update",
                "controls",
                "side-column",
                "annotations:delete",
                "submit",
                "infobar",
                "topbar",
                "annotations:history",
                "annotations:tabs",
                "annotations:menu",
                "annotations:current",
                "edit-history"
            ],
        };
    },

};

If anybody know how to dynamically update the images for annotation after initializing the LabelStudio or initializing the label studio with multiple images, please help me. Thanks :)

hlomzik commented 1 year ago

Hi! We have hidden ability to display multiple images in a gallery, if you provide array of image urls instead of usual one: data: { images: ['url1', 'url2'] } But they have to be the same size and they all be labeled in one place with the same regions, so it's only suitable for different layers of the same object/shot, like R G B. To update task in LSF you can use assignTask + some other methods, it's not very clear and convenient and we'll improve this soon. Also we are planning to release real multi-image segmentation, stay tuned! It's already in beta.