Skip to content

[feat] util img: dedicated function for converting RGB data to RGB8#3259

Merged
pieleric merged 1 commit intodelmic:masterfrom
pieleric:feat-util-img-dedicated-function-for-converting-rgb-data-to-rgb8
Jan 4, 2026
Merged

[feat] util img: dedicated function for converting RGB data to RGB8#3259
pieleric merged 1 commit intodelmic:masterfrom
pieleric:feat-util-img-dedicated-function-for-converting-rgb-data-to-rgb8

Conversation

@pieleric
Copy link
Copy Markdown
Member

@pieleric pieleric commented Nov 3, 2025

Converting from RGB to RGB should be simple... and it used to be handled
by essentially copying the data. Just a basic code to handle tint.
However, this works well only if the data is already uint8.
For uint16, this didn't work. Also, the range wasn't computed.

=> introduce projectYXC2RGB8() to handle explicitly such method, and use
in when the data is in "YXC" format.
In particular, this helps opening Tescan RGB 16-bits images.

Copy link
Copy Markdown

Copilot AI left a comment

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 introduces a new utility function projectYXC2RGB8 to handle RGB/RGBA image projection with intensity range mapping and tinting, refactoring existing inline code in the stream projection module.

  • Adds projectYXC2RGB8 function in img.py for converting YXC-format RGB/RGBA data to uint8 RGB with intensity range and tint support
  • Refactors _projectTile method in _projection.py to use the new function instead of inline tint handling
  • Adds comprehensive test coverage for the new function including RGB, RGBA, different data types, and tint scenarios

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 6 comments.

File Description
src/odemis/util/img.py Adds projectYXC2RGB8 function with support for RGB/RGBA conversion, intensity range mapping, and tinting; adds Optional to type imports
src/odemis/acq/stream/_projection.py Refactors _projectTile to use projectYXC2RGB8 for cleaner RGB tile processing
src/odemis/util/test/img_test.py Adds TestProjectYXC2RGB8 test class with comprehensive coverage for various input types and tint scenarios

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

Comment thread src/odemis/util/img.py Outdated
Comment thread src/odemis/util/img.py Outdated
Comment thread src/odemis/util/img.py Outdated
Comment thread src/odemis/util/img.py
Comment thread src/odemis/acq/stream/_projection.py
Comment thread src/odemis/util/img.py Outdated
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Nov 3, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

Walkthrough

RGB tile projection in the acquisition stream now produces a new DataArray containing RGB data instead of mutating the input tile: it obtains an intensity range via self.stream._getDisplayIRange(), calls the new utility projectYXC2RGB8() to convert YXC RGB/RGBA arrays to 8-bit RGB(A) with optional tinting, and sets updated metadata with MD_DIMS = "YXC". A public projectYXC2RGB8() function was added to src/odemis/util/img.py. Unit tests for this function were added to src/odemis/util/test/img_test.py. The patch contains duplicate implementations of the function and duplicate test class entries.

Sequence Diagram(s)

mermaid
sequenceDiagram
participant StreamProjection as Stream._projection
participant Stream as Stream (source)
participant ImgUtil as util.img.projectYXC2RGB8
participant Meta as Stream._find_metadata
participant Model as model.DataArray

StreamProjection->>Stream: receive tile
StreamProjection->>Stream: _getDisplayIRange()
Stream-->>StreamProjection: irange
StreamProjection->>ImgUtil: projectYXC2RGB8(tile.data, irange, tint)
ImgUtil-->>StreamProjection: rgb ndarray (uint8)
StreamProjection->>Meta: _find_metadata(tile.metadata)
Meta-->>StreamProjection: md (new dict)
StreamProjection->>StreamProjection: set md[MD_DIMS] = "YXC"
StreamProjection->>Model: wrap rgb ndarray with md
Model-->>StreamProjection: DataArray (RGB)
StreamProjection-->>Caller: return DataArray (RGB)

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: introducing a dedicated function for RGB to RGB8 conversion.
Description check ✅ Passed The description is related to the changeset, explaining the motivation (handling uint16 data, computing range) and the solution (introducing projectYXC2RGB8).
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d3f4182 and 463fd3e.

📒 Files selected for processing (3)
  • src/odemis/acq/stream/_projection.py (1 hunks)
  • src/odemis/util/img.py (3 hunks)
  • src/odemis/util/test/img_test.py (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/odemis/util/test/img_test.py
  • src/odemis/util/img.py
🧰 Additional context used
🧬 Code graph analysis (1)
src/odemis/acq/stream/_projection.py (4)
src/odemis/acq/stream/_base.py (2)
  • _getDisplayIRange (972-986)
  • _find_metadata (988-1028)
src/odemis/util/img.py (1)
  • ensureYXC (704-734)
src/odemis/acq/stream/_static.py (1)
  • _find_metadata (333-340)
src/odemis/model/_dataflow.py (1)
  • DataArray (42-95)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build (ubuntu-22.04)
  • GitHub Check: build (ubuntu-24.04)
🔇 Additional comments (1)
src/odemis/acq/stream/_projection.py (1)

1076-1089: LGTM! Clean implementation of the RGB8 conversion path.

The changes correctly implement the RGB to RGB8 conversion using the new dedicated function projectYXC2RGB8(). Key improvements:

  • Properly obtains the intensity range needed for uint16 data conversion
  • Ensures YXC order before conversion
  • Validates tint parameter with appropriate fallback
  • Creates a new DataArray instead of mutating the input tile
  • Correctly handles metadata via _find_metadata which already returns a new dict

This implementation addresses the PR objectives to support RGB 16-bit images (e.g., Tescan) by computing the data range during conversion.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c0714e5 and 4322ba5.

📒 Files selected for processing (3)
  • src/odemis/acq/stream/_projection.py (1 hunks)
  • src/odemis/util/img.py (2 hunks)
  • src/odemis/util/test/img_test.py (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
src/odemis/acq/stream/_projection.py (3)
src/odemis/acq/stream/_base.py (2)
  • _getDisplayIRange (972-986)
  • _find_metadata (988-1028)
src/odemis/util/img.py (2)
  • ensureYXC (702-732)
  • projectYXC2RGB8 (489-578)
src/odemis/model/_dataflow.py (1)
  • DataArray (42-95)
src/odemis/util/test/img_test.py (1)
src/odemis/util/img.py (1)
  • projectYXC2RGB8 (489-578)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: CodeQL analysis (python)
  • GitHub Check: lint
  • GitHub Check: build (ubuntu-24.04)
  • GitHub Check: build (ubuntu-22.04)

Comment thread src/odemis/util/img.py
Comment thread src/odemis/util/img.py Outdated
@pieleric pieleric force-pushed the feat-util-img-dedicated-function-for-converting-rgb-data-to-rgb8 branch from 4322ba5 to d3f4182 Compare November 28, 2025 16:30
@pieleric pieleric requested a review from tmoerkerken November 28, 2025 16:30
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (1)
src/odemis/util/img.py (1)

489-489: Broaden the type hint for irange to support numeric types.

The type hint Optional[Tuple[int, int]] is too restrictive. At line 524, irange is cast to data.dtype, which can be float or other numeric types. The hint should reflect this flexibility.

Apply this diff:

-def projectYXC2RGB8(data: numpy.ndarray, irange: Optional[Tuple[int, int]] = None,
+def projectYXC2RGB8(data: numpy.ndarray, irange: Optional[Tuple[float, float]] = None,
                     tint: Tuple[int, int, int] = (255, 255, 255)) -> numpy.ndarray:

Based on past review comments (Copilot's feedback on type hints).

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4322ba5 and d3f4182.

📒 Files selected for processing (3)
  • src/odemis/acq/stream/_projection.py (1 hunks)
  • src/odemis/util/img.py (3 hunks)
  • src/odemis/util/test/img_test.py (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/odemis/util/test/img_test.py
  • src/odemis/acq/stream/_projection.py
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build (ubuntu-22.04)
  • GitHub Check: build (ubuntu-24.04)

Comment thread src/odemis/util/img.py
Comment thread src/odemis/util/img.py
Converting from RGB to RGB should be simple... and it used to be handled
by essentially copying the data. Just a basic code to handle tint.
However, this works well only if the data is already uint8.
For uint16, this didn't work. Also, the range wasn't computed.

=> introduce projectYXC2RGB8() to handle explicitly such method, and use
in when the data is in "YXC" format.
In particular, this helps opening Tescan RGB 16-bits images.
@pieleric pieleric force-pushed the feat-util-img-dedicated-function-for-converting-rgb-data-to-rgb8 branch from d3f4182 to 463fd3e Compare December 16, 2025 09:01
@pieleric pieleric merged commit 5d77d29 into delmic:master Jan 4, 2026
5 checks passed
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.

4 participants