Skip to content

Add custom label colors for textbox mode - #18

Open
karenhes wants to merge 8 commits into
synced-with-serverfrom
feature/textbox-colored-labels
Open

Add custom label colors for textbox mode#18
karenhes wants to merge 8 commits into
synced-with-serverfrom
feature/textbox-colored-labels

Conversation

@karenhes

Copy link
Copy Markdown
Collaborator

The color is now linked to the label in textbox mode, i.e., if you choose label 1 you get a specific color for all images with label 1. I hope this is easier to review!

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR links textbox-mode custom labels to deterministic colors, so the same label text renders consistently across frames/images and persists server-side when saving annotations.

Changes:

  • Generate a deterministic hex color from custom label text on the client and apply it to slider markers / label display.
  • Send a custom_frame_label_colors mapping (label name → RGB) to the backend during save.
  • Persist custom label colors in save_labels() when creating/using Label rows.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 8 comments.

File Description
subsequence_classification/views.py Parses posted custom label colors and applies them to Label records when saving subsequence annotations.
subsequence_classification/static/subsequence_classification/subsequence_classification.js Adds deterministic label→color hashing, includes color mapping in save payload, and updates UI coloring for textbox-mode labels.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread subsequence_classification/views.py Outdated
Comment on lines +158 to +159
print(f"Custom label: {custom_label}, Created: {created}, Colors: {custom_label_colors.get(custom_label)}")
#if created:

Copilot AI Mar 25, 2026

Copy link

Choose a reason for hiding this comment

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

This debug print(...) logs user-provided label values/colors and will add noise in production. Please switch to the project’s logging approach (or remove) so sensitive/user-input data isn’t printed to stdout.

Copilot uses AI. Check for mistakes.
Comment on lines 191 to 195
label, created = Label.objects.get_or_create(
name=custom_label,
#task=annotation.image_annotation.task,
defaults={'color_red': 0, 'color_green': 255, 'color_blue': 0}
#defaults={'color_red': 0, 'color_green': 255, 'color_blue': 0}
)

Copilot AI Mar 25, 2026

Copy link

Choose a reason for hiding this comment

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

Same issue as above: Label.objects.get_or_create(name=custom_label) can throw MultipleObjectsReturned because Label.name is not unique. Use a safe lookup/create approach or add a uniqueness constraint to prevent save failures.

Copilot uses AI. Check for mistakes.
Comment thread subsequence_classification/views.py Outdated
Comment on lines 403 to +409
$('#currentFrameLabel').text(customLabel);
$('#currentFrameLabelDisplay').text(customLabel);

$('#currentFrameLabel').html(`<span style="color: ${color}">${customLabel}</span>`);
$('#currentFrameLabelDisplay').html(
`<span style="color: ${color}">${customLabel}</span>`
);

Copilot AI Mar 25, 2026

Copy link

Choose a reason for hiding this comment

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

customLabel comes from user input, but it’s interpolated into .html(...) without escaping, which enables XSS (e.g., a label like <img src=x onerror=...>). Use .text() and set the color via CSS (or build a span element and set textContent) instead of inserting raw HTML.

Suggested change
$('#currentFrameLabel').text(customLabel);
$('#currentFrameLabelDisplay').text(customLabel);
$('#currentFrameLabel').html(`<span style="color: ${color}">${customLabel}</span>`);
$('#currentFrameLabelDisplay').html(
`<span style="color: ${color}">${customLabel}</span>`
);
const customLabelSpan = $('<span>').text(customLabel).css('color', color);
$('#currentFrameLabel').empty().append(customLabelSpan.clone());
$('#currentFrameLabelDisplay').empty().append(customLabelSpan);

Copilot uses AI. Check for mistakes.
Comment thread subsequence_classification/views.py Outdated
Comment thread subsequence_classification/views.py Outdated
Comment on lines 153 to 157
label, created = Label.objects.get_or_create(
name=custom_label,
#task=annotation.image_annotation.task,
defaults={'color_red': 128, 'color_green': 128, 'color_blue': 128}
#defaults={'color_red': 128, 'color_green': 128, 'color_blue': 128}
)

Copilot AI Mar 25, 2026

Copy link

Choose a reason for hiding this comment

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

Label.objects.get_or_create(name=custom_label) can raise MultipleObjectsReturned if the DB already contains multiple Label rows with the same name (the Label.name field is not unique). Consider enforcing uniqueness (model constraint) or switching to a deterministic selection strategy (e.g., filter(name=...).order_by('id').first() plus create-if-missing) so saves don’t intermittently 500.

Copilot uses AI. Check for mistakes.

@jpdefrutos jpdefrutos left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

The funcionality works as expected. Some corrections and checks need to be put in place before approving.

Ideally, the "textbox" label functionality should be compatible with predefined labels. This can be set as a feature to be added later on.


}

function stringToColor(str) {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

When the new label is similar to a previously defined one e.g., LabelA and LabelB, the generated colour is the same. Check whether the generated colour has already been used, and change it otherwise.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Ok, I can try to fix this, but haven't done it yet.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

ok, submit your changes when done :)

}

function addLabelButton(label_id, label_name, red, green, blue, parent_id) {
function addLabelButton(label_id, label_name, color_red, color_green, color_blue, parent_id) {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

These changes are not related to the original PR.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Ok, I changed it because it was defined like color_red in the views.py, but maybe it doesn't matter?

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

It doesn't matter

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed reverted to red, green and blue in the latest commit.

Comment thread subsequence_classification/views.py Outdated
Comment thread subsequence_classification/views.py Outdated
Comment thread subsequence_classification/views.py Outdated
name=custom_label,
#task=annotation.image_annotation.task,
defaults={'color_red': 0, 'color_green': 255, 'color_blue': 0}
#defaults={'color_red': 0, 'color_green': 255, 'color_blue': 0}

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Remove unused code

Comment thread subsequence_classification/views.py Outdated
Comment thread subsequence_classification/views.py Outdated
karenhes and others added 4 commits April 17, 2026 11:30
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Label exists and already has a colour, this should be preserved

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
}

function addLabelButton(label_id, label_name, red, green, blue, parent_id) {
function addLabelButton(label_id, label_name, color_red, color_green, color_blue, parent_id) {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

It doesn't matter


}

function stringToColor(str) {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

ok, submit your changes when done :)

…ToColor function now checks whether the generated colour has already been used, and changes it otherwise.
ehof pushed a commit that referenced this pull request May 21, 2026
  Replace the cycling fixed-palette approach with a hash-based color
  generation scheme aligned with PR #18 (feature/textbox-colored-labels):

  - Add stringToColor() using the polynomial hash + golden angle (137.508°)
    mapping to HSL hue, so similar labels get visually distinct colors
  - Add hslToHex() helper to produce well-saturated, consistent colors
  - Cache label→color in g_labelColorMap so the same label always gets
    the same color within and across sessions
  - Auto-create missing Label entries in the shared Label model (with RGB
    color) and link them to the task on save, if not already present
  - Drop BronchoscopyBoundingBox.color — color is now derived from the
    label name rather than stored per box
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