свертка с использованием фильтра нижних частот 3X3 для изображения .pgm в Stack Overflow

Я пытаюсь написать программу на C ++, которая имеет следующие 3 функции:
(i) read_pgm_image () — прочитать изображение в формате .pgm из файла;
(ii) convolve () — для свертки изображения с использованием фильтра нижних частот 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 (). В идеале я должен получить размытую версию входного изображения (которую я не могу загрузить). Но вместо этого я получаю изображение мусора.

Любая помощь высоко ценится…
Спасибо.

1

Решение

Вы декларируете img быть двумерным массивом целых чисел, то есть каждая запись в массиве составляет 4 байта. Вы также читаете файл 4 байта за раз, используя sizeof(int),

 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, значения пикселей либо 1 или 2 байта, (или char или же shorts) в зависимости от того, является ли максимальное значение интенсивности больше 255. Вы читаете 2 или 4 пиксельные значения из файла в 1 запись в вашем img массив.

Ваш читатель файла должен выглядеть более понравившимся. Мы можем прочитать файл сразу, так как массивы 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%):

введите описание изображения здесь

1

Другие решения

Есть небольшая ошибка с границами цикла для k и l (< должно быть <=), так что вы суммируете 4 пикселя вместо 9. Вы делите на 9 позже, чтобы получить среднее значение, которое будет правильным, если вы добавите правильное количество пикселей, но сумма уже имеет недостатки.

2

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector