distorted image in pgm binary file manipulation

ⅰ亾dé卋堺 提交于 2019-12-25 16:00:39

问题


I'm trying to perform convolution on a pgm image of type P5 (binary) with the set up below:

input and output array

vector<vector<char>> image(rows, vector<char>(cols, '\0'));
vector<vector<char>> out(rows, vector<char>(cols, '\0'));

const int SIZE = 3;

Filter

vector<vector<int>> filter = { { 0, -1, 0 }, { -1, 5, -1 }, { 0, -1, 0 } };

insert binary data into image array

I'm reading PGM file like this:

getline(infile, type);
//getline(infile, comment);   
infile >> rows >> cols;   
getline(infile, line);
getline(infile, highest);    
//getline(infile, line);

for (int i = 0; i < rows; i++)
    for (int j = 0; j < cols; j++)
        infile >> image[i][j]; //infile is from filestream


outfile.open("output.pgm");

//Insert default header attributes into output pgm file.
outfile << type  << "\n" << rows << " " << cols << "\n" << maxpx << "\n";


    for (int i = SIZE / 2; i < rows - SIZE / 2; i++)
    {
        for (int j = SIZE / 2; j < cols - SIZE / 2; j++)
        {
            uint8_t sum = 0;
            for (int k = -SIZE / 2; k <= SIZE / 2; k++)
            {
                for (int l = -SIZE / 2; l <= SIZE / 2; l++)
                {
                    sum += image[i+k][j+l] * filter[k + SIZE / 2][l + SIZE / 2];
                }
            }
          out[i][j] = sum;
        }
    }

Write binary data into out file

for (int i = 0; i < rows; i++)
    for (int j = 0; j < cols; j++)
        outfile << out[i][j];

I do not get any error when I run the code, but the image is distorted. I can clearly make out some part of the output image, but it's is not coming out complete.

Not sure if it has to do with my manipulation.

Update:

I changed uint8_t to char, but I still get the same error.

  1. When I change outfile << out[i][j]; to outfile << image[i][j]; so I can get the actual image back, but looks like there could be some issues with how I'm reading the file into image vector. Not sure how to at this point. I get this image

Lena.pgm file

MCVE(Pastebin)


回答1:


I am no expert on C++, but I believe you cannot (or maybe should not) use the >> operator to read binary files.

I worked this out by noticing that your image goes wrong where there are black pixels and I believe that these null bytes are being interpreted incorrectly by ifstream when you don't actually want them interpreted at all. I decreased the contrast on your image so the range of the pixels was no longer 0-255 but 67-197 and it all works. So it works when there are no low values in your image.

I believe you need to change the way you read the binary image data from:

infile >> image[i][j];

to something like:

infile.read((char*)&image[i][j],1);

or maybe something using get(). Sorry, I cannot be more precise, as C++ is not my forte but hopefully you can now proceed further. If anyone cares to explain what I am saying in a comment - please feel free to teach me! Thank you.




回答2:


Check out the documentation for text and binary streams:

A text stream is an ordered sequence of characters composed into lines (zero or more characters plus a terminating '\n'). Whether the last line requires a terminating '\n' is implementation-defined. Characters may have to be added, altered, or deleted on input and output to conform to the conventions for representing text in the OS (in particular, C streams on Windows OS convert \n to \r\n on output, and convert \r\n to \n on input)

...

A binary stream is an ordered sequence of characters that can transparently record internal data. Data read in from a binary stream always equals to the data that were earlier written out to that stream. Implementations are only allowed to append a number of null characters to the end of the stream. A wide binary stream doesn't need to end in the initial shift state.

The default format for a std::fstream is non-binary, that is, it treats the input and output as a text stream. You want to manipulate the raw bytes in the file, so you want to treat it as a binary stream. To specify a binary stream, use the std::ios::binary flag in the constructor of your std::fstream object.



来源:https://stackoverflow.com/questions/39797167/distorted-image-in-pgm-binary-file-manipulation

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