получить другой результат значения пикселя pgm в c ++ и matlab

0

Я понимаю, что нет причин для реализации функции, которая считывает значения пикселей изображения pgm на c++, но я должен сделать это для моего назначения.

По соображениям точности после того, как я прочитал значения пикселей, я сравнил их со значениями пикселей, считываемыми в Matlab, используя imread (файл), однако некоторые из значений совпадают, а некоторые отключены, и я не уверен, почему.

Ниже приведена функция для 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;

}

  • 1
    Как вы сравниваете с Matlab? Немного трудно следовать вашему коду. Вы принимаете во внимание тот факт, что матрица Matlab имеет базовый индекс = 1, а для C ++ это 0?
  • 0
    Да, я немного почистил код
Теги:
image
pgm

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. Вы можете рассмотреть вопрос о том, что этот случай отдельно.

Тем не менее - для небольшого тестового файла, который я сделал, следующий модифицированный код выполнил работу по чтению OK. Посмотрите, работает ли это лучше для вас?

#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 1 равно 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 - первым. В зависимости от того, как вы сравниваете вещи, которые могут иметь значение.

  • 0
    Я немного упростил программу, чтобы было легче следить, и не проверял ее потом, так что мне плохо, извините за это! Большое спасибо за ваш ответ!
  • 0
    Я понял, что так и случилось. Рад, что у вас все под контролем!
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню