PFM 圖片格式
參考: https://linux.die.net/man/5/pfm
1. 描述
本文檔描述了Netpbm轉換器pamtopfm(1)和pfmtopam(1)所理解的PFM圖形圖像文件格式。
世界上有多種稱為PFM的相似格式,它們都沒有權威的記錄。這里描述的格式是布賴恩亨德森從一個他發現處理'PFM'格式的程序中推斷出來的格式。
PFM格式受Netpbm格式的啟發,您會看到很多相似之處。不過,它不是官方的Netpbm格式。其目標與Netpbm格式不一致。
2. 格式
PFM圖像是一個字節流。該流包含一個標題,緊接着是一個光柵。下面介紹這兩個組件。所描述的部分之前或之后沒有分隔符。
(1) PFM標題 PFM header
PFM標題是ASCII文本的連續3行'行'。每行之后是一個空格字符。該字符通常是換行符,因此是“行”,但不一定是。
pamtopfm在它生成的PFM中使用換行符。
(2) Identifier Line
標識符行包含字符'PF'或'Pf'。 PF意味着它是一種彩色PFM。 Pf表示這是一個灰度PFM。
(3) 尺寸線 Dimensions Line
尺寸線包含兩個正整數,用空格分隔。首先是圖像的寬度;第二個是圖像的高度。兩者都以像素為單位。
(4) 比例因子/字節順序 Scale Factor / Endianness
比例因子/字節順序線是一個奇怪的線,它將字節順序信息壓縮成一個合理的尺度描述。該行由非零十進制數組成,不一定是整數。如果數字是負數,那意味着PFM柵格是小端。否則,它是大端。數字的絕對值是圖像的比例因子。
比例因子告訴柵格中樣本的單位。你用某種方式將它與一些單獨理解的單位信息一起用來將樣本值轉化為有意義的值,例如每平方米的瓦數。
(5) PFM光柵 PFM raster
柵格是一系列像素,一個接一個地打包,沒有任何類型的分隔符。它們采用標准的西方閱讀順序:從圖像中的左到右和從上到下。
每個像素由1或3個樣本組成,一個接一個地打包,沒有任何類型的分隔符。 1個樣本用於灰度PFM,3個用於彩色PFM(請參閱PFM標頭的標識行)。
每個樣本由4個連續的字節組成。這些字節表示一個32位字符串,采用大端或小端格式,由PFM標頭的比例因子/字節順序線確定。該字符串是IEEE 32位浮點數字代碼。由於這與大多數CPU和編譯器使用的格式相同,因此在處理字節序變化后,通常可以讓程序直接將字節用作浮點數。
PFM 圖片寫入
參考: https://github.com/Microsoft/AirSim common_utils/Utils.hpp
static void writePfmFile(const float * const image_data, int width, int height, std::string path, float scalef=1) { std::fstream file(path.c_str(), std::ios::out | std::ios::binary); std::string bands; float fvalue; // scale factor and temp value to hold pixel value bands = "Pf"; // grayscale // sign of scalefact indicates endianness, see pfm specs if(isLittleEndian()) scalef = -scalef; // insert header information file << bands << "\n"; file << width << " "; file << height << "\n"; file << scalef << "\n"; if(bands == "Pf"){ // handle 1-band image for (int i=0; i < height; i++) { for(int j=0; j < width; ++j){ fvalue = image_data[i * width + j]; file.write(reinterpret_cast<char *>(&fvalue), sizeof(fvalue)); } } } }
