编写一个均值滤波函数,要求:
1. 函数输入为100*100的图像和3*3的均值滤波矩阵,图像数据类型为unsigned char,均值滤波矩阵数据类型为float。
2. 输入的图像可以自定义,但要有一定意义,比如是一个正弦条纹图。
3. 将输出图像的第一行输出到控制台,并与Matlab计算的结果进行对比,看计算结果是否正确。
注:3*3均值滤波矩阵为
1/9 1/9 1/9
1/9 1/9 1/9
1/9 1/9 1/9
#include "stdafx.h"
#include<cmath>
#include<stdio.h>
#include<fstream>
#include<iostream>
#include<windows.h>
#include<cstdlib>
#include<iomanip>
#include <memory.h>
using namespace std;
unsigned char *pBmpBuf; //读入图像数据的指针
int bmpWidth; //图像的宽
int bmpHeight; //图像的高
RGBQUAD *pColorTable; //颜色表指针
int biBitCount; //图像类型,每像素位数
//-------------------------------------------------------------------------------------------
//读图像的位图数据、宽、高、颜色表及每像素位数等数据进内存,存放在相应的全局变量中
bool readBmp(char *bmpName)
{
FILE *fp = fopen(bmpName, "rb"); //二进制读方式打开指定的图像文件
if (fp == 0) return 0;
//跳过位图文件头结构BITMAPFILEHEADER
fseek(fp, sizeof(BITMAPFILEHEADER), 0);
//定义位图信息头结构变量,读取位图信息头进内存,存放在变量head中
BITMAPINFOHEADER head;
fread(&head, sizeof(BITMAPINFOHEADER), 1, fp); //获取图像宽、高、每像素所占位数等信息
bmpWidth = head.biWidth;
bmpHeight = head.biHeight;
biBitCount = head.biBitCount; //定义变量,计算图像每行像素所占的字节数(必须是4的倍数)
int lineByte = (bmpWidth * biBitCount / 8 + 3) / 4 * 4; //灰度图像有颜色表,且颜色表表项为256
if (biBitCount == 8)
{
//申请颜色表所需要的空间,读颜色表进内存
pColorTable = new RGBQUAD[256];
fread(pColorTable, sizeof(RGBQUAD), 256, fp);
}
//申请位图数据所需要的空间,读位图数据进内存
pBmpBuf = new unsigned char[lineByte * bmpHeight];
fread(pBmpBuf, 1, lineByte * bmpHeight, fp);
fclose(fp);//关闭文件
return 1;//读取文件成功
}
//-------------------------------------------------------------------------------------------
//以下为图像像素的读取函数与均值滤波操作
void ImageData()
{
//操作:将读入图像各像素点DATA保存到一个float型数组里
float image[100][100];
for (int i = 0; i < bmpHeight; i++)
{
for (int j = 0; j < bmpWidth; j++)
{
image[i][j] = *(pBmpBuf + i * 100 + j);
}
}
//操作:均值滤波
for (int i = 1; i < bmpHeight-1; i++)
{
for (int j = 1; j < bmpWidth-1; j++)
{
image[i][j] = (image[i-1][j-1]
+ image[i-1][j]
+ image[i-1][j+1]
+ image[i][j-1]
+ image[i][j]
+ image[i][j+1]
+ image[i+1][j-1]
+ image[i+1][j]
+ image[i+1][j+1] )/ 9;
}
}
//输出图像第一行滤波结果到控制台
for (int j = 1; j < bmpWidth; j++)
{
cout << image[1][j] << " ";
}
cout << endl;
}
int main()
{
//读入指定BMP文件进内存
char readPath[] = "nv.BMP";
readBmp(readPath);
//输出图像的信息
cout << "width=" << bmpWidth << " height=" << bmpHeight << " biBitCount=" << biBitCount << endl;
ImageData();
system("pause");
return 0;
}
经过教研室小伙伴们的完善,下边的代码更加完美(⊙o⊙)…
#include<iostream>
#include<windows.h>
#include<fstream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<iomanip>
using namespace std;
unsigned char *pBmpBuf;//读入图像数据的指针
int bmpWidth;//图像的宽
int bmpHeight;//图像的高
RGBQUAD *pColorTable;//颜色表指针
int biBitCount;//图像类型,每像素位数
//给定一个图像位图数据、宽、高、颜色表指针及每像素所占的位数等信息,将其写到指定文件中
bool readBmp(char *bmpName)
{
FILE *fp = fopen(bmpName, "rb");//二进制读方式打开指定的图像文件
if (fp == 0)
return 0;
//跳过位图文件头结构BITMAPFILEHEADER
fseek(fp, sizeof(BITMAPFILEHEADER), 0);
//定义位图信息头结构变量,读取位图信息头进内存,存放在变量head中
BITMAPINFOHEADER head;
fread(&head, sizeof(BITMAPINFOHEADER), 1, fp);
//获取图像宽、高、每像素所占位数等信息
bmpWidth = head.biWidth;
bmpHeight = head.biHeight;
biBitCount = head.biBitCount;
//定义变量,计算图像每行像素所占的字节数(必须是4的倍数)
int lineByte = (bmpWidth * biBitCount / 8 + 3) / 4 * 4;
//灰度图像有颜色表,且颜色表表项为256
if (biBitCount == 8)
{
//申请颜色表所需要的空间,读颜色表进内存
pColorTable = new RGBQUAD[256];
fread(pColorTable, sizeof(RGBQUAD), 256, fp);
}
//申请位图数据所需要的空间,读位图数据进内存
pBmpBuf = new unsigned char[lineByte * bmpHeight];
fread(pBmpBuf, 1, lineByte * bmpHeight, fp);
fclose(fp);//关闭文件
return 1;//读取文件成功
}
//将图像数据保存至image,并进行滤波操作
void ImageData(float **image)
{
//保存数据
for (int i = 0; i < bmpHeight; i++)
{
for (int j = 0; j < bmpWidth; j++)
{
image[i][j] = *(pBmpBuf + i*bmpWidth + j);
}
}
//滤波操作
for (int i = 1; i < bmpHeight-1; i++)
{
for (int j = 1; j < bmpWidth-1; j++)
{
image[i][j] = (image[i - 1][j - 1] + image[i - 1][j] + image[i - 1][j + 1] + image[i][j - 1] + image[i][j]
+ image[i][j + 1] + image[i + 1][j - 1] + image[i + 1][j] + image[i + 1][j + 1]) / 9;
}
}
//输出图像第一行滤波结果到控制台
for (int j = 1; j < bmpWidth; j++)
{
cout <<image[1][j] << " ";
}
cout << endl;
}
int main()
{
char readPath[] = "nv.bmp";
readBmp(readPath);
float **Image = new float*[bmpHeight];
for (int i = 0; i < bmpWidth; i++)
{
Image[i] = new float[bmpWidth];
}
ImageData(Image);
return 0;
}