<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Transparency on ICE-ICE-BEAR-BLOG</title><link>https://ice-ice-bear.github.io/tags/transparency/</link><description>Recent content in Transparency on ICE-ICE-BEAR-BLOG</description><generator>Hugo -- gohugo.io</generator><language>en</language><lastBuildDate>Tue, 07 Apr 2026 00:00:00 +0900</lastBuildDate><atom:link href="https://ice-ice-bear.github.io/tags/transparency/index.xml" rel="self" type="application/rss+xml"/><item><title>PopCon Dev Log #3 — Background Removal and APNG Transparency Pipeline</title><link>https://ice-ice-bear.github.io/posts/2026-04-07-popcon-dev3/</link><pubDate>Tue, 07 Apr 2026 00:00:00 +0900</pubDate><guid>https://ice-ice-bear.github.io/posts/2026-04-07-popcon-dev3/</guid><description>&lt;img src="https://ice-ice-bear.github.io/" alt="Featured image of post PopCon Dev Log #3 — Background Removal and APNG Transparency Pipeline" /&gt;&lt;p&gt;VEO 3.1 generates animation on solid backgrounds, but LINE animated emoji requires transparent APNGs. This post covers the post-processing pipeline built to strip backgrounds from every frame — from rembg-based initial removal through binary alpha thresholding, color decontamination, and edge refinement — plus all the RGBA plumbing changes needed in the resize, quantize, and assembly stages.&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;Previous post: &lt;a class="link" href="https://ice-ice-bear.github.io/en/posts/2026-04-03-popcon-dev2/" &gt;PopCon Dev Log #2&lt;/a&gt;&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h2 id="the-problem-opaque-backgrounds-from-veo"&gt;The Problem: Opaque Backgrounds from VEO
&lt;/h2&gt;&lt;p&gt;PopCon&amp;rsquo;s pipeline works like this:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Google Imagen generates character pose images&lt;/li&gt;
&lt;li&gt;VEO 3.1 converts pose images into animated video&lt;/li&gt;
&lt;li&gt;Frames are extracted from the video and assembled into APNG&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The problem: &lt;strong&gt;VEO always generates video with a solid background&lt;/strong&gt;. LINE animated emoji spec requires transparent-background APNGs, so per-frame background removal was essential.&lt;/p&gt;
&lt;p&gt;A simple chroma key approach (replacing a specific color with transparency) was insufficient. VEO&amp;rsquo;s background colors are inconsistent, and anti-aliased edges create semi-transparent pixels that blend foreground and background colors.&lt;/p&gt;
&lt;h2 id="design-multi-stage-background-removal-pipeline"&gt;Design: Multi-Stage Background Removal Pipeline
&lt;/h2&gt;&lt;p&gt;After research, we designed the following multi-stage pipeline:&lt;/p&gt;
&lt;pre class="mermaid" style="visibility:hidden"&gt;flowchart TD
 A["VEO 3.1 Video"] --&gt; B["Frame Extraction"]
 B --&gt; C["rembg Initial &amp;lt;br/&amp;gt; Background Removal"]
 C --&gt; D["Binary Alpha &amp;lt;br/&amp;gt; Thresholding"]
 D --&gt; E["Color Decontamination"]
 E --&gt; F["Edge Refinement &amp;lt;br/&amp;gt; Alpha Stabilization"]
 F --&gt; G["RGBA Resize"]
 G --&gt; H["Alpha-Preserving &amp;lt;br/&amp;gt; Quantization"]
 H --&gt; I["Transparent APNG &amp;lt;br/&amp;gt; Assembly"]&lt;/pre&gt;&lt;p&gt;What each stage solves:&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Stage&lt;/th&gt;
 &lt;th&gt;Problem Solved&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;rembg&lt;/td&gt;
 &lt;td&gt;AI-based foreground/background segmentation — more accurate than solid-color chroma key&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Binary Alpha&lt;/td&gt;
 &lt;td&gt;Cleans up semi-transparent pixels (alpha 128-254) left by rembg&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Color Decontamination&lt;/td&gt;
 &lt;td&gt;Removes background color bleeding into foreground edge pixels&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;Edge Refinement&lt;/td&gt;
 &lt;td&gt;Stabilizes alpha boundaries across frames to reduce flickering&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="implementation"&gt;Implementation
&lt;/h2&gt;&lt;h3 id="stage-1-rembg-based-background-removal"&gt;Stage 1: rembg-Based Background Removal
&lt;/h3&gt;&lt;p&gt;We added a &lt;code&gt;remove_background()&lt;/code&gt; function using the rembg library, which leverages U2-Net for foreground segmentation on each frame.&lt;/p&gt;
&lt;p&gt;Initial results were decent, but two problems emerged:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Semi-transparent edges&lt;/strong&gt;: Pixels with alpha values between 50-200 remained along character outlines, creating &amp;ldquo;ghost&amp;rdquo; borders in the APNG&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Color bleeding&lt;/strong&gt;: Background color mixed into the RGB values of edge pixels, leaving visible residue even after making them transparent&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="stage-2-binary-alpha-thresholding"&gt;Stage 2: Binary Alpha Thresholding
&lt;/h3&gt;&lt;p&gt;To fix the semi-transparent pixel problem, we applied binary thresholding to the alpha channel. Pixels above a threshold (e.g., 128) become fully opaque (255), and those below become fully transparent (0).&lt;/p&gt;
&lt;p&gt;This can make edges slightly rougher, but at emoji dimensions (LINE spec: 320x270), clean boundaries matter more than anti-aliasing smoothness.&lt;/p&gt;
&lt;h3 id="stage-3-color-decontamination"&gt;Stage 3: Color Decontamination
&lt;/h3&gt;&lt;p&gt;This stage corrects the RGB values of edge pixels contaminated by background color bleed. For pixels with low alpha (near-transparent), the background color contribution is mathematically removed.&lt;/p&gt;
&lt;p&gt;The principle: reverse the premultiplied alpha compositing to subtract the background color component. After this stage, edge colors look natural against any background.&lt;/p&gt;
&lt;h3 id="stage-4-edge-refinement-and-alpha-stabilization"&gt;Stage 4: Edge Refinement and Alpha Stabilization
&lt;/h3&gt;&lt;p&gt;When background removal runs independently per frame, the alpha boundary flickers between frames. Character outlines jitter by 1-2 pixels, especially in moving areas.&lt;/p&gt;
&lt;p&gt;To mitigate this, we applied erosion/dilation operations and Gaussian blur to alpha boundaries for inter-frame consistency.&lt;/p&gt;
&lt;h2 id="rgba-support-across-the-apng-pipeline"&gt;RGBA Support Across the APNG Pipeline
&lt;/h2&gt;&lt;p&gt;Updating the existing pipeline for RGBA was just as involved as the background removal itself. The existing code assumed RGB throughout.&lt;/p&gt;
&lt;h3 id="resize_frame-update"&gt;resize_frame() Update
&lt;/h3&gt;&lt;p&gt;The original resize logic pasted images onto a white canvas &lt;code&gt;(255, 255, 255)&lt;/code&gt;. For RGBA mode, this was changed to a &lt;strong&gt;transparent canvas&lt;/strong&gt; &lt;code&gt;(0, 0, 0, 0)&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id="_quantize_frames-update"&gt;_quantize_frames() Update
&lt;/h3&gt;&lt;p&gt;LINE animated emoji have a file size limit (300KB), making color quantization essential. The existing &lt;code&gt;Image.quantize()&lt;/code&gt; call ignored the alpha channel, quantizing only RGB.&lt;/p&gt;
&lt;p&gt;The fix: separate the alpha channel before quantization, quantize RGB only, then recompose — preserving transparency information throughout.&lt;/p&gt;
&lt;h3 id="process_video-pipeline-integration"&gt;process_video() Pipeline Integration
&lt;/h3&gt;&lt;p&gt;Finally, &lt;code&gt;remove_background()&lt;/code&gt; was wired into the &lt;code&gt;process_video()&lt;/code&gt; pipeline. It runs after frame extraction but before resize:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Frame Extraction → Background Removal → Resize → Quantize → APNG Assembly
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="research-notes"&gt;Research Notes
&lt;/h2&gt;&lt;p&gt;Beyond background removal, several related technologies were researched:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Frame Interpolation&lt;/strong&gt;: &lt;a class="link" href="https://github.com/google-research/frame-interpolation" target="_blank" rel="noopener"
 &gt;FILM&lt;/a&gt; and &lt;a class="link" href="https://github.com/hzwer/ECCV2022-RIFE" target="_blank" rel="noopener"
 &gt;RIFE&lt;/a&gt; — explored for generating smoother animations when VEO produces insufficient frames. Not yet integrated, but potentially needed in the next iteration.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Wan 2.1&lt;/strong&gt;: Evaluated as an alternative video generation model to VEO. Accessible via Alibaba Cloud&amp;rsquo;s DashScope API or fal.ai.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;APNG creation&lt;/strong&gt;: Investigated the Aspose Python library for APNG generation, but decided to keep the existing Pillow-based approach.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="commit-log"&gt;Commit Log
&lt;/h2&gt;&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;Commit Message&lt;/th&gt;
 &lt;th&gt;Changes&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;docs: add post-process background removal design spec&lt;/td&gt;
 &lt;td&gt;Design document for background removal&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;docs: add post-process background removal implementation plan&lt;/td&gt;
 &lt;td&gt;Implementation plan document&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;chore: add .worktrees/ to gitignore&lt;/td&gt;
 &lt;td&gt;Ignore git worktree directory&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;feat: add remove_background() with rembg and alpha edge stabilization&lt;/td&gt;
 &lt;td&gt;Core background removal function with alpha edge stabilization&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;feat: update resize_frame() to support RGBA with transparent canvas&lt;/td&gt;
 &lt;td&gt;RGBA transparent canvas support in resize&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;feat: update _quantize_frames() to preserve alpha channel&lt;/td&gt;
 &lt;td&gt;Alpha channel preservation during quantization&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;feat: wire remove_background() into process_video() pipeline&lt;/td&gt;
 &lt;td&gt;Integrate background removal into the video processing pipeline&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;test: add end-to-end APNG transparency verification&lt;/td&gt;
 &lt;td&gt;E2E test for APNG transparency&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;fix: clean up intermediate directories after frame processing&lt;/td&gt;
 &lt;td&gt;Clean up temp directories after frame processing&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;feat: post-process background removal with rembg on extracted VEO frames&lt;/td&gt;
 &lt;td&gt;Apply rembg post-processing to VEO frames&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;feat: enhance background removal with binary alpha, color decontamination, and edge refinement&lt;/td&gt;
 &lt;td&gt;Quality improvements with binary alpha, color decontamination, edge refinement&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;feat: enhance background removal (continued)&lt;/td&gt;
 &lt;td&gt;Continued background removal improvements&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="next-steps"&gt;Next Steps
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Evaluate frame interpolation integration (FILM or RIFE)&lt;/li&gt;
&lt;li&gt;Automate A/B testing for background removal quality&lt;/li&gt;
&lt;li&gt;Optimize VEO prompts to reduce background removal burden&lt;/li&gt;
&lt;li&gt;Final LINE spec validation and submission testing&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>