gpt4 book ai didi

c++ - C++ 中的按位数学运算

转载 作者:搜寻专家 更新时间:2023-10-31 01:31:51 25 4
gpt4 key购买 nike

我正在尝试理解 function读取和转换存储为 16 位 png 文件的深度数据。

首先,他们将文件加载到 CV_16UC1 类型的 opencv Mat 中

cv::Mat depth_image = cv::imread(filename.c_str(), CV_LOAD_IMAGE_ANYDEPTH);

然后他们分配

unsigned short * depth_raw = new unsigned short[frame_height * frame_width];
for (int i = 0; i < frame_height * frame_width; ++i) {
depth_raw[i] = ((((unsigned short)depth_image.data[i * 2 + 1]) << 8) + ((unsigned short)depth_image.data[i * 2 + 0]));
depth_raw[i] = (depth_raw[i] << 13 | depth_raw[i] >> 3);
depth_data[i] = float((float)depth_raw[i] / 1000.0f);
}

现在我知道 C++ 中的“<<”运算符类似于位移位,意思是 5 << 1对应于以下位移:“00000101”(二进制为 5)->“00001010”(二进制为 10)。所以显然可以使用“<< n”或“>> n”对 2^n 进行乘法和除法运算。

我仍然觉得很难理解上面的转换。这是上述转换的带有数字的示例(将 cout 应用于每个步骤):

depth_image.data[i] = 192
depth_image.data[2*i+1] = 47
depth_image.data[2*i+0] = 192
(((unsigned short)depth_image.data[i * 2 + 1]) << 8) = 12032
((unsigned short)depth_image.data[i * 2 + 0]) = 192
depth_raw[i] = 12224
depth_raw[i] << 13 = 0
depth_raw[i] >> 3 = 191
depth_raw[i] << 13 | depth_raw[i] >> 3 = 191
depth_data[i] = 1.528

真正奇怪的是最后一行:似乎是从unsigned short转换过来的至 float正在将数字 191 转换为 1528 ???

任何帮助或提示将不胜感激。

编辑:
我找到了一些 Matlab 代码,展示了作者之前如何保存深度图像:

% resave depth map with bit shifting
depthRaw = double(imread(filename))/1000;
saveDepth (depthRaw,newFilename);

function saveDepth (depth,filename)
depth(isnan(depth)) =0;
depth =single(depth)*1000;
depthVis = uint16(depth);
depthVis = bitor(bitshift(depthVis,3), bitshift(depthVis,3-16));
imwrite(depthVis,filename);
end

所以它看起来像一个奇怪的储蓄......

编辑2:
作者回复:
“深度图以移动 3 位的方式保存,使 PNG 格式的深度更适合人眼。因此我们需要在文件读取时将其移回”。

最佳答案

没有共同的规范,数据是如何存储的。因此,可能需要从小端转换为大端或相反。要了解字节顺序,请看这里:https://en.wikipedia.org/wiki/Endianness

depth_raw[i] = ((((unsigned short)depth_image.data[i * 2 + 1]) << 8) + ((unsigned short)depth_image.data[i * 2 + 0]));

这个语句是字节序的转换。第一个字节转换为 unsigned short(从 8 位到 16 位),然后右移,然后在低端添加第二个字节。它基本上交换两个字节并将其转换为无符号整数。

depth_raw[i] = (depth_raw[i] << 13 | depth_raw[i] >> 3);
depth_data[i] = float((float)depth_raw[i] / 1000.0f);

字节序转换后,数据必须被解释。确定作者在这里打算做什么的唯一方法是查看深度图的文档。第一行将 3 个最低有效位移到前面,将其他位移到后面。我不知道,为什么这样做。我认为之后除以 1000 只是为了校正单位(可能是毫米单位的米或米单位的公里),或者它是某种固定点语义。 (整数数据类型中有理数的表示)。

关于c++ - C++ 中的按位数学运算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44717510/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com