Skip to content

LUT range incorrectly copied when processing images #288

@PierreRaybaut

Description

@PierreRaybaut

LUT range incorrectly copied when processing images

ℹ️ This issue is related to this Sigima Issue

Summary

When processing an image in DataLab (e.g., subtracting offset), the LUT range (Look-Up Table range, stored as zscalemin/zscalemax in ImageObj) from the original image is copied to the result image. This causes incorrect visualization when the processed data has a significantly different value range than the original.

Steps to Reproduce

  1. Load an image in DataLab (e.g., laser_spot_array.png)
  2. View the image - the LUT is auto-computed to fit the data range (e.g., ~50 to ~200 lsb)
  3. Apply "Subtract offset" using a background area (Processing → Offset correction)
    • For example, using ROI: x0=65.0, y0=61.0, Δx=312.0, Δy=20.0
  4. The result image appears incorrectly displayed (may show as completely black or with wrong contrast)

Expected Behavior

The result image should have its LUT range auto-computed to fit the new data range (e.g., ~-5 to ~175 after subtracting ~50 from the original values).

Actual Behavior

The result image uses the original image's LUT range (~50 to 200), which doesn't match the new data range (-5 to ~175). This causes:

  • Parts of the image to appear clipped or saturated
  • In some cases, the image appears completely black or with no visible contrast
  • Users need to manually adjust the LUT to see the data correctly

Root Cause

The generic dst_1_to_1() function in sigima/proc/base.py calls src.copy() to create result objects. Since ImageObj.copy() faithfully copies all attributes including zscalemin and zscalemax, the LUT range was being inherited even though the data values have changed.

Solution

Created image-specific wrapper functions in sigima/proc/image/base.py that reset the LUT range after copying:

  • dst_1_to_1() - for 1-to-1 image processing
  • dst_2_to_1() - for 2-to-1 image processing
  • dst_n_to_1() - for n-to-1 image processing

These wrappers call the generic base functions, then reset zscalemin and zscalemax to None so the result image auto-scales on display.

The ImageObj.copy() method remains unchanged - a copy should faithfully copy all attributes. The fix is applied at the processing layer where it belongs.

Files Changed

  • sigima/proc/image/base.py: Added image-specific dst_1_to_1, dst_2_to_1, dst_n_to_1 wrappers
  • sigima/proc/image/*.py: Updated imports to use wrappers from sigima.proc.image.base
  • sigima/tests/image/offset_correction_unit_test.py: Added regression test

Affected Versions

  • Sigima ≤ 1.0.4
  • DataLab ≤ 1.0.x (when using Sigima ≤ 1.0.4)

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions