pgm 二进制文件操作中的图像失真
distorted image in pgm binary file manipulation
我正在尝试对 P5
类型的 pgm
图像执行卷积(二进制)
设置如下:
输入输出数组
vector<vector<char>> image(rows, vector<char>(cols, '[=10=]'));
vector<vector<char>> out(rows, vector<char>(cols, '[=10=]'));
const int SIZE = 3;
过滤器
vector<vector<int>> filter = { { 0, -1, 0 }, { -1, 5, -1 }, { 0, -1, 0 } };
将二进制数据插入图像数组
我正在这样读取 PGM 文件:
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;
}
}
将二进制数据写入输出文件
for (int i = 0; i < rows; i++)
for (int j = 0; j < cols; j++)
outfile << out[i][j];
当我 运行 代码时我没有得到任何错误,但是图像失真了。我可以清楚地辨认出输出图像的某些部分,但它并不完整。
不知道是不是和我的操作有关
更新:
我把uint8_t
改成了char,但还是报同样的错误。
- 当我将
outfile << out[i][j];
更改为 outfile << image[i][j];
以便恢复实际图像时,但看起来我将文件读入 image
的方式可能存在一些问题向量。不知道在这一点上如何。
我得到这张图片
查看 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.
std::fstream
的默认格式是非二进制的,也就是说,它将输入和输出视为文本流。你想操作文件中的原始字节,所以你想把它当作二进制流。要指定二进制流,请在 std::fstream
对象的构造函数中使用 std::ios::binary
标志。
我不是 C++ 专家,但我相信您不能(或者不应该)使用 >>
运算符来读取二进制文件。
我注意到你的图像在有黑色像素的地方出错了,我相信这些空字节被 ifstream
错误地解释了,而你实际上根本不想解释它们。我降低了图像的对比度,因此像素范围不再是 0-255,而是 67-197,一切正常。所以当你的图像中没有低值时它会起作用。
我认为您需要更改从以下位置读取二进制图像数据的方式:
infile >> image[i][j];
类似于:
infile.read((char*)&image[i][j],1);
或者使用 get()
的东西。抱歉,我不能说得更准确,因为 C++ 不是我的强项,但希望您现在可以更进一步。如果有人想在评论中解释我在说什么 - 请随时教我!谢谢。
我正在尝试对 P5
类型的 pgm
图像执行卷积(二进制)
设置如下:
输入输出数组
vector<vector<char>> image(rows, vector<char>(cols, '[=10=]'));
vector<vector<char>> out(rows, vector<char>(cols, '[=10=]'));
const int SIZE = 3;
过滤器
vector<vector<int>> filter = { { 0, -1, 0 }, { -1, 5, -1 }, { 0, -1, 0 } };
将二进制数据插入图像数组
我正在这样读取 PGM 文件:
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;
}
}
将二进制数据写入输出文件
for (int i = 0; i < rows; i++)
for (int j = 0; j < cols; j++)
outfile << out[i][j];
当我 运行 代码时我没有得到任何错误,但是图像失真了。我可以清楚地辨认出输出图像的某些部分,但它并不完整。
不知道是不是和我的操作有关
更新:
我把uint8_t
改成了char,但还是报同样的错误。
- 当我将
outfile << out[i][j];
更改为outfile << image[i][j];
以便恢复实际图像时,但看起来我将文件读入image
的方式可能存在一些问题向量。不知道在这一点上如何。 我得到这张图片
查看 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.
std::fstream
的默认格式是非二进制的,也就是说,它将输入和输出视为文本流。你想操作文件中的原始字节,所以你想把它当作二进制流。要指定二进制流,请在 std::fstream
对象的构造函数中使用 std::ios::binary
标志。
我不是 C++ 专家,但我相信您不能(或者不应该)使用 >>
运算符来读取二进制文件。
我注意到你的图像在有黑色像素的地方出错了,我相信这些空字节被 ifstream
错误地解释了,而你实际上根本不想解释它们。我降低了图像的对比度,因此像素范围不再是 0-255,而是 67-197,一切正常。所以当你的图像中没有低值时它会起作用。
我认为您需要更改从以下位置读取二进制图像数据的方式:
infile >> image[i][j];
类似于:
infile.read((char*)&image[i][j],1);
或者使用 get()
的东西。抱歉,我不能说得更准确,因为 C++ 不是我的强项,但希望您现在可以更进一步。如果有人想在评论中解释我在说什么 - 请随时教我!谢谢。