2017-06-23 42 views
1

我想了解function,它讀取和轉換以16位png文件存儲的深度數據。C++中的按位數學運算

首先,他們將文件加載到類型的OpenCV的墊CV_16UC1

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++中的「< <」操作是一樣的東西有點移位,意思是對應於以下移位:「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格式的深度更加令人滿意,因此我們需要在文件讀取期間將其移回。

回答

3

有沒有共同的規範,如何存儲數據。因此可能需要從小到大或從其他方式轉換。要了解字節序看看這裏: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位),然後向右移位,然後第二個字節被添加到下端。它基本上交換兩個字節並將其轉換爲一個unsigned int。

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

經過轉換後,數據必須被解釋。確定作者在這裏要做的唯一方法是查看深度圖的文檔。第一行將3個最不重要的位移到前面,其他的向下移動。我不知道,爲什麼這樣做。我認爲在此之後1000的分割只是爲了校正單位(可能是毫米或毫米),或者它是某種固定點語義。 (整數數據類型中的有理數的重新排序)。

+1

感謝您的強有力,明智的答案。我已經聯繫了作者,但至今沒有回覆。一旦找到答案,我會發布解決方案... – mcExchange