

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

# Modello demo: annotazione di immagini con `crowd-bounding-box`
<a name="sms-custom-templates-step2-demo1"></a>

Quando scegli di utilizzare un modello personalizzato come tipo di attività nella console Amazon SageMaker Ground Truth, accedi al **pannello attività Etichettatura personalizzata**. in cui puoi scegliere tra più modelli di base. I modelli rappresentano alcune delle attività più comuni e forniscono un punto di partenza per la creazione di un modello di attività di etichettatura personalizzata. Se non utilizzi la console o come risorsa aggiuntiva, consulta [Amazon SageMaker AI Ground Truth Sample Task UIs ](https://github.com/aws-samples/amazon-sagemaker-ground-truth-task-uis) per un archivio di modelli dimostrativi per una varietà di tipi di attività di etichettatura.

Questa dimostrazione funziona con il modello. **BoundingBox** La dimostrazione funziona anche con le AWS Lambda funzioni necessarie per l'elaborazione dei dati prima e dopo l'operazione. Nel repository Github riportato sopra, per trovare modelli che funzionano con AWS Lambda le funzioni, `{{ task.input.<property name> }}` cercate nel modello.

**Topics**
+ [Modello Riquadro di delimitazione personalizzato iniziale](#sms-custom-templates-step2-demo1-base-template)
+ [Modello Riquadro di delimitazione personalizzato](#sms-custom-templates-step2-demo1-your-own-template)
+ [Il file manifest](#sms-custom-templates-step2-demo1-manifest)
+ [La tua funzione Lambda di pre-annotazione](#sms-custom-templates-step2-demo1-pre-annotation)
+ [La tua funzione Lambda di post-annotazione](#sms-custom-templates-step2-demo1-post-annotation)
+ [Output del processo di etichettatura](#sms-custom-templates-step2-demo1-job-output)

## Modello Riquadro di delimitazione personalizzato iniziale
<a name="sms-custom-templates-step2-demo1-base-template"></a>

Di seguito è riportato il modello di riquadro di delimitazione iniziale fornito.

```
<script src="https://assets.crowd.aws/crowd-html-elements.js"></script>

<crowd-form>
  <crowd-bounding-box
    name="boundingBox"
    src="{{ task.input.taskObject | grant_read_access }}"
    header="{{ task.input.header }}"
    labels="{{ task.input.labels | to_json | escape }}"
  >

    <!-- The <full-instructions> tag is where you will define the full instructions of your task. -->
    <full-instructions header="Bounding Box Instructions" >
      <p>Use the bounding box tool to draw boxes around the requested target of interest:</p>
      <ol>
        <li>Draw a rectangle using your mouse over each instance of the target.</li>
        <li>Make sure the box does not cut into the target, leave a 2 - 3 pixel margin</li>
        <li>
          When targets are overlapping, draw a box around each object,
          include all contiguous parts of the target in the box.
          Do not include parts that are completely overlapped by another object.
        </li>
        <li>
          Do not include parts of the target that cannot be seen,
          even though you think you can interpolate the whole shape of the target.
        </li>
        <li>Avoid shadows, they're not considered as a part of the target.</li>
        <li>If the target goes off the screen, label up to the edge of the image.</li>
      </ol>
    </full-instructions>

    <!-- The <short-instructions> tag allows you to specify instructions that are displayed in the left hand side of the task interface.
    It is a best practice to provide good and bad examples in this section for quick reference. -->
    <short-instructions>
      Use the bounding box tool to draw boxes around the requested target of interest.
    </short-instructions>
  </crowd-bounding-box>
</crowd-form>
```

I modelli personalizzati utilizzano il [linguaggio modello Liquid](https://shopify.github.io/liquid/) e ciascuno degli elementi tra parentesi graffe doppie è una variabile. La AWS Lambda funzione di pre-annotazione dovrebbe fornire un oggetto denominato `taskInput` e le proprietà di quell'oggetto sono accessibili come nel modello. `{{ task.input.<property name> }}`

## Modello Riquadro di delimitazione personalizzato
<a name="sms-custom-templates-step2-demo1-your-own-template"></a>

Ad esempio, supponiamo che tu abbia una grande raccolta di foto di animali in cui conosci il tipo di animale presente in un'immagine da un precedente processo di classificazione delle immagini. A questo punto vuoi tracciare un riquadro di delimitazione.

Nell'esempio iniziale sono disponibili tre variabili: `taskObject`, `header` e `labels`.

Ciascuna di queste sarà rappresentata in parti diverse del riquadro di delimitazione.
+ `taskObject` è un URL HTTP(S) o URI S3 per la foto che deve essere annotata. Il `| grant_read_access` aggiunto è un filtro che convertirà un URI S3 in un URL HTTPS con accesso di breve durata a tale risorsa. Se stai utilizzando un URL HTTP(S), non è necessario.
+ `header` è il testo sopra la foto da etichettare, ad esempio "Disegnare una casella attorno al volatile nella foto."
+ `labels` è un array, rappresentato come `['item1', 'item2', ...]`. Si tratta di etichette che possono essere assegnate dal worker alle diverse caselle che vengono disegnate. Ce ne può essere solo una o molte.

Ciascuno dei nomi di variabile proviene dall'oggetto JSON nella risposta del Lambda di pre-annotazione. I nomi riportati sopra sono semplici suggerimenti. Utilizza i nomi di variabile che ti sembrano più adatti per migliorare la leggibilità del codice all'interno del team.

**Utilizza le variabili solo quando necessario**  
Se un campo non cambia, puoi rimuovere la variabile dal modello e sostituirla con il testo, altrimenti dovrai ripetere il testo come valore in ogni oggetto nel manifest o codificarlo nella funzione Lambda di pre-annotazione.

**Example : Modello Riquadro di delimitazione personalizzato finale**  
Per semplificare la procedura, questo modello includerà una variabile, un'etichetta e istruzioni di base. Supponendo che il manifest includa una proprietà "animal" in ogni oggetto dati, quel valore può essere riutilizzato in due parti del modello.  

```
<script src="https://assets.crowd.aws/crowd-html-elements.js"></script>
<crowd-form>
  <crowd-bounding-box
    name="boundingBox"
    labels="[ '{{ task.input.animal }}' ]"
    src="{{ task.input.source-ref | grant_read_access }}"
    header="Draw a box around the {{ task.input.animal }}."
  >
    <full-instructions header="Bounding Box Instructions" >
      <p>Draw a bounding box around the {{ task.input.animal }} in the image. If 
      there is more than one {{ task.input.animal }} per image, draw a bounding 
      box around the largest one.</p>
      <p>The box should be tight around the {{ task.input.animal }} with 
      no more than a couple of pixels of buffer around the 
      edges.</p>
      <p>If the image does not contain a {{ task.input.animal }}, check the <strong>
      Nothing to label</strong> box.
    </full-instructions>
    <short-instructions>
      <p>Draw a bounding box around the {{ task.input.animal }} in each image. If 
      there is more than one {{ task.input.animal }} per image, draw a bounding 
      box around the largest one.</p>
    </short-instructions>
  </crowd-bounding-box>
</crowd-form>
```
Nota il riutilizzo di `{{ task.input.animal }}` in tutto il modello. Se nel manifest tutti i nomi di animale iniziavano con una lettera maiuscola, puoi utilizzare `{{ task.input.animal | downcase }}`, incorporando uno dei filtri Liquid predefiniti nelle frasi in cui devono essere visualizzati in minuscolo.

## Il file manifest
<a name="sms-custom-templates-step2-demo1-manifest"></a>

Il file manifest deve fornire i valori delle variabili che stai utilizzando nel modello. Puoi eseguire alcune trasformazioni dei dati manifest nella Lambda di pre-annotazione, ma se non è necessario puoi mantenere basso il rischio di errori e la Lambda verrà eseguita più rapidamente. Di seguito è riportato un file manifest di esempio per il modello.

```
{"source-ref": "<S3 image URI>", "animal": "horse"}
{"source-ref": "<S3 image URI>", "animal" : "bird"}
{"source-ref": "<S3 image URI>", "animal" : "dog"}
{"source-ref": "<S3 image URI>", "animal" : "cat"}
```

## La tua funzione Lambda di pre-annotazione
<a name="sms-custom-templates-step2-demo1-pre-annotation"></a>

Come parte della configurazione del lavoro, fornite l'ARN di AWS Lambda una funzione che può essere chiamata per elaborare le voci del manifesto e passarle al motore dei modelli.

**Attribuzione di un nome alla funzione Lambda**  
Le best practice per la denominazione della funzione prevedono l'utilizzo di una delle quattro stringhe seguenti come parte del nome della funzione: `SageMaker`, `Sagemaker`, `sagemaker` o `LabelingFunction`. Questo vale per le funzioni sia di pre-annotazione che di post-annotazione.

Quando utilizzi la console, se disponi di funzioni AWS Lambda di proprietà del tuo account, verrà fornito un elenco a discesa di funzioni che soddisfano i requisiti di denominazione tra cui sceglierne una.

In questo esempio di base, passi informazioni al manifest senza ulteriori attività di elaborazione. Questo esempio di funzione di pre-annotazione è scritto per Python 3.7.

```
import json

def lambda_handler(event, context):
    return {
        "taskInput": event['dataObject']
    }
```

L'oggetto JSON del manifest verrà fornito come figlio dell'oggetto `event`. Le proprietà all'interno dell'oggetto `taskInput` saranno disponibili come variabili per il modello, perciò è sufficiente impostare il valore `taskInput` su `event['dataObject']` per passare tutti i valori dal tuo oggetto manifest al tuo modello senza doverli copiare uno a uno. Se vuoi inviare altri valori al modello, puoi aggiungerli all'oggetto `taskInput`.

## La tua funzione Lambda di post-annotazione
<a name="sms-custom-templates-step2-demo1-post-annotation"></a>

Come parte della configurazione del lavoro, fornite l'ARN di AWS Lambda una funzione che può essere chiamata per elaborare i dati del modulo quando un lavoratore completa un'attività. Questo può essere semplice o complesso quanto vuoi. Se desideri eseguire il consolidamento delle risposte e il punteggio non appena disponibili, puoi applicare gli algoritmi di consolidamento del punteggio che and/or preferisci. Se desideri archiviare i dati non elaborati per l’elaborazione offline, puoi farlo.

**Fornire autorizzazioni alla Lambda di pre-annotazione**  
I dati di annotazione saranno contenuti in un file designato dalla stringa `s3Uri` nell’oggetto `payload`. Per elaborare le annotazioni quando arrivano, anche per una semplice funzione passthrough, occorre assegnare l’accesso `S3ReadOnly` alla Lambda, in modo che possa leggere i file di annotazione.  
Nella pagina Console di creazione della Lambda, scorri fino al pannello **Execution role (Ruolo esecuzione)**. Seleziona **Create a new role from one or more templates (Crea un nuovo ruolo da uno o più modelli)**. Assegna un nome al ruolo. Dal menu a discesa **Policy templates (Modelli policy)**, scegli **Amazon S3 object read-only permissions (Autorizzazioni di sola lettura oggetto Amazon S3)**. Salva la Lambda; il ruolo verrà salvato e selezionato.

L'esempio seguente è in Python 2.7.

```
import json
import boto3
from urlparse import urlparse

def lambda_handler(event, context):
    consolidated_labels = []

    parsed_url = urlparse(event['payload']['s3Uri']);
    s3 = boto3.client('s3')
    textFile = s3.get_object(Bucket = parsed_url.netloc, Key = parsed_url.path[1:])
    filecont = textFile['Body'].read()
    annotations = json.loads(filecont);
    
    for dataset in annotations:
        for annotation in dataset['annotations']:
            new_annotation = json.loads(annotation['annotationData']['content'])
            label = {
                'datasetObjectId': dataset['datasetObjectId'],
                'consolidatedAnnotation' : {
                'content': {
                    event['labelAttributeName']: {
                        'workerId': annotation['workerId'],
                        'boxesInfo': new_annotation,
                        'imageSource': dataset['dataObject']
                        }
                    }
                }
            }
            consolidated_labels.append(label)
    
    return consolidated_labels
```

La Lambda di post-annotazione riceverà spesso batch di risultati dell’attività nell’oggetto evento. Questo batch sarà l’oggetto `payload` in cui Lambda esegue le iterazioni. Ciò che viene restituito sarà un oggetto che soddisfa il [contratto API](sms-custom-templates-step3.md).

## Output del processo di etichettatura
<a name="sms-custom-templates-step2-demo1-job-output"></a>

L’output del processo è disponibile in una cartella denominata in base al processo di etichettatura nel bucket S3 di destinazione specificato, all’interno di una sottocartella denominata `manifests`.

Per un'attività riquadro di delimitazione, l'aspetto dell'output disponibile nel manifest di output sarà simile alla demo sottostante. L'esempio è stato pulito per la stampa. L'output effettivo sarà una riga singola per record.

**Example : JSON nel manifest di output**  

```
{
  "source-ref":"<URL>",
  "<label attribute name>":
    {
       "workerId":"<URL>",
       "imageSource":"<image URL>",
       "boxesInfo":"{\"boundingBox\":{\"boundingBoxes\":[{\"height\":878, \"label\":\"bird\", \"left\":208, \"top\":6, \"width\":809}], \"inputImageProperties\":{\"height\":924, \"width\":1280}}}"},
  "<label attribute name>-metadata":
    {
      "type":"groundTruth/custom",
      "job_name":"<Labeling job name>",
      "human-annotated":"yes"
    },
  "animal" : "bird"
}
```
Nota che l'attributo `animal` aggiuntivo dal tuo manifest originale viene passato al manifest di output allo stesso livello di `source-ref` e dei dati di etichettatura. Tutte le proprietà del manifest di input, indipendentemente dal fatto che siano state utilizzati nel modello o meno, verranno passate al manifest di output.