2017-06-28 85 views
-4

我需要將每像素16位的pgm圖像轉換爲每像素8位的pgm圖像,但是我有問題要讀取pgm圖像16 bpp,我不明白我在做什麼錯誤。這裏的代碼:當它試圖執行istruction IMG打開pgm圖像16 bpp

#include "pgm.h" 

#include <iterator> 
#include <algorithm> 
#include <fstream> 
#include <sstream> 

using namespace std; 

bool convert16to8bit(const std::string& inFilename, mat<uint8_t>& img, const std::string& outFilename){ 
    mat<uint16_t> imgTemp; 

    ifstream is(inFilename, ios::binary); 
    if (!is) 
     return false; 

    string magic; 
    is >> magic; 
    if (magic != "P2" && magic != "P5") 
     return false; 

    size_t rows, cols, nlevels; 
    is >> cols >> rows >> nlevels; 

    if (nlevels < 255) 
     return false; 

    is.get(); 

    img = mat<uint8_t>(rows, cols); 
    if (nlevels == 255){ 
     if (magic == "P5"){ 
      is.unsetf(ios::skipws); 
      img.data_.assign(istream_iterator<uint8_t>(is), istream_iterator<uint8_t>()); 
     }else 
      img.data_.assign(istream_iterator<int>(is), istream_iterator<int>()); 
    } 
    else{ 
     imgTemp = mat<uint16_t>(rows, cols); 
     if (magic == "P5"){ 
      is.unsetf(ios::skipws); 
      imgTemp.data_.assign(istream_iterator<uint16_t>(is), istream_iterator<uint16_t>()); 
     } 
     else 
      imgTemp.data_.assign(istream_iterator<int>(is), istream_iterator<int>()); 

     for (size_t r = 0; r < rows; r++) 
      for (size_t c = 0; c < cols; c++) 
       img(r, c) = imgTemp(r, c); 
    } 

    stringstream ss; 
    ss << outFilename << ".pgm"; 
    ofstream os(ss.str(), ios::binary); 
    if (!os) 
     return false; 
    os << magic <<"\n" << cols << " " << rows << "\n255\n"; 
    if (magic == "P2") 
     copy(begin(img), end(img), ostream_iterator<int>(os, " ")); 
    else 
     copy(begin(img), end(img), ostream_iterator<uint8_t>(os)); 

    return true; 
} 


//mat.h 

#if !defined MAT_H 
#define MAT_H 

#include <vector> 

template <typename T> 
struct mat { 
    size_t rows_, cols_; 
    std::vector<T> data_; 

    mat(size_t rows = 0, size_t cols = 0) : rows_(rows), cols_(cols), data_(rows*cols) {} 

    const size_t rows() const { return rows_; } 
    const size_t cols() const { return cols_; } 

    const T& operator()(size_t r, size_t c) const { return data_[r*cols_ + c]; } 
    T& operator()(size_t r, size_t c) { return data_[r*cols_ + c]; } 

    auto begin() -> decltype(data_.begin()) { return data_.begin(); } 
    auto end() -> decltype(data_.end()) { return data_.end(); } 
    auto begin() const -> decltype(data_.begin()) { return data_.begin(); } 
    auto end() const -> decltype(data_.end()) { return data_.end(); } 
}; 
#endif // MAT_H 

此代碼創建一個錯誤(R,C)= imgTemp(R,C)(錯誤:矢量下標超出範圍)與PGM 16bpp的但與一個pgm 8bpp我可以打開它沒有問題,並重新創建它沒有錯誤的原始。我認爲問題在於istream_iterator < uint16_t>,因爲istream_iterator < uint8_t>可以工作(使用pgm 8bit)。任何解決方案

感謝您的幫助

+1

任何解決方案,到底是什麼? 「我有問題閱讀一張pgm圖片」不是一個問題陳述。你能更精確地知道什麼是不工作的嗎? –

+0

我無法閱讀和記憶大小爲16位的imgTemp.data_像素 –

+1

您是否有例外?編譯器錯誤?帶有你不期望的值的變量?這是幫助我們幫助你的那種信息。你能收集他們,並編輯你的問題,包括他們? –

回答

0

我已經找到了解決我的問題。這裏是正確的代碼,如果它可以用於某人:

#include "pgm.h" 

#include <iterator> 
#include <algorithm> 
#include <fstream> 
#include <sstream> 

using namespace std; 

bool convert16to8bit(const std::string& inFilename, mat<uint8_t>& img, const std::string& outFilename){ 
    mat<uint16_t> imgTemp; 

    ifstream is(inFilename, ios::binary); 
    if (!is) 
     return false; 

    string magic; 
    is >> magic; 
    if (magic != "P2" && magic != "P5") 
     return false; 

    size_t rows, cols, nlevels; 
    is >> cols >> rows >> nlevels; 

    if (nlevels < 255) 
     return false; 

    is.get(); 

    img = mat<uint8_t>(rows, cols); 
    if (nlevels == 255){ 
     if (magic == "P5"){ 
      is.unsetf(ios::skipws); 
      img.data_.assign(istream_iterator<uint8_t>(is), istream_iterator<uint8_t>()); 
     }else 
      img.data_.assign(istream_iterator<int>(is), istream_iterator<int>()); 
    } 
    else{ 
     imgTemp = mat<uint16_t>(rows, cols); 
     if (magic == "P5"){ 

      //here is the line changed 
      is.read(reinterpret_cast<char *>(&imgTemp.data_[0]), imgTemp.rows()*imgTemp.cols() * 2);   
     } 
     else 
      imgTemp.data_.assign(istream_iterator<int>(is), istream_iterator<int>()); 

     for (size_t r = 0; r < rows; r++) 
      for (size_t c = 0; c < cols; c++) 
       img(r, c) = imgTemp(r, c); 
    } 

    stringstream ss; 
    ss << outFilename << ".pgm"; 
    ofstream os(ss.str(), ios::binary); 
    if (!os) 
     return false; 
    os << magic <<"\n" << cols << " " << rows << "\n255\n"; 
    if (magic == "P2") 
     copy(begin(img), end(img), ostream_iterator<int>(os, " ")); 
    else 
     copy(begin(img), end(img), ostream_iterator<uint8_t>(os)); 

    return true; 
}