Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix for #93 #94

Closed
wants to merge 3 commits into from
Closed

Fix for #93 #94

wants to merge 3 commits into from

Conversation

Ownmarc
Copy link
Collaborator

@Ownmarc Ownmarc commented Apr 17, 2020

Quick fix for #93 without diving in react-image-annotate

Quick fix for #93 without diving in react-image-annotate
@Ownmarc
Copy link
Collaborator Author

Ownmarc commented Apr 17, 2020

Works well for Segmentation, but I am getting bugs with classification (and I didn't test the others).

@Ownmarc
Copy link
Collaborator Author

Ownmarc commented Apr 17, 2020

Works well for Segmentation, but I am getting bugs with classification (and I didn't test the others).

fixed by checking if we are in image_segmentation

Copy link
Collaborator

@seveibar seveibar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if this is the right level of abstraction to fix #93 because some people may cycle through their image annotation, and the "empty" state is actually the "done" state for purposes of displaying the samples (example below helps clarify this). I've asked a question on #93 which will help clarify the level of abstraction that is appropriate, but I have a feeling the right place for this functionality is in the <ImageSegmentation /> component or the useLocalStorage file-handler

Consider the following object created in the current version of the editor with the image segmentation template. Notice that the last sample has an empty array rather than null, because I hit save with no regions selected.

{
  "interface": {
    "type": "image_segmentation",
    "availableLabels": [
      "valid",
      "invalid"
    ],
    "regionTypesAllowed": [
      "bounding-box",
      "polygon",
      "point"
    ]
  },
  "taskData": [
    {
      "imageUrl": "https://s3.amazonaws.com/asset.workaround.online/example-jobs/sticky-notes/image1.jpg"
    },
    {
      "imageUrl": "https://s3.amazonaws.com/asset.workaround.online/example-jobs/sticky-notes/image2.jpg"
    }
  ],
  "taskOutput": [
    [
      {
        "regionType": "bounding-box",
        "centerX": 0.2962962962962963,
        "centerY": 0.3313253012048193,
        "width": 0.3891120035698349,
        "height": 0.15127175368139223,
        "color": "hsl(139,100%,50%)"
      }
    ],
    []
  ]
}

After this change (if I understand the change correctly), upon repeating the steps I did above this object would become...

{
  "interface": {
    "type": "image_segmentation",
    "availableLabels": [
      "valid",
      "invalid"
    ],
    "regionTypesAllowed": [
      "bounding-box",
      "polygon",
      "point"
    ]
  },
  "taskData": [
    {
      "imageUrl": "https://s3.amazonaws.com/asset.workaround.online/example-jobs/sticky-notes/image1.jpg"
    },
    {
      "imageUrl": "https://s3.amazonaws.com/asset.workaround.online/example-jobs/sticky-notes/image2.jpg"
    }
  ],
  "taskOutput": [
    [
      {
        "regionType": "bounding-box",
        "centerX": 0.2962962962962963,
        "centerY": 0.3313253012048193,
        "width": 0.3891120035698349,
        "height": 0.15127175368139223,
        "color": "hsl(139,100%,50%)"
      }
    ],
    null
  ]
}

I think this new behavior is probably OK. I just want to mention there's a use case where someone wants to mark a sample as "done" after reviewing it, and an empty array is also an OK way to say, "there are no regions". If the concern of #93 is performance, we should considering modifying useLocalStorage with a periodic check, e.g. every 10 seconds if it has changed. If that creates stuttering, we could also modify how objects are stored in local storage to make writes smaller.

This PR can be considered a checkpoint and merged, just wanted to document some thoughts. See the small changes I mentioned in the code.

src/components/OHAEditor/index.js Show resolved Hide resolved
oha.taskOutput[singleSampleOHA.sampleIndex] !== null
) {
const o1 = oha["taskOutput"][singleSampleOHA.sampleIndex]
const o2 = newOHA["taskOutput"][singleSampleOHA.sampleIndex]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

something very useful about seamless immutable objects is you can usually just do o1 === o2

Copy link
Collaborator Author

@Ownmarc Ownmarc Apr 18, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that compares keys length ?

@Ownmarc
Copy link
Collaborator Author

Ownmarc commented Apr 18, 2020

You understand it correctly. [] would be the way to say there is nothing in it and null would be a state where no one has passed on the image yet. Maybe there could be something added in the annotation to explicitly say what state the annotation is in (example: has to be reviewed, reviewed, final, ground truth, etc.)

null ->[] would trigger onChangeOHA whil [] -> [] would not trigger onChangeOHA

@seveibar
Copy link
Collaborator

seveibar commented Apr 21, 2020

So the fix here is very related to #32 and sample state being unclear. @Ownmarc is right that we need to represent the state of sample better. I think there's a good potential to do this while integrating the brush proposal into the UDT JSON. We're pushing out some awesome changes this week to make UDT work as a importable React or native javascript library (the last npm module is pretty out of date) but then I think this issue will take full focus. I'll make sure to CC everyone here on the format change proposal and include sample state management.

@Ownmarc curious if you have any thoughts on #32, I'm not sure if we should introduce JSONL yet. I do think this format would be more intuitive and make it clearer how to represent sample state:

{
  "interface": { /* ... */ },
  "samples": Array<{
      /* document, imageUrl etc. */
     "state": "needs-review",
     "output": {
      /* entities etc. */
     }
   }>
}

@seveibar seveibar closed this Apr 21, 2020
@CedricJean CedricJean deleted the patch-1 branch May 8, 2020 21:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants