如何将16位无符号整数转换为更大的8位无符号整数?

时间:2015-08-19 20:35:42

标签: c++

我有一个需要返回一个16位无符号int向量的函数,但对于另一个我也称之为的函数,我需要8位无符号int向量格式的输出。例如,如果我开始时:

std::vector<uint16_t> myVec(640*480);

我如何将其转换为以下格式:

std::vector<uint8_t> myVec2(640*480*4);

更新(更多信息): 我正在使用libfreenect及其getDepth()方法。我修改它以输出一个16位无符号整数向量,以便我可以以毫米为单位检索深度数据。但是,我还想显示深度数据。我正在使用freenect安装中的一些示例代码c ++,它使用过剩并需要一个8位无符号int向量来显示深度,但是,我需要16位来检索以毫米为单位的深度并将其记录到文本文件中。因此,我希望在glut的绘制函数中将数据检索为16位无符号整数向量,然后对其进行转换,以便我可以使用已经编写的过剩函数来显示它。

3 个答案:

答案 0 :(得分:3)

  

我如何将其转换为以下格式:

     

std :: vector myVec2;这样myVec2.size()将是两倍   大到myVec.size()?

myVec2.reserve(myVec.size() * 2);
for (auto it = begin(myVec); it!=end(myVec); ++it)
{
    uint8_t val = static_cast<uint8_t>(*it); // isolate the low 8 bits
    myVec2.push_back(val);
    val = static_cast<uint8_t>((*it) >> 8); // isolate the upper 8 bits
    myVec2.push_back(val);
}

或者您可以更改push_back()的顺序,如果哪个字节首先(上部或下部)很重要。

答案 1 :(得分:3)

根据您的更新,假设8位无符号整数将显示为灰度图像,您需要的是类似于亮度传递函数。基本上,您的输出函数正在寻找将数据映射到值0-255,但您不一定希望这些数据直接对应毫米。如果你的所有数据都是0-3mm怎么办?然后你的图像看起来几乎完全是黑色的。怎么样都是300-400mm?然后它会完全变白,因为它被剪裁为255。

要做到这一点的基本方法是找到最小值和最大值,并执行此操作:

double scale = 255.0 / (double)(maxVal - minVal);
for( int i = 0; i < std::min(myVec.size(), myVec2.size()); ++i )
{
    myVec2.at(i) = (unsigned int)((double)(myVec.at(i)-minVal) * scale);
}

根据您的数据分布情况,您可能需要做一些更复杂的事情才能充分利用您的动态范围。

编辑:这假设您的过剩功能正在创建图像,如果它使用8位值作为图形的输入,那么您可以忽略。

Edit2:您的其他更新后的更新。如果你想填充640x480x4矢量,你显然是在做一个图像。你需要做我上面概述的,但它所寻找的4个维度是红色,绿色,蓝色和Alpha。 Alpha通道必须始终为255(这控制它是多么透明,你不希望它是透明的),对于其他3 ...你从上面的函数获得的值(缩放值)如果将所有3个通道(通道为红色,绿色和蓝色)设置为相同的值,它将显示为灰度。例如,如果我的数据范围为0-25mm,对于值为10mm的像素,我会将数据设置为255 /(25-0)* 10 = 102,因此像素将是(102,102,102, 255)

编辑3:添加有关亮度传递函数的维基百科链接 - https://en.wikipedia.org/wiki/Color_mapping

答案 2 :(得分:-1)

直截了当的方式:

std::vector<std::uint8_t> myVec2(myVec.size() * 2);
std::memcpy(myVec2.data(), myVec.data(), myVec.size());

或使用标准库

std::copy( begin(myVec), end(myVec), begin(myVec2));