PGM檔案格式

瘦欲@ 提交于 2020-01-30 18:59:38

PGM檔案格式

PGM全文Portable Gray Map,是一種圖片檔案格式。PGM圖像包含了以下幾個元素:

  1. 一個magic number,代表檔案格式。PGM圖片的magic number是"P5"這兩個字元。
  2. 空白符(空格,tab,CR,LF)
  3. 寬度(W),用ASCII字元表示
  4. 空白符
  5. 高度(H),用ASCII字元表示
  6. 空白符
  7. 最大灰度值(Maxval),用ASCII字元表示
  8. 單個空白符(通常是換行符號)
  9. H個row,每個row有W個灰度值。每個灰度值的範圍落在[0,Maxval],0代表黑色,Maxval代表白色。

TensorRT/samples/common/common.h中讀取PGM檔案的函數:

inline void readPGMFile(const std::string& fileName, uint8_t* buffer, int inH, int inW)
{
    /*
    explicit ifstream (const string& filename, ios_base::openmode mode = ios_base::in);
    mode: Flags describing the requested i/o mode for the file.
    binary mode: Operations are performed in binary mode rather than text.
    */
    std::ifstream infile(fileName, std::ifstream::binary);
    //如果infile.is_open()回傳0則失敗並輸出錯誤訊息;如果回傳1則pass
    assert(infile.is_open() && "Attempting to read from a file that is not open.");
    std::string magic, h, w, max;
    //默認狀態下會忽略空白字元
    infile >> magic >> h >> w >> max;
    /*
    istream& seekg (streamoff off, ios_base::seekdir way);
    Sets the position of the next character to be extracted from the input stream.
    way: it could be: ios_base::beg, ios_base::cur, ios_base::end, meaning begin, current position, and end of the stream
    off: Offset value, relative to the way parameter.
    */
    //因為接下來不再使用">>",所以需要自行跳過空白字元
    infile.seekg(1, infile.cur);
    //reinterpret_cast: it converts pointer of one type to another type without checking if the target type and the type of pointed data are the same
    /*
    istream& read (char* s, streamsize n);
    Extracts "n" characters from the stream and stores them in the array pointed to by "s".
    */
    //注意到std::istream::read的第一個參數是char*型別的,這也是我們需要使用reinterpret_cast的原因
    //將inH * inW個字元讀到buffer中
    infile.read(reinterpret_cast<char*>(buffer), inH * inW);
}

TensorRT/samples/opensource/sampleMNIST/sampleMNIST.cpp中調用readPGMFile

std::vector<uint8_t> fileData(inputH * inputW);
readPGMFile(locateFile(std::to_string(inputFileIdx) + ".pgm", mParams.dataDirs), fileData.data(), inputH, inputW);

將PGM圖片檔中的內容讀到fileData.data()內。

為了更好地理解PGM檔是如何被讀取的,筆者基於readPGMFile寫了一段程序,用於將feep.pgm這個檔案轉成PNG檔。完整代碼放在cpp-code-snippets/opencv/opencv_pgm_to_png.cpp

首先來看看feep.pgm這個檔案,如果以vim編輯器將它打開,會看到:

P5 24 7 15
^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^C^C^C^C^@^@^G^G^G^G^@^@^K^K^K^K^@^@^O^O^O^O^@^@^C^@^@^@^@^@^G^@^@^@^@^@^K^@^@^@^@^@^O^@^@^O^@^@^C^C^C^@^@^@^G^G^G^@^@^@^K^K^K^@^@^@^O^O^O^O^@^@^C^@^@^@^@^@^G^@^@^@^@^@^K^@^@^@^@^@^O^@^@^@^@^@^C^@^@^@^@^@^G^G^G^G^@^@^K^K^K^K^@^@^O^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@^@

仿照sampleMNIST.cpp的方式將它輸出:

 ....  ----  ++++  #### 
 .     -     +     #  # 
 ...   ---   +++   #### 
 .     -     +     #    
 .     ----  ++++  #  

將它轉為PNG圖片檔:
feep.png

參考連結

pgm doc

PGMB Files

cpp-code-snippets/opencv/opencv_pgm_to_png.cpp

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!