我尝试在lena的图像上运行整数到整数的提升5/3。我一直在关注Walker,Nguyen和Chen的论文"A low-power Low-memory system for wavelet-based image compression“(2015年10月7日Link活跃)。
不过,我遇到了一些问题。图像看起来就是不太对劲。我似乎在绿色和蓝色通道中略有溢出,这意味着后续的小波函数遍数会发现不应该存在的高频。我也很确定我还弄错了什么,因为我在高频部分的边缘看到了一条s0图像的线。
我的函数如下:
bool PerformHorizontal( Col24* pPixelsIn, Col24* pPixelsOut, int width, int pixelPitch, int height )
{
const int widthDiv2 = width / 2;
int y = 0;
while( y < height )
{
int x = 0;
while( x < width )
{
const int n = (x) + (y * pixelPitch);
const int n2 = (x / 2) + (y * pixelPitch);
const int s = n2;
const int d = n2 + widthDiv2;
// Non-lifting 5 / 3
/*pPixelsOut[n2 + widthDiv2].r = pPixelsIn[n + 2].r - ((pPixelsIn[n + 1].r + pPixelsIn[n + 3].r) / 2) + 128;
pPixelsOut[n2].r = ((4 * pPixelsIn[n + 2].r) + (2 * pPixelsIn[n + 2].r) + (2 * (pPixelsIn[n + 1].r + pPixelsIn[n + 3].r)) - (pPixelsIn[n + 0].r + pPixelsIn[n + 4].r)) / 8;
pPixelsOut[n2 + widthDiv2].g = pPixelsIn[n + 2].g - ((pPixelsIn[n + 1].g + pPixelsIn[n + 3].g) / 2) + 128;
pPixelsOut[n2].g = ((4 * pPixelsIn[n + 2].g) + (2 * pPixelsIn[n + 2].g) + (2 * (pPixelsIn[n + 1].g + pPixelsIn[n + 3].g)) - (pPixelsIn[n + 0].g + pPixelsIn[n + 4].g)) / 8;
pPixelsOut[n2 + widthDiv2].b = pPixelsIn[n + 2].b - ((pPixelsIn[n + 1].b + pPixelsIn[n + 3].b) / 2) + 128;
pPixelsOut[n2].b = ((4 * pPixelsIn[n + 2].b) + (2 * pPixelsIn[n + 2].b) + (2 * (pPixelsIn[n + 1].b + pPixelsIn[n + 3].b)) - (pPixelsIn[n + 0].b + pPixelsIn[n + 4].b)) / 8;*/
pPixelsOut[d].r = pPixelsIn[n + 1].r - (((pPixelsIn[n].r + pPixelsIn[n + 2].r) >> 1) + 127);
pPixelsOut[s].r = pPixelsIn[n].r + (((pPixelsOut[d - 1].r + pPixelsOut[d].r) >> 2) - 64);
pPixelsOut[d].g = pPixelsIn[n + 1].g - (((pPixelsIn[n].g + pPixelsIn[n + 2].g) >> 1) + 127);
pPixelsOut[s].g = pPixelsIn[n].g + (((pPixelsOut[d - 1].g + pPixelsOut[d].g) >> 2) - 64);
pPixelsOut[d].b = pPixelsIn[n + 1].b - (((pPixelsIn[n].b + pPixelsIn[n + 2].b) >> 1) + 127);
pPixelsOut[s].b = pPixelsIn[n].b + (((pPixelsOut[d - 1].b + pPixelsOut[d].b) >> 2) - 64);
x += 2;
}
y++;
}
return true;
}肯定有什么地方不对劲,但我就是搞不清楚。有比我稍微聪明一点的人能指出我哪里错了吗?值得注意的是,你可以在工作代码上面看到Daub5/3的未提升版本,这也给了我相同的工件……我很困惑,因为我以前有过一次这样的工作(那是两年多以前的事了,我不再有那个代码了)。
如有任何帮助,我们将不胜感激:)
编辑:通过将低通像素限制在0到255的范围内,我似乎已经消除了溢出问题。不过,我有点担心这不是正确的解决方案。有人能对此发表评论吗?
发布于 2010-01-16 18:17:14
好的,我可以无损地向前,然后反转,只要我在短时间内存储我的post前向变换数据。显然,这比我希望的占用了更多的空间,但这确实为我研究各种压缩算法提供了一个很好的起点。您还可以使用SSE2指令一次压缩24个分量像素。这是我想出来的标准的C正向变换:
const int16_t dr = (int16_t)pPixelsIn[n + 1].r - ((((int16_t)pPixelsIn[n].r + (int16_t)pPixelsIn[n + 2].r) >> 1));
const int16_t sr = (int16_t)pPixelsIn[n].r + ((((int16_t)pPixelsOut[d - 1].r + dr) >> 2));
const int16_t dg = (int16_t)pPixelsIn[n + 1].g - ((((int16_t)pPixelsIn[n].g + (int16_t)pPixelsIn[n + 2].g) >> 1));
const int16_t sg = (int16_t)pPixelsIn[n].g + ((((int16_t)pPixelsOut[d - 1].g + dg) >> 2));
const int16_t db = (int16_t)pPixelsIn[n + 1].b - ((((int16_t)pPixelsIn[n].b + (int16_t)pPixelsIn[n + 2].b) >> 1));
const int16_t sb = (int16_t)pPixelsIn[n].b + ((((int16_t)pPixelsOut[d - 1].b + db) >> 2));
pPixelsOut[d].r = dr;
pPixelsOut[s].r = sr;
pPixelsOut[d].g = dg;
pPixelsOut[s].g = sg;
pPixelsOut[d].b = db;
pPixelsOut[s].b = sb;创建它的倒数是很简单的(一个非常简单的代数)。值得一提的是,顺便说一句,您需要从右到左、从下到上反转图像。接下来,我将看看是否可以将这些数据分流到uint8_ts中,并损失一点或两个精度。对于压缩来说,这真的不是问题。
发布于 2010-01-15 00:09:02
您可以使用极值进行一些测试,以查看溢出的可能性。示例:
pPixelsOut[d].r = pPixelsIn[n + 1].r - (((pPixelsIn[n].r + pPixelsIn[n + 2].r) >> 1) + 127);
If:
pPixelsIn[n ].r == 255
pPixelsIn[n+1].r == 0
pPixelsIn[n+2].r == 255
Then:
pPixelsOut[d].r == -382
But if:
pPixelsIn[n ].r == 0
pPixelsIn[n+1].r == 255
pPixelsIn[n+2].r == 0
Then:
pPixelsOut[d].r == 128您有511个可能值的范围(-382 ..128),因此,为了避免溢出或钳位,您需要一个额外的比特、一些量化或另一种编码类型!
发布于 2010-01-14 06:39:50
我猜数据已经被阈值处理了吧?
我也不明白为什么你要加回+127和-64。
https://stackoverflow.com/questions/2045541
复制相似问题