【问题标题】:getting different result of pgm pixel value in c++ and matlab在 C++ 和 matlab 中得到不同的 pgm 像素值结果
【发布时间】:2013-11-16 03:51:26
【问题描述】:

我知道没有理由在 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;

}

【问题讨论】:

  • 与Matlab相比如何?有点难以遵循您的代码。您是否考虑到 Matlab 矩阵的基索引 = 1,而对于 C++,它是 0?
  • 是的,我已经清理了一些代码

标签: c++ image matlab pgm


【解决方案1】:

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

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

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,则应查找双字节。您可以考虑单独处理这种情况。

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

#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;
}

对于测试文件,我创建了以下内容。注意1的ascii值为49

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 中它是第一个。取决于您如何比较可能重要的事物。

【讨论】:

  • 我稍微简化了程序,以便更容易理解,之后没有再次测试它,所以这是我的错,对此感到抱歉!非常感谢您的回答!
  • 我想这就是发生的事情。很高兴您现在可以控制一切!
  • 所以嗯,我在你的帮助下得到了代码,但是当我对它进行一些矩阵操作时,它似乎很不对劲,所以我看看发生了什么......然后它变成了出C++代码似乎在这里和那里错过像素值,所以说,在matlab中我得到[64、23、45、14、87],在c++中我会得到类似[64、45、14、87]的东西,这根本没有意义...我的图像尺寸是 112x92,整个图像发生了大约 10 次,都在一条线的中间。
  • 这是否意味着您最终会“不同步” - 最后几个像素值是无意义的(可能与最后一个有效值重复)?还是以某种方式“重回正轨”?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多