测试用例背景
让我们考虑一种简单的颜色减少方法。通过使用无符号字符 C 和 C++ 类型进行矩阵项存储,像素通道最多可以有 256 个不同的值。对于三通道图像,这可能会导致形成太多的颜色(准确地说是 1600 万)。使用如此多的色调可能会对我们的算法性能造成沉重打击。但是,有时只需使用更少的人即可获得相同的最终结果。
在这种情况下,我们通常会减少色彩空间。这意味着我们将颜色空间当前值除以新的输入值,最终得到更少的颜色。例如,0 到 9 之间的每个值都采用新值 0,10 到 19 之间的每个值都采用值 10,依此类推。
当您将 uchar(无符号 char - 又名介于 0 和 255 之间的值)值与 int 值相除时,结果也将是 char。这些值只能是 char 值。因此,任何分数都将向下舍入。利用这一事实,uchar 域中的上层操作可以表示为:

一个简单的色彩空间缩减算法将包括仅通过图像矩阵的每个像素并应用此公式。值得注意的是,我们进行了除法和乘法运算。对于系统来说,这些操作的成本非常高。如果可能的话,值得通过使用更便宜的操作来避免它们,例如一些减法、加法或在最好的情况下进行简单的赋值。此外,请注意,我们只有有限数量的上层操作的输入值。在 uchar 系统的情况下,确切地说是 256。
因此,对于较大的图像,明智的做法是事先计算所有可能的值,并且在分配过程中,只需使用查找表进行分配即可。查找表是简单的数组(具有一个或多个维度),对于给定的输入值变体,它保存最终输出值。它的优势在于我们不需要进行计算,我们只需要读取结果。
我们的测试用例程序(以及下面的代码示例)将执行以下操作:读取作为命令行参数传递的图像(它可以是彩色或灰度),并使用给定的命令行参数整数值应用缩减。在 OpenCV 中,目前有三种主要方法可以逐像素地浏览图像。为了让事情变得更有趣,我们将使用这些方法中的每一种对图像进行扫描,并打印出花费了多长时间。
您可以下载完整的源代码,也可以在 OpenCV 的 samples 目录中查找核心部分的 cpp 教程代码。它的基本用法是:
how_to_scan_images imageName.jpg intValueToReduce [G]
最后一个参数是可选的。如果给定图像将以灰度格式加载,否则使用 BGR 色彩空间。
计算查找表
第一件事是计算查找表。
// 将输入字符串转换为数字 - C++ 样式
std::stringstream s;
s << argv[2];
int divideWith = 0;
s >> divideWith;
if (!s || !divideWith) {
std::cout << "输入的用于除法的无效数字。" << std::endl;
return -1;
}
uchar table[256];
for (int i = 0; i < 256; ++i)
table[i] = static_cast<uchar>((i / divideWith) * divideWith);
在这里,我们首先使用 C++ stringstream 类将第三个命令行参数从文本转换为整数格式。然后我们使用简单的外观和上面的公式来计算查找表。这里没有特定于 OpenCV 的东西。



