-2

我对 Nvidia 提供的名为 DCT8x8 的示例有疑问,该示例应用于图像以并行执行算法。更多信息:http: //developer.download.nvidia.com/compute/DevZone/C/html/C/src/dct8x8/doc/dct8x8.pdf

该代码执行正向 DCT,并在 BMP 图像上反向执行。

我的第一个问题是,有没有办法计算获得 JPG 的唯一正向变换?

其次,代码中有几个部分我不明白我希望熟悉DTC和CUDA的人可以帮助我。

首先:在文件 dtc8x8_gold.cpp 中,程序使用以下矩阵:

const float DCTv8matrix[BLOCK_SIZE2] =
{
0.3535533905932738f, 0.4903926402016152f, 0.4619397662556434f, 0.4157348061512726f, 0.3535533905932738f, 0.2777851165098011f, 0.1913417161825449f, 0.0975451610080642f,
0.3535533905932738f, 0.4157348061512726f, 0.1913417161825449f, -0.0975451610080641f, -0.3535533905932737f, -0.4903926402016152f, -0.4619397662556434f, -0.2777851165098011f,
0.3535533905932738f, 0.2777851165098011f, -0.1913417161825449f, -0.4903926402016152f, -0.3535533905932738f, 0.0975451610080642f, 0.4619397662556433f, 0.4157348061512727f,
0.3535533905932738f, 0.0975451610080642f, -0.4619397662556434f, -0.2777851165098011f, 0.3535533905932737f, 0.4157348061512727f, -0.1913417161825450f, -0.4903926402016153f,
0.3535533905932738f, -0.0975451610080641f, -0.4619397662556434f, 0.2777851165098009f, 0.3535533905932738f, -0.4157348061512726f, -0.1913417161825453f, 0.4903926402016152f,
0.3535533905932738f, -0.2777851165098010f, -0.1913417161825452f, 0.4903926402016153f, -0.3535533905932733f, -0.0975451610080649f, 0.4619397662556437f, -0.4157348061512720f,
0.3535533905932738f, -0.4157348061512727f, 0.1913417161825450f, 0.0975451610080640f, -0.3535533905932736f, 0.4903926402016152f, -0.4619397662556435f, 0.2777851165098022f,
0.3535533905932738f, -0.4903926402016152f, 0.4619397662556433f, -0.4157348061512721f, 0.3535533905932733f, -0.2777851165098008f, 0.1913417161825431f, -0.0975451610080625f
};

const float DCTv8matrixT[BLOCK_SIZE2] =
{
0.3535533905932738f, 0.3535533905932738f, 0.3535533905932738f, 0.3535533905932738f, 0.3535533905932738f, 0.3535533905932738f, 0.3535533905932738f, 0.3535533905932738f,
0.4903926402016152f, 0.4157348061512726f, 0.2777851165098011f, 0.0975451610080642f, -0.0975451610080641f, -0.2777851165098010f, -0.4157348061512727f, -0.4903926402016152f,
0.4619397662556434f, 0.1913417161825449f, -0.1913417161825449f, -0.4619397662556434f, -0.4619397662556434f, -0.1913417161825452f, 0.1913417161825450f, 0.4619397662556433f,
0.4157348061512726f, -0.0975451610080641f, -0.4903926402016152f, -0.2777851165098011f, 0.2777851165098009f, 0.4903926402016153f, 0.0975451610080640f, -0.4157348061512721f,
0.3535533905932738f, -0.3535533905932737f, -0.3535533905932738f, 0.3535533905932737f, 0.3535533905932738f, -0.3535533905932733f, -0.3535533905932736f, 0.3535533905932733f,
0.2777851165098011f, -0.4903926402016152f, 0.0975451610080642f, 0.4157348061512727f, -0.4157348061512726f, -0.0975451610080649f, 0.4903926402016152f, -0.2777851165098008f,
0.1913417161825449f, -0.4619397662556434f, 0.4619397662556433f, -0.1913417161825450f, -0.1913417161825453f, 0.4619397662556437f, -0.4619397662556435f, 0.1913417161825431f,
0.0975451610080642f, -0.2777851165098011f, 0.4157348061512727f, -0.4903926402016153f, 0.4903926402016152f, -0.4157348061512720f, 0.2777851165098022f, -0.0975451610080625f
};

float Q[BLOCK_SIZE2] =
{
32.f, 33.f, 51.f, 81.f, 66.f, 39.f, 34.f, 17.f,
33.f, 36.f, 48.f, 47.f, 28.f, 23.f, 12.f, 12.f,
51.f, 48.f, 47.f, 28.f, 23.f, 12.f, 12.f, 12.f,
81.f, 47.f, 28.f, 23.f, 12.f, 12.f, 12.f, 12.f,
66.f, 28.f, 23.f, 12.f, 12.f, 12.f, 12.f, 12.f,
39.f, 23.f, 12.f, 12.f, 12.f, 12.f, 12.f, 12.f,
34.f, 12.f, 12.f, 12.f, 12.f, 12.f, 12.f, 12.f,
17.f, 12.f, 12.f, 12.f, 12.f, 12.f, 12.f, 12.f
};

float C_a = 1.387039845322148f; //!< a = (2^0.5) * cos( pi / 16); Used in forward and inverse DCT.
float C_b = 1.306562964876377f; //!< b = (2^0.5) * cos( pi / 8); Used in forward and inverse DCT.
float C_c = 1.175875602419359f; //!< c = (2^0.5) * cos(3 * pi / 16); Used in forward and inverse DCT.
float C_d = 0.785694958387102f; //!< d = (2^0.5) * cos(5 * pi / 16); Used in forward and inverse DCT.
float C_e = 0.541196100146197f; //!< e = (2^0.5) * cos(3 * pi / 8); Used in forward and inverse DCT.
float C_f = 0.275899379282943f; //!< f = (2^0.5) * cos(7 * pi / 16); Used in forward and inverse DCT.

有人可以解释一下为什么要使用这些值以及使用它们的原因吗?

在文件 dct8x8_kernel_quantization.cu 中还有另一个 Q 矩阵,我的猜测是表示量化的阈值,如果是,为什么是这些值?

__constant__ short Q[] =
{
32, 33, 51, 81, 66, 39, 34, 17,
33, 36, 48, 47, 28, 23, 12, 12,
51, 48, 47, 28, 23, 12, 12, 12,
81, 47, 28, 23, 12, 12, 12, 12,
66, 28, 23, 12, 12, 12, 12, 12,
39, 23, 12, 12, 12, 12, 12, 12,
34, 12, 12, 12, 12, 12, 12, 12,
17, 12, 12, 12, 12, 12, 12, 12
};

我的最后一个问题是,我觉得这些值是为“barbara.bmp”图像指定的,如果为真,不会让我使用与默认图像不同的图像,这就是我想要做的,除了理解代码。

非常感谢您的帮助!

扫罗

4

1 回答 1

1

离散余弦变换根据输入数据元素在数据集中的位置将输入数据元素乘以余弦项。这些余弦项可以针对不同的n 值预先计算,即针对数据集中的不同位置。

第一个矩阵 ( DCTv8matrix) 表示一组这些余弦项计算。请注意,所有值都介于 -1 和 1 之间,即余弦函数的范围。

第二个矩阵 ( DCTv8matrixT) 只是第一个矩阵的转置。

第三个和第四个矩阵 (float Q[BLOCK_SIZE2]__constant__ short Q[]) 是量化因子的浮点和整数表示。为了实现压缩,JPEG编码中使用的一种方法是“丢弃”由DCT产生的最终变换数据中的某些“频率分量”。这些矩阵用于帮助量化 2D 变换数据中的某些“频率分量”。较低的“频率成分”表示朝向左上角,较高的“频率成分”表示朝向右下角。量化因子的具体选择由 JPEG 算法的设计者(或实施者)决定,以实现压缩同时仍保留逼真的图像。

在这种情况下,最大的量化出现在最高的“频率”。

通常选择的量化因子对于特定图像不是唯一的。您应该能够在其他图像上使用这些因素并获得合理的结果。

尽管此示例完成了与JPEG编码(和解码)相关的大部分工作,但我认为以 JPEG 格式存储中间结果并非易事。仍然有必要创建一个例程,将适当的 JPEG 标头(例如 JFIF 标头)写入文件,然后以适当的顺序写入适当的量化数据。

于 2013-11-24T01:03:40.143 回答