繁体   English   中英

C ++中的按位数学运算

[英]Bitwise math operations in C++

我正在尝试理解一个读取和转换存储为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 shortfloat的转换是将数字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

所以看起来很奇怪...

EDIT2:
作者的回复:
“深度图的保存方式是将其移动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]));

这句话是一种忍耐的转变。 第一个字节强制转换为无符号短整数(从8到16位),然后向右移位,然后将第二个字节添加到低端。 它基本上交换两个字节并将其转换为无符号的int。

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

极性转换后,必须对数据进行解释。 确保作者打算在此处执行的操作的唯一方法是查看深度图的文档。 第一行将3个最低有效位移到最前面,其余三个位向下移。 我不知道为什么要这么做。 我认为之后除以1000只是为了校正单位(可能是m单位为mm或km单位为km),或者是某种定点语义。 (表示整数数据类型中的有理数)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM