Skip to content

feat(tuya_t5_pocket): add edge-locked Atkinson and gamma-serpentine dithering - #677

Merged
shiliu-yang merged 3 commits into
tuya:masterfrom
maidang-xing:feat/t5-pocket-edge-atkinson-gamma-serpentine-dither
Aug 18, 2026
Merged

feat(tuya_t5_pocket): add edge-locked Atkinson and gamma-serpentine dithering#677
shiliu-yang merged 3 commits into
tuya:masterfrom
maidang-xing:feat/t5-pocket-edge-atkinson-gamma-serpentine-dither

Conversation

@maidang-xing

@maidang-xing maidang-xing commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds two dithering methods to the T5 Pocket camera's YUV422->binary pipeline: BINARY_METHOD_EDGE_ATKINSON (edge-locked Atkinson, bold poster-like look with crisp outlines) and BINARY_METHOD_GAMMA_SERPENTINE (gamma-corrected serpentine Floyd-Steinberg, brightens shadow detail before dithering).
  • Both are selectable via the existing method-cycling UI already in camera_screen.c (no new UI needed).
  • Both use a per-frame adaptive black/white threshold instead of a fixed one, since raw camera luma isn't gamma-corrected like a normal photo and a fixed threshold otherwise crushes darker scenes to mostly-black.
  • Also ports the same two methods into the shared src/tal_image component (TAL_IMAGE_MONO_MTH_EDGE_ATKINSON / TAL_IMAGE_MONO_MTH_GAMMA_SERPENTINE), which was already linked into this and other apps (your_robot_dog, your_chat_bot, lvgl_games, etc.) but not previously used by the T5 Pocket camera path -- the app had its own separate copy of the same 9 base algorithms. Adding the two new methods there too keeps both implementations in sync and makes them available to any app calling tal_image_format_yuv422_to_binary().
  • bayer_dither.py (moved to apps/tuya_t5_pocket/tools/, alongside compare_dither.py and png2lvgl_raw.py) gets matching PC-side ports (edge_atkinson_dither, gamma_serpentine_dither) used to validate these constants against real photos before porting to C.

Test plan

  • tos.py build succeeds for T5AI / TUYA_T5AI_POCKET (both the app-local copy and the shared tal_image component)
  • Flashed to a real T5 Pocket device; cycled camera capture through all methods including the two new ones
  • Validated dithering output visually via the PC-side Python ports on multiple test photos before tuning the C-side constants
  • Reviewer: confirm on-device visual output matches expectations for your test scenes
  • Reviewer: consider a follow-up build of another tal_image-consuming app (e.g. your_chat_bot) to double-check the shared component change

🤖 Generated with Claude Code

maidang-xing and others added 3 commits August 17, 2026 20:01
…ithering

Add two ordered/error-diffusion dithering methods to the camera YUV422->binary
pipeline (BINARY_METHOD_EDGE_ATKINSON, BINARY_METHOD_GAMMA_SERPENTINE),
selectable via the existing method-cycling UI in camera_screen.c.

- Edge-locked Atkinson: locks high-contrast edges to solid black (via a raw
  3x3 Laplacian magnitude, gated by brightness) and Atkinson-diffuses the
  rest, giving a bold poster-like look while keeping outlines crisp.
- Gamma-corrected serpentine Floyd-Steinberg: brightens shadow detail via a
  gamma LUT before dithering (since raw camera luma isn't gamma-corrected
  and error diffusion otherwise preserves the source's true, often darker,
  average brightness), with scan direction alternating per row.
- Both use calculate_adaptive_threshold()/gamma(mean(raw)) for a per-frame
  black/white split instead of a fixed threshold tuned for normal photos.

bayer_dither.py gets PC-side ports (edge_atkinson_dither, gamma_serpentine_dither)
used to validate these constants against real photos before porting to C.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Add the local dev tooling used to validate/generate dithering output for
the T5 Pocket display, and keep the one remaining sample PHOTO asset:

- compare_dither.py: runs all bayer_dither.py algorithms against test
  photos and composites them into a single comparison grid image.
- tools/png2lvgl_raw.py: embeds PNGs as raw-byte lv_img_dsc_t C arrays
  (same format already used by tuya_floyd.c / tuyaopen_logo).
- photos/photo_image2_gamma_serpentine_dither.c: sample output of the new
  gamma-serpentine dither, wired into the build via CMakeLists.txt (not
  currently referenced by any screen).
- .gitignore: ignore the local .agents/ tooling directory.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
bayer_dither.py and compare_dither.py are PC-side test/dev scripts, not
part of the firmware build (nothing in CMakeLists.txt or C code references
them). Move them next to the existing png2lvgl_raw.py and ditter-converter/
tooling in apps/tuya_t5_pocket/tools/, out of src/display/ which should
only contain compiled display source.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@shiliu-yang
shiliu-yang merged commit 3d6c4f5 into tuya:master Aug 18, 2026
1 check 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.

2 participants