【发布时间】:2013-07-17 08:42:40
【问题描述】:
我已经编写了下一个算法(用于 Android/NDK)来将级别应用于位图。问题是这真的很慢,在像 SGSIII 这样的快速设备上,一张 8MP 图像可能需要 4 秒。在带有 ARMv6 的设备上需要很长时间(超过 10 秒)。有什么办法可以优化吗?
void applyLevels(unsigned int *rgb, const unsigned int width, const unsigned int height, const float exposure, const float brightness, const float contrast, const float saturation)
{
float R, G, B;
unsigned int pixelIndex = 0;
float exposureFactor = powf(2.0f, exposure);
float brightnessFactor = brightness / 10.0f;
float contrastFactor = contrast > 0.0f ? contrast : 0.0f;
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
const int pixelValue = buffer[pixelIndex];
R = ((pixelValue & 0xff0000) >> 16) / 255.0f;
G = ((pixelValue & 0xff00) >> 8) / 255.0f;
B = (pixelValue & 0xff) / 255.0f;
// Clamp values
R = R > 1.0f ? 1.0f : R < 0.0f ? 0.0f : R;
G = G > 1.0f ? 1.0f : G < 0.0f ? 0.0f : G;
B = B > 1.0f ? 1.0f : B < 0.0f ? 0.0f : B;
// Exposure
R *= exposureFactor;
G *= exposureFactor;
B *= exposureFactor;
// Contrast
R = (((R - 0.5f) * contrastFactor) + 0.5f);
G = (((G - 0.5f) * contrastFactor) + 0.5f);
B = (((B - 0.5f) * contrastFactor) + 0.5f);
// Saturation
float gray = (R * 0.3f) + (G * 0.59f) + (B * 0.11f);
R = gray * (1.0f - saturation) + R * saturation;
G = gray * (1.0f - saturation) + G * saturation;
B = gray * (1.0f - saturation) + B * saturation;
// Brightness
R += brightnessFactor;
G += brightnessFactor;
B += brightnessFactor;
// Clamp values
R = R > 1.0f ? 1.0f : R < 0.0f ? 0.0f : R;
G = G > 1.0f ? 1.0f : G < 0.0f ? 0.0f : G;
B = B > 1.0f ? 1.0f : B < 0.0f ? 0.0f : B;
// Store new pixel value
R *= 255.0f;
G *= 255.0f;
B *= 255.0f;
buffer[pixelIndex] = ((int)R << 16) | ((int)G << 8) | (int)B;
pixelIndex++;
}
}
}
【问题讨论】:
-
您应该去掉每个 R/G/B 值的
/ 255.0和* 255.0并使用 255.0 而不是 1.0 作为最大值。这将消除昂贵的部门操作。您可能还想考虑使用 NEON,因为这显然是 SIMD 的候选者。 -
这个问题似乎是题外话,因为它是关于代码审查的。你可以发帖codereview.stackexchange.com
-
尝试不使用浮点数,看看普通整数数学是否足够精确。毕竟,无论如何,你都是以 8 位整数开始和结束的。
-
当然,开头的
clamp values完全没用,因为该值被屏蔽为 255 并除以 255.0 - 不可能为负数或大于 1。当然,使用定点数学会是更好的选择。第二个“钳位值”似乎在错误的位置(当然,这是必需的,因为乘法/加法可能会将其推到范围之外)
标签: c++ c optimization image-processing bitmap