我正在尝试用C ++编写一个程序,该程序具有以下3个函数: (i)read_pgm_image() - 从文件中读取.pgm格式的图像; (ii)卷积() - 使用3X3低通滤波器对图像进行卷积;和, (iii)write_pgm_image() - 将图像数据写回单独的文件
这是我的代码:
#include<iostream>
#include<fstream>
#include<string>
using namespace std;
void read_pgm_image(char name[]);
void convolve(int img[][256], int M, int N, int img_intensity);
void write_pgm_image(char name[], int img[256][256], int img_data[]);
int main()
{ read_pgm_image("lenna2.pgm");
getchar();
return 0;
}
void read_pgm_image(char name[])
{ string magic, creator_info;
int img_intensity, M, N;
ifstream file(name, ios::binary);
if(file.is_open())
{ cout<<"File successfully opened! \n\n";
cout<<"Reading the file...\n";
cout<<"Name of the file:\t"<<name<<'\n';
getline(file,magic); // get the magic number
getline(file,creator_info); // get the creator information
file>>M; // get width of the image
cout<<"Width of the Image:\t"<<M<<'\n';
file>>N; // get length of the image
cout<<"Length of the Image:\t"<<N<<'\n';
file>>img_intensity; // get the image intensity
cout<<"Maximum Intensity:\t"<<img_intensity<<'\n';
int img[256][256]; // create an array to store image data
for(int i=0; i<N; i++)
{ for(int j=0; j<M; j++)
{ file.read((char*)&img[i][j],sizeof(int));
}
}
file.close();
convolve(img, M, N, img_intensity); // Calling the Convolve function
}
else
{ cout<<"Error in opening image!";
file.close();
}
}
void convolve(int img[256][256], int M, int N, int img_intensity)
{ int con_img[256][256], sum=0, img_data[3]={M,N,img_intensity};
for(int i=0; i<N; i++)
{ for(int j=0; j<M; j++)
{ con_img[i][j]=img[i][j];
}
}
for(int i=1; i<(N-1); i++)
{ for(int j=1; j<(M-1); j++)
{ for(int k=(i-1); k<(i+1); k++)
{ for(int l=(j-1); l<(j+1); l++)
{ sum = sum + img[k][l];
}
}
con_img[i][j] = sum/9;
sum=0;
}
}
write_pgm_image("image_convolve.pgm", con_img, img_data);
}
void write_pgm_image(char name[], int img[256][256], int img_data[3])
{ cout<<"\nCreating image file...\n";
ofstream file(name,ios::binary);
if(file.is_open())
{ cout<<"File successfully created!\n";
cout<<"Writing image data...\n";
file<<"P5\n"<<img_data[0]<<' '<<img_data[1]<<' '<<img_data[2]; //Writing P5, image width, image length and maximum intensity
cout<<"Image data written!\n";
for(int i=0; i<img_data[1]; i++) //Write image data to the file
{ for(int j=0; j<img_data[0]; j++)
{ file.write((char*)&(img[i][j]), sizeof(int));
}
}
cout<<"Image pixel info written!\n";
file.close();
}
else
{ cout <<"Error in creating file!";
file.close();
}
}
在convolve()函数中似乎存在一些问题。理想情况下,我应该得到输入图像的模糊版本(我无法上传)。但我得到的是垃圾图片。
非常感谢任何帮助...... 谢谢。
答案 0 :(得分:2)
k和l的循环边界存在一个小错误(&lt;应该是&lt; =),所以你总计4个像素而不是9个。你以9除以得到平均值,这将是如果你加了正确的像素数,那就更正了,但总和已经存在缺陷了。
答案 1 :(得分:1)
您声明img
是一个2D整数数组,也就是说数组中的每个条目都是4个字节。您还使用sizeof(int)
一次读取4个字节的文件。
int img[256][256]; // create an array to store image data
for(int i=0; i<N; i++)
{ for(int j=0; j<M; j++)
{ file.read((char*)&img[i][j],sizeof(int));
}
}
根据PGM file specification,像素值为 1或2字节,(char
或shorts
),具体取决于最大强度值是否为大于255.您正在从文件中读取2或4个像素值到img
数组中的1个条目。
你的文件阅读器看起来应该更喜欢这个。我们可以一次性读取该文件,因为C ++和PGM数组都按行主顺序存储数据。
char img[N][M];
file.ignore(); // ignore one character (as described in file specification)
file.read((char*)img,(streamsize)sizeof(img));
如果仍然无效,请确保您可以重现此PGM文件test.pgm
的结果:
P5
# this is a comment
5 5
255
!!!!!AAAAA~~~~~AAAAA!!!!!
打印矩阵给出了以下值:
33 33 33 33 33
65 65 65 65 65
126 126 126 126 126
65 65 65 65 65
33 33 33 33 33
我计算机上的图像查看器显示如下(放大2000%):