<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Signals &amp; Image Processing Series on Mi&amp;Bee Blog</title><link>https://blog.mickeyzzc.tech/en/series/signals--image-processing-series/</link><description>Recent content in Signals &amp; Image Processing Series on Mi&amp;Bee Blog</description><generator>Hugo -- gohugo.io</generator><language>en</language><managingEditor>蓝宝石的傻话</managingEditor><lastBuildDate>Sun, 28 Jun 2026 10:00:00 +0800</lastBuildDate><atom:link href="https://blog.mickeyzzc.tech/en/series/signals--image-processing-series/rss.xml" rel="self" type="application/rss+xml"/><item><title>Image Basics &amp; Getting Started with OpenCV</title><link>https://blog.mickeyzzc.tech/en/posts/physical-world/image-basics-opencv/</link><pubDate>Fri, 08 May 2026 10:00:00 +0800</pubDate><guid>https://blog.mickeyzzc.tech/en/posts/physical-world/image-basics-opencv/</guid><description>&lt;h2 id="what-is-a-digital-image"&gt;What Is a Digital Image&lt;/h2&gt;
&lt;p&gt;Computer vision operates on digital images. At its core, a digital image is just a 2D array of pixels.&lt;/p&gt;
&lt;h3 id="pixels-and-grayscale-images"&gt;Pixels and Grayscale Images&lt;/h3&gt;
&lt;p&gt;A grayscale image is the simplest form—each pixel stores a single brightness value from 0 (pure black) to 255 (pure white). In Python, a grayscale image of width W and height H is a 2D array with shape &lt;code&gt;(H, W)&lt;/code&gt;:&lt;/p&gt;
&lt;div class="code-block-wrapper" data-lang="python"&gt;
 &lt;div class="code-block-header"&gt;
 &lt;div class="code-block-meta"&gt;&lt;span class="code-language"&gt;python&lt;/span&gt;&lt;/div&gt;
 
 &lt;button class="copy-button" aria-label="Copy code"&gt;
 &lt;svg class="copy-icon" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;rect x="9" y="9" width="13" height="13" rx="2" ry="2"/&gt;&lt;path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/&gt;&lt;/svg&gt;
 &lt;svg class="check-icon" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"&gt;&lt;polyline points="20 6 9 17 4 12"/&gt;&lt;/svg&gt;
 &lt;/button&gt;
 
 &lt;/div&gt;
 &lt;div class="code-block-body"&gt;&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt;1
&lt;/span&gt;&lt;span class="lnt"&gt;2
&lt;/span&gt;&lt;span class="lnt"&gt;3
&lt;/span&gt;&lt;span class="lnt"&gt;4
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;numpy&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;np&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Create a 100x100 gray square (brightness 128)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;gray_img&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;full&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;128&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dtype&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uint8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;&lt;code&gt;uint8&lt;/code&gt; ranges from 0 to 255 because 8 bits can represent 2^8 = 256 unique values. If a pixel value exceeds its range, &lt;strong&gt;wrap around&lt;/strong&gt; occurs: 255 + 1 becomes 0, not 256 (like an odometer rolling over). Use &lt;code&gt;cv2.add()&lt;/code&gt; (saturating arithmetic) or &lt;code&gt;np.clip()&lt;/code&gt; to prevent wrap around.&lt;/p&gt;</description></item><item><title>Image Degradation Models — Where Does Blur Come From?</title><link>https://blog.mickeyzzc.tech/en/posts/physical-world/image-degradation-model/</link><pubDate>Fri, 05 Jun 2026 10:00:00 +0800</pubDate><guid>https://blog.mickeyzzc.tech/en/posts/physical-world/image-degradation-model/</guid><description>&lt;h2 id="why-do-photos-get-blurry"&gt;Why Do Photos Get Blurry?&lt;/h2&gt;
&lt;p&gt;Scrolling through your phone gallery, you will always encounter such regrets: at the moment you pressed the shutter, you captured a beautiful moment, but the photo turned out blurry — maybe due to shaky hands, insufficient light, or the subject moving too fast. Old photos are even worse — the passage of time makes memories from back then become fuzzy.&lt;/p&gt;
&lt;p&gt;Blur is not accidental. In the world of digital imaging, every photo undergoes a complex transformation process from the real scene to digital signals. Light passes through the lens, falls on the sensor, gets recorded by electronic systems — every link may introduce &amp;ldquo;degradation.&amp;rdquo; Understanding how these degradations occur is the first step to studying image restoration from a mathematical perspective.&lt;/p&gt;</description></item><item><title>Image Interpolation — From Nearest Neighbor to Bicubic</title><link>https://blog.mickeyzzc.tech/en/posts/physical-world/image-interpolation-methods/</link><pubDate>Mon, 08 Jun 2026 10:00:00 +0800</pubDate><guid>https://blog.mickeyzzc.tech/en/posts/physical-world/image-interpolation-methods/</guid><description>&lt;h2 id="why-interpolation-matters"&gt;Why Interpolation Matters&lt;/h2&gt;
&lt;p&gt;Imagine you have a low-resolution photo and want to print it larger. Between every two pixels in the original image is now a &amp;ldquo;blank space&amp;rdquo; — where do the new pixels come from?&lt;/p&gt;
&lt;p&gt;Interpolation is the solution: using known pixel values to estimate values at unknown positions. Image upscaling is essentially an interpolation problem.&lt;/p&gt;
$$ \text{Upscaled Image} = \text{Interpolation Algorithm}(\text{Original Pixels}) $$&lt;p&gt;The quality of interpolation directly affects the upscaled image. Too simple methods produce mosaic artifacts, while too complex methods may introduce ringing artifacts. Let&amp;rsquo;s progress step by step, from the simplest nearest neighbor interpolation to the most commonly used bicubic interpolation.&lt;/p&gt;</description></item><item><title>Frequency Domain Restoration — Inverse and Wiener Filtering</title><link>https://blog.mickeyzzc.tech/en/posts/physical-world/frequency-domain-restoration/</link><pubDate>Fri, 12 Jun 2026 10:00:00 +0800</pubDate><guid>https://blog.mickeyzzc.tech/en/posts/physical-world/frequency-domain-restoration/</guid><description>&lt;h2 id="why-work-in-the-frequency-domain"&gt;Why Work in the Frequency Domain&lt;/h2&gt;
&lt;p&gt;In the previous post we built the image degradation model: the observed image $g(x,y)$ is the original image $f(x,y)$ convolved with a degradation function $h(x,y)$ and corrupted by additive noise $n(x,y)$:&lt;/p&gt;
$$g(x,y) = h(x,y) * f(x,y) + n(x,y)$$&lt;p&gt;Restoration means: given $g$ and $h$, recover $f$ as closely as possible.&lt;/p&gt;
&lt;p&gt;In the spatial domain, this requires solving a deconvolution problem. Deconvolution is a massive linear system. For a $512 \times 512$ image, you face 260,000 unknowns. Direct solving is practically impossible.&lt;/p&gt;</description></item><item><title>Spatial Domain Restoration &amp; Edge-Preserving Filters</title><link>https://blog.mickeyzzc.tech/en/posts/physical-world/spatial-domain-restoration/</link><pubDate>Tue, 16 Jun 2026 10:00:00 +0800</pubDate><guid>https://blog.mickeyzzc.tech/en/posts/physical-world/spatial-domain-restoration/</guid><description>&lt;p&gt;The previous post introduced frequency domain image processing methods — transforming images to the frequency domain via Fourier transform, then performing filtering, restoration, and other operations. However, frequency domain methods are sometimes less intuitive, especially when we&amp;rsquo;re more accustomed to directly manipulating pixels.&lt;/p&gt;
&lt;p&gt;Spatial domain methods process images directly in pixel space, without requiring transformations. This chapter introduces spatial domain image restoration, edge-preserving filtering, and sharpening techniques.&lt;/p&gt;
&lt;h2 id="lucy-richardson-iterative-deconvolution"&gt;Lucy-Richardson Iterative Deconvolution&lt;/h2&gt;
&lt;p&gt;The goal of deconvolution is to recover the original image from a degraded image. The degradation process is typically modeled as convolution: degraded image = original image convolved with blur kernel + noise.&lt;/p&gt;</description></item><item><title>Deep Learning Super-Resolution — SRCNN and SRGAN</title><link>https://blog.mickeyzzc.tech/en/posts/physical-world/dl-super-resolution-srcnn-srgan/</link><pubDate>Sat, 20 Jun 2026 10:00:00 +0800</pubDate><guid>https://blog.mickeyzzc.tech/en/posts/physical-world/dl-super-resolution-srcnn-srgan/</guid><description>&lt;h2 id="from-mathematical-models-to-data-driven-learning"&gt;From Mathematical Models to Data-Driven Learning&lt;/h2&gt;
&lt;p&gt;In super-resolution tasks, traditional methods rely on carefully designed mathematical models—interpolation algorithms, sparse representation, prior constraints, and so on. But deep learning brought a paradigm shift: directly learning the mapping from degraded space to clear space from massive paired low-resolution (LR) and high-resolution (HR) image data.&lt;/p&gt;
&lt;p&gt;The core idea is simple: train a neural network $F_{\theta}$ that can map low-resolution images to high-resolution images:&lt;/p&gt;</description></item><item><title>Modern Super-Resolution — From ESRGAN to Diffusion Models</title><link>https://blog.mickeyzzc.tech/en/posts/physical-world/modern-super-resolution-esrgan-diffusion/</link><pubDate>Wed, 24 Jun 2026 10:00:00 +0800</pubDate><guid>https://blog.mickeyzzc.tech/en/posts/physical-world/modern-super-resolution-esrgan-diffusion/</guid><description>&lt;div class="sr-evo" id="sr-evo-0"&gt;
 &lt;div class="sr-evo__track"&gt;
 &lt;div class="sr-evo__rail" id="sr-evo-rail-0"&gt;
 &lt;div class="sr-evo__fill" id="sr-evo-fill-0"&gt;&lt;/div&gt;
 &lt;/div&gt;
 &lt;div class="sr-evo__item" data-idx="0" id="sr-evo-item-0-0"&gt;
 &lt;div class="sr-evo__dot" style="--c:#FF9800"&gt;2014&lt;/div&gt;
 &lt;div class="sr-evo__card"&gt;
 &lt;div class="sr-evo__head"&gt;SRCNN&lt;/div&gt;
 &lt;div class="sr-evo__body"&gt;三层卷积 · 3-layer CNN&lt;/div&gt;
 &lt;div class="sr-evo__foot"&gt;pioneered DL SR&lt;/div&gt;
 &lt;/div&gt;
 &lt;/div&gt;
 &lt;div class="sr-evo__item" data-idx="1" id="sr-evo-item-0-1"&gt;
 &lt;div class="sr-evo__dot" style="--c:#9C27B0"&gt;2016&lt;/div&gt;
 &lt;div class="sr-evo__card"&gt;
 &lt;div class="sr-evo__head"&gt;SRGAN&lt;/div&gt;
 &lt;div class="sr-evo__body"&gt;感知损失 &amp;#43; GAN&lt;/div&gt;
 &lt;div class="sr-evo__foot"&gt;visual quality leap&lt;/div&gt;
 &lt;/div&gt;
 &lt;/div&gt;
 &lt;div class="sr-evo__item" data-idx="2" id="sr-evo-item-0-2"&gt;
 &lt;div class="sr-evo__dot" style="--c:#9C27B0"&gt;2018&lt;/div&gt;
 &lt;div class="sr-evo__card"&gt;
 &lt;div class="sr-evo__head"&gt;ESRGAN&lt;/div&gt;
 &lt;div class="sr-evo__body"&gt;RRDB &amp;#43; RaGAN&lt;/div&gt;
 &lt;div class="sr-evo__foot"&gt;richer features, no BN&lt;/div&gt;
 &lt;/div&gt;
 &lt;/div&gt;
 &lt;div class="sr-evo__item" data-idx="3" id="sr-evo-item-0-3"&gt;
 &lt;div class="sr-evo__dot" style="--c:#4CAF50"&gt;2021&lt;/div&gt;
 &lt;div class="sr-evo__card"&gt;
 &lt;div class="sr-evo__head"&gt;Real-ESRGAN&lt;/div&gt;
 &lt;div class="sr-evo__body"&gt;真实退化建模 · Real-world&lt;/div&gt;
 &lt;div class="sr-evo__foot"&gt;works on real photos&lt;/div&gt;
 &lt;/div&gt;
 &lt;/div&gt;
 &lt;div class="sr-evo__item" data-idx="4" id="sr-evo-item-0-4"&gt;
 &lt;div class="sr-evo__dot" style="--c:#2196F3"&gt;2021&lt;/div&gt;
 &lt;div class="sr-evo__card"&gt;
 &lt;div class="sr-evo__head"&gt;SwinIR&lt;/div&gt;
 &lt;div class="sr-evo__body"&gt;Transformer 注意力&lt;/div&gt;
 &lt;div class="sr-evo__foot"&gt;global context modeling&lt;/div&gt;
 &lt;/div&gt;
 &lt;/div&gt;
 &lt;div class="sr-evo__item" data-idx="5" id="sr-evo-item-0-5"&gt;
 &lt;div class="sr-evo__dot" style="--c:#2196F3"&gt;2022&lt;/div&gt;
 &lt;div class="sr-evo__card"&gt;
 &lt;div class="sr-evo__head"&gt;Diffusion&lt;/div&gt;
 &lt;div class="sr-evo__body"&gt;迭代去噪 · Iterative&lt;/div&gt;
 &lt;div class="sr-evo__foot"&gt;best quality, slowest&lt;/div&gt;
 &lt;/div&gt;
 &lt;/div&gt;
 &lt;/div&gt;
&lt;/div&gt;
&lt;style&gt;
.sr-evo{margin:2rem auto;max-width:360px}
.sr-evo__track{position:relative;padding-left:44px}
.sr-evo__rail{position:absolute;left:21px;top:20px;bottom:20px;width:2px;background:var(--border);border-radius:1px;overflow:hidden}
.sr-evo__fill{position:absolute;top:0;left:0;width:100%;height:0;background:linear-gradient(#FF9800,#9C27B0 30%,#4CAF50 60%,#2196F3 85%);transition:height .8s cubic-bezier(.4,0,.2,1)}
.sr-evo__item{position:relative;padding:10px 0;opacity:0;transform:translateX(-16px);transition:opacity .6s,transform .6s}
.sr-evo__item.visible{opacity:1;transform:translateX(0)}
.sr-evo__dot{position:absolute;left:-34px;top:12px;width:28px;height:28px;border-radius:50%;background:var(--c,var(--accent));display:flex;align-items:center;justify-content:center;font-size:9px;font-weight:800;color:#fff;z-index:1;box-shadow:0 0 0 3px var(--bg)}
.sr-evo__card{background:var(--bg-surface);border:1px solid var(--border);border-radius:var(--radius-md);padding:8px 12px}
.sr-evo__head{font-size:14px;font-weight:700;color:var(--text)}
.sr-evo__body{font-size:11.5px;color:var(--text-secondary);margin-top:2px;line-height:1.4}
.sr-evo__foot{font-size:10.5px;color:var(--text-secondary);opacity:.65;margin-top:1px}
@media(max-width:480px){
.sr-evo{max-width:100%;margin:1.5rem 0}
.sr-evo__track{padding-left:38px}
.sr-evo__rail{left:17px}
.sr-evo__dot{left:-29px;width:24px;height:24px;font-size:8px;top:14px}
.sr-evo__item{padding:8px 0}
.sr-evo__card{padding:6px 10px}
.sr-evo__head{font-size:13px}
}
&lt;/style&gt;
&lt;script&gt;
(function(){var id='0',items=document.querySelectorAll('#sr-evo-'+id+' .sr-evo__item'),fill=document.getElementById('sr-evo-fill-'+id),n=items.length;if(!n||!fill)return;var intv=1200,idx=0,started=0,prm=window.matchMedia('(prefers-reduced-motion: reduce)').matches;function topAt(i){var rail=document.getElementById('sr-evo-rail-'+id),rr=rail.getBoundingClientRect(),dr=items[i].querySelector('.sr-evo__dot').getBoundingClientRect();return dr.top-rr.top+dr.height/2}function setH(h){fill.style.height=Math.round(h)+'px'}function next(){if(idx&gt;=n)return;items[idx].classList.add('visible');setH(topAt(idx));idx++;if(idx&lt;n)setTimeout(next,intv);else setH(topAt(n-1))}function all(){for(var i=0;i&lt;n;i++)items[i].classList.add('visible');setH(topAt(n-1))}if(prm){all();return}if('IntersectionObserver'in window){var wrap=document.getElementById('sr-evo-'+id);new IntersectionObserver(function(e){e.forEach(function(e){if(e.isIntersecting&amp;&amp;!started){started=1;setTimeout(next,300)}})},{threshold:.25}).observe(wrap)}else all()})();
&lt;/script&gt;
&lt;h2 id="from-srgan-to-esrgan-2018"&gt;From SRGAN to ESRGAN (2018)&lt;/h2&gt;
&lt;p&gt;SRGAN (Super-Resolution GAN) introduced Generative Adversarial Networks (GANs) to super-resolution in 2016, achieving significant visual quality improvements over traditional PSNR-optimization methods through perceptual loss. However, SRGAN still had room for improvement. &lt;strong&gt;ESRGAN&lt;/strong&gt; (Enhanced Super-Resolution GAN) by Wang et al. in 2018 optimized four key directions.&lt;/p&gt;</description></item><item><title>Implementing Image Restoration in Go and Rust</title><link>https://blog.mickeyzzc.tech/en/posts/physical-world/image-restoration-go-rust/</link><pubDate>Sun, 28 Jun 2026 10:00:00 +0800</pubDate><guid>https://blog.mickeyzzc.tech/en/posts/physical-world/image-restoration-go-rust/</guid><description>&lt;p&gt;This post implements core image restoration algorithms in Go and Rust, comparing the two languages&amp;rsquo; approaches to image processing through practical code.&lt;/p&gt;
&lt;div class="blur-wrap" id="blur-0"&gt;
 &lt;div class="blur-head"&gt;
 &lt;span&gt;原始图像&lt;/span&gt;
 &lt;span&gt;退化图像&lt;/span&gt;
 &lt;/div&gt;
 &lt;canvas class="blur-canvas" id="blur-c-0"
 role="img" aria-label="Sharp image vs blurred image simulation with different PSF types"&gt;&lt;/canvas&gt;
 &lt;div class="blur-bar"&gt;
 &lt;span class="blur-name" id="blur-n-0"&gt;—&lt;/span&gt;
 &lt;span class="blur-psf" id="blur-p-0"&gt;—&lt;/span&gt;
 &lt;/div&gt;

&lt;style&gt;
.blur-wrap{margin:1.8rem auto;max-width:420px;background:var(--bg-surface,#f3f0f6);border:1px solid var(--border,#e5e1eb);border-radius:var(--radius-md,8px);padding:0.5rem 0.5rem 0.35rem}
.blur-head{display:flex;justify-content:space-between;font-size:11px;color:var(--text-secondary,#888);padding:0 0.15rem 0.25rem}
.blur-canvas{display:block;width:100%;height:auto;border-radius:4px}
.blur-bar{text-align:center;margin-top:0.35rem;padding-top:0.3rem;border-top:1px solid var(--border,#e5e1eb)}
.blur-name{display:block;font-size:12px;font-weight:600;color:var(--text,#333);margin-bottom:0.1rem}
.blur-psf{display:block;font-size:10px;font-family:var(--font-mono,monospace);color:var(--text-secondary,#888);letter-spacing:0.01em}
@media(max-width:480px){.blur-wrap{max-width:100%;margin:1.2rem 0}}
@media(prefers-reduced-motion:reduce){.blur-canvas{opacity:0.85}}
&lt;/style&gt;
&lt;script&gt;
(function(){
var c=document.getElementById('blur-c-0'),nEl=document.getElementById('blur-n-0'),pEl=document.getElementById('blur-p-0');
if(!c)return;
var ctx=c.getContext('2d'),dpr=1,W=0,H=0,half=0,rm=window.matchMedia('(prefers-reduced-motion:reduce)').matches;
var states=[
{n:'原始图像（锐利）',p:'无需 PSF — 理想点成像'},
{n:'高斯模糊 σ=1.5',p:'G(x,y) = (1/2πσ²)·exp(-(x²+y²)/2σ²)'},
{n:'运动模糊 L=5,θ=45°',p:'H(u,v)=T·sinc(π(a·u+b·v))·e^(-jπ(a·u+b·v))'},
{n:'散焦模糊 r=3',p:'PSF(r)=1/πr² (√(x²+y²) ≤ r)'}
];
var idx=0,timer=null,off=document.createElement('canvas'),offC=off.getContext('2d');
function dims(){
var r=c.parentElement.getBoundingClientRect(),w=Math.floor(r.width)-4;
return{w:w&lt;100?100:w,h:Math.round(w*0.56)||56}
}
function ptn(ax,w,h,ox,oy){
var cx=ox+w*0.25,cy=oy+h*0.35,mr=Math.min(w,h)*0.32,sr=Math.max(6,mr/6|0);
ax.fillStyle='#f0eef2';ax.fillRect(ox,oy,w,h);
ax.strokeStyle='#1a1a2e';ax.lineWidth=1.5;
for(var r=sr;r&lt;=mr;r+=sr){ax.beginPath();ax.arc(cx,cy,r,0,7);ax.stroke()}
ax.strokeStyle='#2d3436';ax.lineWidth=1;
for(var i=0;i&lt;12;i++){var a=i/12*6.2832;ax.beginPath();ax.moveTo(cx,cy);ax.lineTo(cx+Math.cos(a)*mr,cy+Math.sin(a)*mr);ax.stroke()}
var bx=ox+w*0.58,by=oy+h*0.06,sz=Math.max(3,Math.min(6,(w*0.035)|0));
for(var r2=0;r2&lt;8;r2++)for(var c2=0;c2&lt;8;c2++){ax.fillStyle=(r2+c2)&amp;1?'#ddd':'#16213e';ax.fillRect(bx+c2*sz,by+r2*sz,sz,sz)}
var lx=ox+w*0.7,ly=oy+h*0.55;
for(var i=0;i&lt;10;i++){var bw=Math.max(1,((10-i)*0.5)|0);ax.fillStyle='#0a0a23';ax.fillRect(lx+i*(bw+2),ly,bw,h*0.15)}
var hx=ox+w*0.12,hy=oy+h*0.73;
for(var i=0;i&lt;6;i++){ax.fillStyle=i&amp;1?'#e9e9ed':'#0a0a23';ax.fillRect(hx,hy+i*4,w*0.18,4)}
ax.fillStyle='#1a1a2e';ax.font='bold '+(Math.max(8,(w*0.038)|0))+'px -apple-system,sans-serif';
ax.textAlign='center';ax.textBaseline='bottom';ax.fillText('蓝宝石 123',ox+w/2,oy+h-4)
}
function blurRight(ax,x,y,w,h,si){
ax.save();ax.beginPath();ax.rect(x,y,w,h);ax.clip();
if(si===0){ptn(ax,w,h,x,y)}
else if(si===1||si===3){ax.filter=si===1?'blur(3px)':'blur(6px)';ptn(ax,w,h,x,y);ax.filter='none'}
else{
off.width=Math.ceil(w*dpr);off.height=Math.ceil(h*dpr);
offC.setTransform(dpr,0,0,dpr,0,0);ptn(offC,w,h,0,0);
var st=10,dd=Math.round(Math.min(w,h)*0.025);
for(var i=0;i&lt;st;i++){ax.globalAlpha=0.12;ax.drawImage(off,x+i/st*dd,y+i/st*dd,w,h)}
ax.globalAlpha=1
}
ax.restore()
}
function draw(){
var gap=2,lw=half-gap,rw=W-half-gap,rx=half+gap;
ctx.clearRect(0,0,W,H);ptn(ctx,lw,H,0,0);blurRight(ctx,rx,0,rw,H,idx);
ctx.strokeStyle='rgba(128,128,128,0.2)';ctx.lineWidth=1;
ctx.beginPath();ctx.moveTo(half,0);ctx.lineTo(half,H);ctx.stroke();
var s=states[idx];nEl.textContent=s.n;pEl.textContent=s.p
}
function next(){idx=(idx+1)%states.length;draw()}
function resize(){
var d=dims();W=d.w;H=d.h;half=W/2|0;dpr=window.devicePixelRatio||1;
c.width=Math.round(W*dpr);c.height=Math.round(H*dpr);
c.style.width=W+'px';c.style.height=H+'px';ctx.setTransform(dpr,0,0,dpr,0,0);draw()
}
resize();
new ResizeObserver(function(){resize()}).observe(c.parentElement);
var mq=window.matchMedia('(prefers-reduced-motion:reduce)');
mq.addEventListener('change',function(e){rm=e.matches;if(rm&amp;&amp;timer){clearInterval(timer);timer=null}else if(!rm&amp;&amp;!timer)timer=setInterval(next,3000)});
if(!rm)timer=setInterval(next,3000)
})();
&lt;/script&gt;
&lt;/div&gt;

&lt;h2 id="go-implementation"&gt;Go Implementation&lt;/h2&gt;
&lt;p&gt;Go&amp;rsquo;s standard &lt;code&gt;image&lt;/code&gt; library provides image encoding/decoding and pixel access. The following implementation demonstrates how to implement bicubic interpolation, Gaussian blur, and Laplacian sharpening in Go.&lt;/p&gt;</description></item><item><title>Acoustic Waves &amp; Digital Signal Processing Basics</title><link>https://blog.mickeyzzc.tech/en/posts/physical-world/acoustics-dsp-basics/</link><pubDate>Mon, 04 May 2026 10:00:00 +0800</pubDate><guid>https://blog.mickeyzzc.tech/en/posts/physical-world/acoustics-dsp-basics/</guid><description>&lt;h2 id="destructive-interference"&gt;Destructive Interference&lt;/h2&gt;
&lt;p&gt;Active noise cancellation (ANC) builds on a simple physical principle: destructive interference. Two sound waves of the same frequency and opposite phase cancel each other out.&lt;/p&gt;
&lt;p&gt;The original noise signal:&lt;/p&gt;
$$
p_n(t) = A \cos(2\pi ft + \phi)
$$&lt;p&gt;The anti-noise generated by the ANC system:&lt;/p&gt;
$$
p_c(t) = -A \cos(2\pi ft + \phi) = A \cos(2\pi ft + \phi + \pi)
$$&lt;p&gt;Superposition:&lt;/p&gt;
$$
p_{\text{total}} = p_n(t) + p_c(t) = 0
$$&lt;p&gt;That is the ideal case. In a real ANC headset, the anti-noise travels from the speaker to the eardrum through an acoustic path, and the electronics introduce latency. If the phase shift is off by even a few degrees, or the amplitudes don&amp;rsquo;t match, cancellation degrades fast.&lt;/p&gt;</description></item><item><title>Adaptive Filtering: From LMS to NLMS</title><link>https://blog.mickeyzzc.tech/en/posts/physical-world/adaptive-filtering-lms-nlms/</link><pubDate>Thu, 07 May 2026 10:00:00 +0800</pubDate><guid>https://blog.mickeyzzc.tech/en/posts/physical-world/adaptive-filtering-lms-nlms/</guid><description>&lt;h2 id="the-lms-algorithm"&gt;The LMS Algorithm&lt;/h2&gt;
&lt;p&gt;The core problem in adaptive filtering is: given a reference signal &lt;code&gt;x(n)&lt;/code&gt; and a desired signal &lt;code&gt;d(n)&lt;/code&gt;, find a filter coefficient vector &lt;code&gt;w&lt;/code&gt; such that the output &lt;code&gt;y(n)&lt;/code&gt; approximates &lt;code&gt;d(n)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The Least Mean Square (LMS) algorithm is the most classic solution to this problem, proposed by Widrow and Hoff in 1960. The core idea is to take one step down the steepest gradient of the error surface at each iteration — stochastic gradient descent.&lt;/p&gt;</description></item><item><title>FXLMS and Active Noise Control System Architecture</title><link>https://blog.mickeyzzc.tech/en/posts/physical-world/fxlms-anc-architecture/</link><pubDate>Mon, 11 May 2026 10:00:00 +0800</pubDate><guid>https://blog.mickeyzzc.tech/en/posts/physical-world/fxlms-anc-architecture/</guid><description>&lt;p&gt;Active Noise Control (ANC) works by generating an acoustic wave with equal amplitude and opposite phase to the incoming noise, canceling it through destructive interference at the target zone. Translating this into hardware requires two decisions: which sensors to use for noise sensing, and what control strategy to apply for anti-noise generation. These two factors define the three canonical ANC architectures: feedforward, feedback, and hybrid.&lt;/p&gt;
&lt;h2 id="feedforward-anc"&gt;Feedforward ANC&lt;/h2&gt;
&lt;p&gt;A feedforward ANC system places a reference microphone upstream of the noise source to capture the disturbance early, feeds it to the DSP, and drives the speaker to produce the anti-noise. An error microphone near the ear monitors the residual noise and feeds it back to the adaptive algorithm for coefficient update.&lt;/p&gt;</description></item><item><title>Variable Step Size and Frequency-Domain Adaptive Algorithms</title><link>https://blog.mickeyzzc.tech/en/posts/physical-world/variable-step-frequency-domain/</link><pubDate>Thu, 14 May 2026 10:00:00 +0800</pubDate><guid>https://blog.mickeyzzc.tech/en/posts/physical-world/variable-step-frequency-domain/</guid><description>&lt;h2 id="the-convergence-trade-off-of-fixed-step-size"&gt;The Convergence Trade-off of Fixed Step Size&lt;/h2&gt;
&lt;p&gt;Standard LMS and NLMS algorithms use a fixed step size parameter $\mu$. The choice of step size directly impacts algorithm performance, but a fundamental contradiction exists:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Large step size&lt;/strong&gt;: Fast convergence and quick adaptation to environmental changes, but large steady-state error and low filtering precision&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Small step size&lt;/strong&gt;: Small steady-state error and high filtering precision, but slow convergence and sluggish response to abrupt changes&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This contradiction is particularly pronounced in applications such as echo cancellation and active noise control — the system needs fast convergence during startup, yet wishes to maintain low error in steady state. A fixed step size cannot satisfy both phases simultaneously.&lt;/p&gt;</description></item><item><title>Embedded ANC: STM32 in Practice</title><link>https://blog.mickeyzzc.tech/en/posts/physical-world/embedded-anc-stm32/</link><pubDate>Mon, 18 May 2026 10:00:00 +0800</pubDate><guid>https://blog.mickeyzzc.tech/en/posts/physical-world/embedded-anc-stm32/</guid><description>&lt;h2 id="hardware-architecture"&gt;Hardware Architecture&lt;/h2&gt;
&lt;p&gt;Implementing real-time ANC begins with selecting the right hardware platform. The controller must complete adaptive filtering within microseconds while managing multiple audio data streams.&lt;/p&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Module&lt;/th&gt;
					&lt;th&gt;Function&lt;/th&gt;
					&lt;th&gt;Typical Choice&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Main Controller&lt;/td&gt;
					&lt;td&gt;Executes adaptive algorithm&lt;/td&gt;
					&lt;td&gt;STM32F4/F7, ESP32-S3, nRF5340&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Reference Mic&lt;/td&gt;
					&lt;td&gt;Captures ambient noise&lt;/td&gt;
					&lt;td&gt;Knowles SPH0645, Infineon IM69D130&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Error Mic&lt;/td&gt;
					&lt;td&gt;Captures residual noise&lt;/td&gt;
					&lt;td&gt;Knowles SPH0645, TDK ICS-43434&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Audio DAC&lt;/td&gt;
					&lt;td&gt;Outputs anti-noise signal&lt;/td&gt;
					&lt;td&gt;ES9218, PCM5102&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Amplifier&lt;/td&gt;
					&lt;td&gt;Drives speaker&lt;/td&gt;
					&lt;td&gt;Class-D&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The reference microphone sits outside the earcup and captures external ambient noise as the algorithm&amp;rsquo;s reference input. The error microphone sits inside the earcup near the speaker, capturing residual noise for evaluating cancellation performance and driving adaptive updates. The audio DAC converts the digital anti-noise signal to analog, which is amplified by a Class-D amplifier to drive the speaker.&lt;/p&gt;</description></item><item><title>Embedded ANC: ESP32 Practice</title><link>https://blog.mickeyzzc.tech/en/posts/physical-world/embedded-anc-esp32/</link><pubDate>Thu, 21 May 2026 10:00:00 +0800</pubDate><guid>https://blog.mickeyzzc.tech/en/posts/physical-world/embedded-anc-esp32/</guid><description>&lt;p&gt;The ESP32-S3&amp;rsquo;s dual-core Xtensa LX7 processor with vector instruction set extensions is well-suited for the real-time DSP workloads required by embedded ANC. Combined with the ESP-DSP library, efficient adaptive filtering becomes practical on this platform.&lt;/p&gt;
&lt;h2 id="i2s-microphone-capture"&gt;I2S Microphone Capture&lt;/h2&gt;
&lt;p&gt;ANC requires at least two synchronous input channels: a reference microphone (capturing ambient noise) and an error microphone (capturing residual error). The ESP32-S3 I2S peripheral supports simultaneous multi-channel ADC data reception. Configuring it for 16-bit, 16 kHz sampling suffices for consumer-grade ANC.&lt;/p&gt;</description></item><item><title>ANC Tuning &amp; Performance Optimization</title><link>https://blog.mickeyzzc.tech/en/posts/physical-world/anc-tuning-debugging/</link><pubDate>Mon, 25 May 2026 10:00:00 +0800</pubDate><guid>https://blog.mickeyzzc.tech/en/posts/physical-world/anc-tuning-debugging/</guid><description>&lt;p&gt;In engineering practice, the most time-consuming and experience-dependent part of an active noise control system is not algorithm selection, but parameter tuning and stability debugging. Filter order, step size, sampling rate — each parameter interacts with the others in ways that are not always obvious. This article draws from hands-on experience to cover the key parameter selection logic and common troubleshooting approaches in ANC tuning.&lt;/p&gt;
&lt;h2 id="filter-order-selection"&gt;Filter Order Selection&lt;/h2&gt;
&lt;p&gt;The FIR filter order $N$ directly determines two core metrics: frequency resolution and computational complexity. Getting this choice wrong reveals itself early in debugging — poor noise reduction, slow convergence, or outright divergence.&lt;/p&gt;</description></item><item><title>IMU Fundamentals: Accelerometer and Gyroscope</title><link>https://blog.mickeyzzc.tech/en/posts/physical-world/imu-accelerometer-gyroscope/</link><pubDate>Fri, 15 May 2026 10:00:00 +0800</pubDate><guid>https://blog.mickeyzzc.tech/en/posts/physical-world/imu-accelerometer-gyroscope/</guid><description>&lt;p&gt;Opening post of the Motion Sensing series. Sensors are the window through which embedded systems perceive the physical world, and the IMU (Inertial Measurement Unit) is the most common type. This article skips heavy theory — just how MEMS sensors work, how to wire them, how to read data, and what the numbers actually look like.&lt;/p&gt;
&lt;h2 id="imu-coordinate-system"&gt;IMU Coordinate System&lt;/h2&gt;
&lt;p&gt;The diagram below defines the three axes of the IMU — all formulas and discussions that follow are based on this coordinate system:&lt;/p&gt;</description></item></channel></rss>