0

我知道没有理由在 C++ 上实现一个读取 pgm 图像的像素值的函数,但我必须为我的任务做这件事。

出于准确性原因,在读取像素值后,我将其与使用 imread(file) 在 matlab 中读取的像素值进行了比较,但是,有些值匹配,有些不匹配,我不知道为什么。

下面是c++的函数,图片是二进制格式:

int Read_File_PGM(string filename){

    int row = 0, col = 0, numrows = 0, numcols = 0, bits;

    string filename;
    ifstream infile(filename.c_str(), ios::binary);

    stringstream ss;
    string inputLine = "";

    // First line : version
    getline(infile,inputLine);
    if(inputLine.compare("P5") != 0) cerr << "Version error" << endl;
    //else cout << "Version : " << inputLine << endl;

    // Second line : width and height
    ss << infile.rdbuf();
    ss >> numrows >> numcols;

    int max_bits;
    ss >> max_bits;
    unsigned char pixel;
    unsigned int pixel_value[numrows][numcols];
    //double sum = 0;

    // Following lines : data


            for(row = 0; row < numrows; ++row){
                    for (col = 0; col < numcols; ++col){
                            infile.read(pixel, 1);
                            ss >> pixel;
                            pixel_value[row][col] = (int)pixel;
            }

            }

    infile.close();


    }
    return 0;

}

4

1 回答 1

0

如所写,您的代码无法编译。添加一些标题等后,我仍然遇到了一些错误。

首先 - 你重新声明“文件名” - 它是函数的参数,但你有这条线

string filename;

紧接着int row = 0 …etc

其次,我的编译器(正确地)不喜欢你的行

infile.read(pixel, 1);

错误消息(这甚至不是警告 - 这是一个错误)是

readPgm.cpp:34: error: invalid conversion from ‘unsigned char’ to ‘char*’ 
readPgm.cpp:34: error:   initializing argument 1 of 
     ‘std::basic_istream<_CharT, _Traits>& 
      std::basic_istream<_CharT,_Traits>::read(_CharT*, std::streamsize) 
      [with _CharT = char, _Traits = std::char_traits<char>]’

但实际上——我认为你根本不需要那一行——因为下一行是

ss >> pixel;

并且由于您已经将ss与文件缓冲区相关联

    ss << infile.rdbuf();

我认为您现在可以读取像素。

但是请注意,您的代码隐含地假定最大值为 < 255(每像素一个字节)。该标准规定,如果数字 > 255,您应该查找双字节。您可以考虑单独处理这种情况。

仍然 - 对于我制作的一个小测试文件,以下修改后的代码在读取内容方面做得很好。看看这是否更适合您?

#include <iostream>
#include <string>
#include <fstream>
#include <sstream>

using namespace std;

int Read_File_PGM(string filename)
{
    int row = 0, col = 0, numrows = 0, numcols = 0, bits;
    stringstream ss;    
    ifstream infile(filename.c_str(), ios::binary);

    string inputLine = "";

    // First line : version
    getline(infile,inputLine);
    if(inputLine.compare("P5") != 0) cerr << "Version error" << endl;
    cout << "Version : " << inputLine << endl;

    // Second line : width and height
    ss << infile.rdbuf();
    ss >> numrows >> numcols;

    int max_bits;
    ss >> max_bits;
    char pixel;
    unsigned int pixel_value[numrows][numcols];
    cout << "rows: " << numrows << "; cols: " << numcols << endl;
    cout << "max size: " << max_bits << endl;

    // Following lines : data
    for (row = 0; row < numrows; ++row){
        for (col = 0; col < numcols; ++col){
             ss >> pixel;
             pixel_value[row][col]= pixel;
             cout << (int)pixel << ";";
        }
        cout << endl;
    }
infile.close();    
}

int main(void) {
  Read_File_PGM("testfile.pgm");
  return 0;
}

对于测试文件,我创建了以下内容。注意 ascii 值149等。

P5
5 5 255
12345
23456
34567
45678
56789

上述程序的输出:

Version : P5
rows: 5; cols: 5
max size: 255
49;50;51;52;53;
50;51;52;53;54;
51;52;53;54;55;
52;53;54;55;56;
53;54;55;56;57;

最后的想法:你还必须记住,在 C 中最后一个索引是“快速”的,而在 Matlab 中它是第一个。取决于你如何比较可能重要的事情。

于 2013-11-16T18:45:04.917 回答