我尝试对类型为pgm
的{{1}}图片执行卷积( binary )
设置如下:
输入和输出数组
P5
过滤
vector<vector<char>> image(rows, vector<char>(cols, '\0'));
vector<vector<char>> out(rows, vector<char>(cols, '\0'));
const int SIZE = 3;
将二进制数据插入图像数组
我正在阅读这样的PGM文件:
vector<vector<int>> filter = { { 0, -1, 0 }, { -1, 5, -1 }, { 0, -1, 0 } };
将二进制数据写入输出文件
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];
更改为char,但我仍然遇到同样的错误。
答案 0 :(得分:2)
我不是C ++的专家,但我相信你不能(或者可能不应该)使用>>
运算符来读取二进制文件。
我通过注意到你的图像在有黑色像素的地方出错而解决了这个问题,并且我认为ifstream
当你实际上根本不想要它们被解释时这些空字节被错误地解释了。我降低了图像的对比度,因此像素的范围不再是0-255而是67-197,这一切都有效。因此,当图像中没有低值时,它会起作用。
我认为您需要更改从以下位置读取二进制图像数据的方式:
infile >> image[i][j];
类似于:
infile.read((char*)&image[i][j],1);
或者使用get()
的东西。对不起,我不能更准确,因为C ++不是我的强项,但希望你现在可以继续前进。如果有人在评论中解释我在说什么 - 请随时教我!谢谢。
答案 1 :(得分:-1)
查看text and binary streams的文档:
文本流是由行组成的有序字符序列(零个或多个字符加上终止
'\n'
)。最后一行是否需要终止'\n'
是实现定义的。可能必须在输入和输出上添加,更改或删除字符,以符合在OS中表示文本的约定(特别是,Windows OS上的C流在输出时将\n
转换为\r\n
,并在输入时将\r\n
转换为\n
...
二进制流是一个有序的字符序列,可以透明地记录内部数据。从二进制流读入的数据总是等于先前写入该流的数据。实现只允许在流的末尾附加一些空字符。宽二进制流不需要以初始移位状态结束。
std::fstream
的默认格式是非二进制格式,即它将输入和输出视为文本流。您希望操纵文件中的原始字节,因此您希望将其视为二进制流。要指定二进制流,请在std::ios::binary
对象的构造函数中使用std::fstream
标志。