目录
实验要求
实验目的
了解为何使用抽象类,学习通过继承实现代码重用的机制和方法
掌握如何声明函数为纯虚函数
掌握如何利用纯虚函数,编写派生类的覆盖函数
实验内容
定义滤波器抽象类Filter,并派生两个具体的滤波器:类MeanFilter和类MedianFilter,分别完成对图像的均值滤波和中值滤波。在抽象类Filter中定义纯虚函数Filtering,在两个派生类中实现相应的函数。
在主函数中声明基类指针,通过该指针指向不同的派生类,从而使用不同的滤波器对象对图像进行滤波。并显示滤波后的图像,注意观察两种滤波器对图像滤波效果的差异。在构造滤波器时选择不同的filterSize,观察对滤波输出图像的影响。
抽象类滤波器 Filter.h
#ifndef FILTER_H
#define FILTER_H
#include “Image.h”
class Filter
{
public:
Filter(int size); //构造函数
virtual ~Filter(); //析构函数;
virtual Matrix Filtering(const Matrix &input) = 0; //滤波函数(纯虚函数);
protected:
int filterSize;
};
#endif
派生类 均值滤波器 MeanFilter.h
#ifndef MEANFILTER_H
#define MEANFILTER_H
#include “Filter.h”
class MeanFilter : public Filter
{
public:
MeanFilter(int size);
virtual ~MeanFilter();
virtual Matrix Filtering(const Matrix &input); //均值滤波函数
};
#endif
派生类 中值滤波器 MedianFilter.h
#ifndef MEDIANFILTER_H
#define MEDIANFILTER_H
#include “Filter.h”
class MedianFilter : public Filter
{
public:
MedianFilter(int size);
virtual ~MedianFilter();
virtual Matrix Filtering(const Matrix &input); // 中值滤波器函数
};
#endif
请完成MeanFilter.cpp、MedianFilter.cpp及主函数文件
使用滤波器对图像进行滤波的参考代码
Image img(“Lena_gaussian.bmp"或者"Lena_salt_and_pepper.bmp”);
Filter *filter = NULL;
filter = new MeanFilter(5);
Image result_mean;
result_mean = filter->Filtering(img);
result_mean.WriteBMP(“Mean.bmp”);
delete filter;
filter = new MedianFilter(5);
Image result_median;
result_median = filter->Filtering(img);
medianfilter.WriteBMP(“Median.bmp”);
delete filter;
实验要求
完成上述代码,并能得到正确的结果图像,对结果进行比较。
实验附带了两幅添加了不同噪声的图像(高斯白噪声Lena_gaussian.bmp和椒盐噪声Lena_salt_and_pepper.bmp)。
设计简单的控制台交互,针对不同的图像,更改滤波器大小,观察滤波效果
代码实现
main.cpp
#include<iostream>
#include"Image.h"
#include"Matrix.h"
#include"Filter.h"
#include"MeanFilter.h"
#include"MedianFilter.h"
using namespace std;
int main()
{
//测试读写文件
Image im1("Lena_salt_and_pepper.bmp");
im1.WriteBMP("1.bmp");
Filter* filter = NULL;
filter = new MeanFilter(5);
filter->Filtering(im1);
Image result_mean (im1);
result_mean.WriteBMP("Mean.bmp");
delete filter;
Image im2("Lena_gaussian.bmp");
im2.WriteBMP("2.bmp");
Filter* filter1 = NULL;
filter1 = new MedianFilter(10);
filter1->Filtering(im2);
Image result_mean2(im2);
cout << 1;
result_mean2.WriteBMP("Median.bmp");
delete filter1;
return 0;
}
filter.h
#ifndef FILTER_H
#define FILTER_H
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include "Image.h"
using namespace std;
class Filter
{
public:
Filter(int size)//构造函数
{
filterSize = size;
}
Filter() {
};
virtual ~Filter() //析构函数;
{
cout << "delete" << endl;
}
virtual Matrix Filtering( Matrix& input) = 0; //滤波函数(纯虚函数);
//protected:
int filterSize;
};
#endif
Meanfilter.h
#pragma once
#ifndef MEANFILTER_H
#define MEANFILTER_H
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include "Filter.h"
using namespace std;
class MeanFilter : public Filter
{
public:
MeanFilter(int size)
{
filterSize = size;
}
virtual ~MeanFilter()
{
cout << "delete mean" << endl;
}
virtual Matrix Filtering( Matrix& input); //均值滤波函数
};
Matrix MeanFilter::Filtering( Matrix& input)
{
double** newdate=NULL;
newdate = new double* [input.height + filterSize - 1];
for (int i = 0; i < input.height + filterSize - 1; i++)
newdate[i] = new double[input.width + filterSize - 1];
for (int i = 0; i < input.height + filterSize - 1; i++)
for (int j = 0; j < input.width + filterSize - 1; j++)
{
newdate[i][j] = 0;
}
for (int i = (filterSize - 1) / 2; i < input.height + (filterSize - 1) / 2; i++)
for (int j = (filterSize - 1) / 2; j < input.width + (filterSize - 1) / 2; j++)
newdate[i][j] = input.getdata(i - (filterSize - 1) / 2, j - (filterSize - 1) / 2);
for (int i = (filterSize - 1) / 2; i < input.height + (filterSize - 1) / 2; i++)
for (int j = (filterSize - 1) / 2; j < input.width + (filterSize - 1) / 2; j++)
{
int sum = 0;
for (int n = i - (filterSize - 1) / 2; n < i + filterSize - (filterSize - 1) / 2; n++)
for (int m = j - (filterSize - 1) / 2; m < j + filterSize - (filterSize - 1) / 2; m++)
{
sum += newdate[n][m];
}
sum = sum / (filterSize * filterSize);
input.setdata(i - (filterSize - 1) / 2, j - (filterSize - 1) / 2, sum);
}
for (int i = 0; i < input.height + filterSize - 1; i++)
delete[] newdate[i];
delete[]newdate;
cout << "123:"<<filterSize << endl;
return input;
}
#endif
Medianfilter.h
#pragma once
#ifndef MEDIANFILTER_H
#define MEDIANFILTER_H
#include "Filter.h"
class MedianFilter : public Filter
{
public:
MedianFilter(int size)
{
filterSize = size;
}
virtual ~MedianFilter()
{
cout << "delete median" << endl;
}
virtual Matrix Filtering(Matrix& input); // 中值滤波器函数
};
Matrix MedianFilter::Filtering(Matrix& input)
{
double** newdate;
newdate = new double* [input.getheight() + filterSize - 1];
for (int i = 0; i < input.getheight() + filterSize - 1; i++)
newdate[i] = new double[input.getwidth() + filterSize - 1];
for (int i = 0; i < input.getheight() + filterSize - 1; i++)
for (int j = 0; j < input.getwidth() + filterSize - 1; j++)
{
newdate[i][j] = 0;
}
for (int i = (filterSize - 1) / 2; i < input.getheight() + (filterSize - 1) / 2; i++)
for (int j = (filterSize - 1) / 2; j < input.getwidth() + (filterSize - 1) / 2; j++)
newdate[i][j] = input.getdata(i - (filterSize - 1) / 2, j - (filterSize - 1) / 2);
for (int i = (filterSize - 1) / 2; i < input.getheight() + (filterSize