c++ - 如何使用 OpenGL 使用自定义调色板重新映射数据
问题描述
假设我有 640x256 的数据矩阵,其中每个元素都是 -10 到 600 范围内的浮点数。我想在屏幕上显示这个矩阵,每个元素都从 RGB 调色板中分配一个颜色。树莓派上的 OpenGL、C++
我目前在做什么:
for (unsigned int i = 0; i < frameSize; ++i) { // frameSize = 640x256
float value = data[i];
if (value > maxVal) {
color = palette.back();
}
else if (value < minVal) {
color = palette.front();
}
else {
color = palette[((value - minVal) / (maxVal - minVal)) * (palette.size() - 1)];
}
imgData[3 * i] = color.R;
imgData[3 * i + 1] = color.G;
imgData[3 * i + 2] = color.B;
}
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, imgData);
glBegin(GL_QUADS);
{
glTexCoord2f(0, 0); glVertex2f(0, 0);
glTexCoord2f(1, 0); glVertex2f(width, 0);
glTexCoord2f(1, 1); glVertex2f(width, height);
glTexCoord2f(0, 1); glVertex2f(0, height);
}
glEnd();
调色板是用户定义的 RGB 颜色向量;minVal和maxVal是data中的最小值和最大值,但可以由用户更改。
此代码工作正常,但图像在 CPU 上着色,这对于大数据可能会很慢。是否可以直接将浮点数据作为纹理传递,并在输出上使用 OpenGL 使用调色板对其进行着色?
我不是在问如何优化 CPU 有界循环。我的问题是是否有可能在 OpenGL 渲染期间完全删除它并完成它的任务。
解决方案
您是否测量过花费了多少时间(那么慢在哪里)?
- GL上的渲染
- CPU和GPU之间的纹理传输
- 重新着色
我的赌注是重新着色......这里有一些提示我会改变:
你正在做 3x 字节访问
imgData[3 * i ] = color.R; imgData[3 * i + 1] = color.G; imgData[3 * i + 2] = color.B;
最好将像素格式对齐到 32 位(假设您的 CPU 是 32 位,具有 32 位内存访问,如果硬件支持,即使是 16 位访问也会将速度提高两倍以上),而是这样做:
imgData[i] = color;
其中颜色是 32 位
unsigned int
。你做了太多“慢”的操作
我没有为 RasberryPi 编写代码,但我怀疑你的 CPU 现在不如 x86/x64 先进,因此很可能在
+,-,*,/
和int/float
操作之间仍然存在巨大的性能差异。例如:3 * i + 2 ((value - minVal) / (maxVal - minVal)) * (palette.size() - 1)
可能会很慢,幸运的是它们可以以不同的方式完成,例如:
unsigned int frameSize3 = frameSize3*3,i; float value,dv=float(palette.size()-1)/(maxVal - minVal); for (i=0;i<frameSize3;) { value = data[i]; if (value>maxVal) color=palette.back(); // here you got temp is it typo? else if (value<minVal) color=palette.front(); // here you got temp is it typo? else color = palette[int((value-minVal)*dv)]; imgData[i]=color.R; i++; imgData[i]=color.G; i++; imgData[i]=color.B; i++; }
仍然你的主要问题是之间的转换
float
很int
慢......所以data[]
真的是浮点数还是整数?的值,范围是data[i],maxVal,minVal,palette.size()
多少?它们是浮点数还是整数?使用 LUT 进行颜色计算
如果您可以转换为整数(取决于您声称可以的值的范围,
-10...600
但调色板大小和maxVal,minVal
?)然后:color = palette[((value - minVal) / (maxVal - minVal)) * (palette.size() - 1)];
可以这样做:
color = LUT[value - minVal];
LUT[610]
从调色板中获取的每个值的颜色在哪里。您可以在应用程序启动时或对调色板进行任何更改后预先计算一次,minVal,maxVal
.LUT[i] = (i*(palette.size()-1)) / (maxVal-minVal);
如果您的输入数据来自相机,请尝试查看它是否可以返回整数数据(甚至是固定格式),这会加快很多速度......
推荐阅读
- javascript - 如何将具有平滑动画的 scrollIntoView 转换为 Promise?
- pandas - 处理 pandas 的“尝试使用 .iloc”错误
- amazon-web-services - 无法获取 ECR 泊坞窗图像
- php - 我尝试播种我的播种器文件,但出现此错误
- python - 如何选择 NaN 行并将 value_A 分配给新列?代码 df.loc['condition_1' & 'condition_2' & 'df.column_a == ''] = 'value_a'
- python - 如何修复'''Mul'对象在Python中没有属性'sp'”错误(使用Sympy和Math)
- git - 将几行作为单独的提交更改分阶段
- spring - 使用轮询器测试直接通道和源的错误处理
- c# - 如何在 xamarin.forms 中为图像添加点击和长按手势?
- swift - 如何从/到 URL、Swift、MacOS 裁剪 Jpeg 图像