将8位颜色扩展为24位颜色



设置

我有几百个Sparkfun LED像素(类似于https://www.sparkfun.com/products/11020)连接到Arduino Uno,并希望使用Arduino的内置串行USB连接从PC控制像素。

像素是可单独寻址的,每个像素具有24位的颜色(RGB)。由于我希望能够非常快速地改变每个像素的颜色,因此从pc到Arduino的数据传输必须非常高效(从Arduino到像素的进一步数据传输已经非常快了)。

问题

我试过简单地将所需的RGB值直接发送到Arduino,但这会导致明显的延迟,例如,当我想同时打开所有LED时。我最简单的想法是将可用的颜色从24位减少到8位,这对我的应用程序来说已经足够了。

如果我这样做,我必须将PC上的8位值扩展到Arduino上的24位值,以设置像素上的实际颜色。这里显而易见的解决方案是一个调色板,它包含所有可用的8位值和相应的24位颜色。不过,我希望有一个没有调色板的解决方案,主要是出于内存空间的原因。

问题

什么是将8位颜色扩展为24位颜色的有效方法,最好是准确保留颜色信息的方法?这个任务有标准的算法吗?

可能的解决方案

我正在考虑一种格式,每个R和B有2个比特,G有3个比特。这些值将被打包到一个字节中,然后传输到Arduino,然后使用比特移位进行解包,并使用map()函数进行插值(http://arduino.cc/en/Reference/Map)。

对这个解决方案有什么想法吗?有什么更好的方法可以做到这一点?

R2B2G3会给你提供很少的颜色(实际上还有一位)。我不知道这对你的申请是否足够。您可以使用抖动技术使8位图像看起来更好。

或者,如果你有任何喜欢的颜色集,你可以将已知的调色板存储在你的设备上,永远不要通过有线发送。您还可以为不同的情况存储多个选项板,并指定要与小整数索引一起使用的选项板。

最重要的是,可以实现一些简单的压缩算法,如RLE或LZW,并在接收后解压缩。

还有一些占地面积很小的非常快速的压缩库可以使用:Snappy、miniLZO。

关于您的问题"什么是更好的方法?",首先要做的事情之一(如果尚未完成)是提高串行数据速率。Arduino论坛建议使用115200 bps作为标准速率,并尝试使用230400 bps。在这种速度下,您需要编写接收软件,以便它将数据从相对较小的接收缓冲区快速传输到较大的缓冲区,而不是试图处理小接收缓冲区中的数据。

第二种可能性是将激活时间放入数据包中。假设F1、F2、F3…是将在LED阵列上显示的一系列帧。提前或在空闲或等待时间从PC发送这些帧,并让Arduino缓冲它们,直到它们按计划出现。当指定帧的激活时间到来时,让Arduino打开它。如果你提前知道帧,但不知道激活时间,请发送和缓冲帧,并在适当的时间只发送激活码。

第三,可以有多个选项板和动态选项板,它们可以动态更改,也可以使用像素地址或像素列表以及像素映射。也就是说,您可能在不同的时间使用不同的协议。协议3可以下载整个调色板,4可以改变调色板的元素,5可以发送24比特值v、时间t、计数n和在时间t要设置为v的n个像素的列表,6可以发送像素设置的位图,等等。位图可以是指示开或关的简单的每像素1位位图,也可以是每像素k位位图,其中k位条目可以指定像素的调色板编号或帧编号。这一切都有点模糊,因为可能性太多了;但简而言之,定义能很好地与所显示的内容配合使用的协议。

第四,考虑到ATmega328P的RAM较小(2KB),但闪存较大(32KB),请考虑将几个调色板、帧和宏硬编码到程序中。我所说的宏是指生成圆弧、直线、开放或填充矩形等图形元素的例程。任何预先已知的显示元件都是闪存而不是RAM存储器的候选者。

您的(2,3,2)位想法是"在野外"使用的。尝试起来应该非常简单。质量会很低,但试一下,看看它是否符合你的需求。

如果查找表随时间保持不变,那么与256色查找表相比,任何其他解决方案似乎都不太可能节省大量内存。我认为任何成功的事情都必须利用你发送到像素的图像中的模式。

不管怎么看,你真正想要的是图像压缩。因此,我建议查看PNG和JPG压缩之类的文件,看看它们是否足够快,适合您的应用程序。

如果没有,那么你可以考虑自己滚动。每像素压缩只能做到这一点;就尺寸而言,你的(2,3,2)想法与你所期望的一样好。你可以尝试四叉树类型的格式:取4像素块的平均值,传输差异的压缩(有损)表示,然后对平均值的半分辨率图像应用相同的操作。。。

正如其他人所指出的,抖动会让你的图像在(2,3,2)上看起来更好。对于您的应用程序来说,抖动最简单的方法可能是为每个像素的每种颜色选择不同的(随机或准随机)固定量化阈值偏移。PC和Arduino都将具有该阈值表的副本;阈值的分布将防止后验化,并且Arduino侧表将有助于保持准确性。

最新更新