误差扩散抖动算法和阈值抖动算法的原理

描述

在嵌入式GUI开发中,低色深(如RGB565)常常导致图片渐变出现明显色带。

今天给大家带来一个好消息!

GUI Guider现已支持LVGL图片抖动处理,内置两种主流算法:Floyd-Steinberg误差扩散抖动和阈值抖动。

本文将结合源码实现,带你深入理解这两种算法的原理、特点与工程应用,让你的界面更细腻、更专业!

什么是图片抖动(Dithering)

想象一下,你有一盒256色的彩笔,但现在只能用16色来画同一幅画。直接的做法是找到最接近的颜色替代,但这样会产生明显的色彩分层和失真。

抖动算法就像一个聪明的艺术家,通过巧妙地安排像素的分布,让人眼在一定距离下看到接近原始色彩的效果。这就是"空间换色彩"的思想。

误差扩散抖动算法

原理简介:

Floyd-Steinberg算法是一种经典的误差扩散抖动方法。其核心思想是:当前像素的量化误差不应浪费,而应传递给邻近像素,从而整体提升视觉效果。

实现算法流程:

算法

1. 将每个像素的RGB值映射到21个等级(step约为12.75),以适应低色深显示。

2. 计算原始像素与量化后像素的误差。

3. 按照Floyd-Steinberg权重,将误差分配给右侧、正下、左下和右下的像素。

源码实例片段:

 

const quantize = (value) => {
 const step = 255 / (21 - 1);
 return Math.round(value / step) * step;
};
// 
误差扩散到邻近像素
diffuseError(1, 0, 7/16); //
右侧
diffuseError(-1, 1, 3/16); // 
左下
diffuseError(0, 1, 5/16); //
正下
diffuseError(1, 1, 1/16); //
右下
算法特点:

 

算法

阈值抖动算法

原理简介:

阈值抖动采用预定义的阈值矩阵,根据像素在矩阵中的位置决定其量化方式。每个像素独立处理,天然支持并行计算。

算法

实现流程:

阈值矩阵设计:     

使用8×8的阈值矩阵,分别针对RGB三个通道设计不同的阈值分布:

 

let red_thresh = [
1, 7, 3, 5, 0, 8, 2, 6,
7, 1, 5, 3, 8, 0, 6, 2,
// ... 64
个值的
8x8
矩阵
]

 

这种分离式设计有特殊考虑:

算法

2. 基于像素位置计算阈值矩阵索引:

let threshold_id = ((y & 7) << 3) + (x & 7);

3. RGB565 格式适配:针对RGB565格式,分别对红、绿、蓝通道做位掩码处理,保证色彩映射准确。

算法特点:

算法

算法对比与选择建议:

算法

若在 GUI Guider 中遇到图片显示出现色带问题,建议在图片属性设置中尝试更换不同的图像渲染算法,以改善图像质量:

算法

实际应用建议:

渐变和照片类图片优先选择Floyd-Steinberg算法,追求最佳视觉体验

UI图标、纯色块、实时渲染场景优先选择阈值抖动算法,追求极致效率

总结

两种抖动算法各有优势:

Floyd-Steinberg-适合追求高质量的场景,特别是照片和复杂图像

阈值抖动-适合对性能要求较高的实时应用和UI图标

在使用GUI Guider的嵌入式GUI开发中,根据具体的硬件平台和应用需求选择合适的算法,可以在性能和视觉效果之间找到最佳平衡点。理解这些算法的原理,不仅能帮助我们更好地使用现有工具,还能在需要时进行定制优化,打造更出色的用户界面体验。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分