第 26 篇:区域采样统计—马赛克、彩色玻璃与油画效果
区域采样统计—马赛克、彩色玻璃与油画效果系列导语本文是有趣的图像处理系列第 26 篇。主题是三种视觉风格化效果背后统一的数学框架区域采样统计——把图像划分为若干区域用区域内像素的某种统计量来替换颜色不同的统计量产生截然不同的视觉效果。导语把一张照片变成油画、马赛克或彩色玻璃效果看起来像是三种完全不同的操作实际上背后是同一套算法框架的三个变体对每个目标像素在其对应的源区域内计算统计量用统计量替换像素颜色。区别只在区域怎么划分和用哪种统计量效果区域形状统计量视觉结果马赛克/像素化固定方块均值平均颜色像素化、打码感彩色玻璃固定方块均值同上强调色块边界镶嵌玻璃感油画圆形邻域众数最频繁亮度对应颜色笔触感、绘画质感这条线索——均值、中值第07篇、众数——恰好串起了排序统计滤波的完整图谱。本文补上其中众数这个此前未单独讲过的角色。一、马赛克/像素化——方块均值1.1 原理像素化的思路极简把图像切成k × k k \times kk×k的方块每块内所有像素用该块的平均颜色替换。I out ( x , y ) 1 k 2 ∑ ( i , j ) ∈ block ( x , y ) I ( i , j ) I_{\text{out}}(x,y) \frac{1}{k^2} \sum_{(i,j) \in \text{block}(x,y)} I(i,j)Iout(x,y)k21(i,j)∈block(x,y)∑I(i,j)其中block ( x , y ) \text{block}(x,y)block(x,y)是像素( x , y ) (x,y)(x,y)所属的k × k k \times kk×k方块。为什么产生像素化感均值把方块内所有细节抹平成一个颜色相邻方块之间出现硬边产生低分辨率的方块感——正是低分辨率屏幕或早期像素游戏的视觉特征。块大小的影响k 4 k4k4轻微像素化细节仍可辨k 16 k16k16明显马赛克适合隐私保护k 64 k64k64极端抽象只剩颜色块轮廓1.2 伪代码函数 像素化(图像 I, 块大小 k): 对每个块起点 (bx, by)步长 k: # 提取该块 block I[by:byk, bx:bxk] # 计算均值颜色 avg_R mean(block[:,:,0]) avg_G mean(block[:,:,1]) avg_B mean(block[:,:,2]) # 整块填充均值颜色 I_out[by:byk, bx:bxk] (avg_R, avg_G, avg_B) 返回 I_out向量化实现OpenCV 版快 8–9 倍函数 像素化_快速(图像 I, 块大小 k): h, w I.shape[:2] # 缩小再放大自动计算块均值 small resize(I, (w//k, h//k), 插值AREA) # 块均值 I_out resize(small, (w, h), 插值NEAREST) # 恢复尺寸保持硬边 返回 I_out左原图 / 右像素化block_size16。图像被切割成 16×16 的方块每块显示该区域的平均颜色细节消失主体轮廓以方块形式保留。二、彩色玻璃——均值 硬边界2.1 与马赛克的区别彩色玻璃Stained Glass和马赛克在数学上几乎完全相同——都是方块均值。区别在于马赛克强调低分辨率的像素感通常用于隐私保护彩色玻璃强调方块之间的颜色对比和边界线视觉上模拟铅制框架镶嵌彩色玻璃实现上的差异彩色玻璃通常在方块边界处额外绘制深色轮廓线1–2px 宽模拟铅框的视觉效果。2.2 Voronoi 版本的彩色玻璃用规则方块划分不够自然用Voronoi 单元第20篇替换方块能产生更像真实彩色玻璃的有机形状V i { ( x , y ) ∣ d ( ( x , y ) , p i ) ≤ d ( ( x , y ) , p j ) , ∀ j ≠ i } V_i \{(x,y) \mid d((x,y), p_i) \leq d((x,y), p_j),\ \forall j \neq i\}Vi{(x,y)∣d((x,y),pi)≤d((x,y),pj),∀ji}对每个 Voronoi 单元用单元内像素的均值颜色填充——这正是 Voronoi 图最直接的图像处理应用。2.3 伪代码函数 彩色玻璃(图像 I, 格子大小 cell, 边框宽度 border1): 对每个块起点 (bx, by)步长 cell: block I[by:bycell, bx:bxcell] avg mean(block, axis(0,1)) I_out[by:bycell, bx:bxcell] avg # 绘制边框深色线 若 border 0: I_out[by:byborder, bx:bxcell] 0 # 上边 I_out[by:bycell, bx:bxborder] 0 # 左边 返回 I_out左原图 / 右彩色玻璃cell_size20。图像被划分为 20×20 的色块每块填充均值颜色整体呈现镶嵌彩玻璃的拼贴感花朵的红色与背景的绿色形成鲜明对比。三、油画效果——众数统计3.1 从均值到众数马赛克和彩色玻璃取的是均值所有像素颜色的平均。油画效果取的是众数出现次数最多的颜色——这个选择产生了完全不同的视觉效果。为什么众数产生笔触感画家用油画笔触色时每一笔都是接近均匀的一块颜色内部几乎没有颜色变化。众数统计模拟了这个行为找到邻域内最主要的颜色众数把这种颜色涂到整个邻域——就像一笔笔涂色自然产生类似油画的笔触感。均值会保留邻域内的颜色过渡混色效果众数则会选择最纯粹的主导颜色产生更清晰、饱和的笔触效果。3.2 亮度量化 颜色统计直接对 RGB 颜色计算众数不合理颜色种类太多每个颜色可能只出现 1 次。实际算法步骤把亮度灰度值量化为L LL个等级通常L 8 L8L8–16 1616每个像素属于某个亮度等级统计邻域内每个亮度等级出现的次数和颜色总和找出出现次数最多的亮度等级众数等级用该等级所有像素的平均颜色替换当前像素量化等级L LL控制笔触细腻程度L LL越小颜色越少笔触越粗犷L LL越大颜色越丰富越接近原图。3.3 伪代码函数 油画效果(图像 I, 邻域半径 r, 量化等级 L): 对每个像素 (x, y): # 提取圆形邻域 邻域 I[y-r:yr1, x-r:xr1] (圆形裁剪) # 初始化各等级的计数和颜色累积 count[0..L-1] 0 color_sum[0..L-1] (0,0,0) # 统计邻域内每个像素 对邻域中每个像素 p: gray 0.299R 0.587G 0.114B # 计算亮度 level floor(gray / 256 × L) # 量化到等级 count[level] 1 color_sum[level] p.RGB # 找众数等级 max_level argmax(count) # 用众数等级的平均颜色替换 I_out[y,x] color_sum[max_level] / count[max_level] 返回 I_out时间复杂度O ( n ⋅ r 2 ⋅ L ) O(n \cdot r^2 \cdot L)O(n⋅r2⋅L)对 1200×628 图像r 3 r3r3L 256 L256L256约需 31 秒Python 纯实现。OpenCV 版本快约164 倍0.19 秒。左原图 / 右油画效果邻域半径3量化等级256。花瓣颜色更加饱和均匀边缘处出现类似笔触的色块感背景绿色被简化为大块纯色区域整体呈现出手绘油画的质感。四、三种效果的统一视角4.1 统计量决定视觉风格统计量对噪声的鲁棒性颜色保真度视觉效果均值中等中颜色混合偏淡平滑方块马赛克/玻璃感中值第07篇强去椒盐高保边平滑保边无风格化众数弱多数投票高选主色笔触饱满油画感4.2 区域形状决定纹理风格规则方块→ 像素化、马赛克、彩色玻璃硬边界、网格感圆形邻域→ 油画效果柔和笔触边界Voronoi 单元→ 有机彩色玻璃不规则但自然随机形状→ 碎片效果Fragment四方向偏移均值4.3 与第07篇非线性平滑的关系第07篇讲了中值滤波和双边滤波——它们的目标是去噪同时保边。本篇的三种效果目标相反刻意制造不真实感让图像看起来像马赛克、玻璃或油画。两类操作都是非线性的但动机不同一类追求保真去噪一类追求风格化艺术效果。结语本篇用区域采样统计统一了三种视觉效果的数学本质✅马赛克/像素化方块均值产生硬边色块实现简单但应用广泛隐私保护✅彩色玻璃同为方块均值加边框或改用 Voronoi 单元产生镶嵌玻璃感✅油画效果圆形邻域众数统计最主导的亮度等级对应颜色模拟笔触质感✅统一框架区域形状 统计量的不同组合产生截然不同的视觉风格标签图像处理油画效果马赛克彩色玻璃区域统计众数滤波像素化风格化PythonOpenCV