相关文章推荐
坏坏的西瓜  ·  cmake ...·  1 月前    · 
性感的小蝌蚪  ·  Android ...·  2 月前    · 
伤情的热水瓶  ·  在 Flutter ...·  1 年前    · 

1. 均值滤波

使用一个M×N的窗口(又称滤波窗口、模板、掩膜),根据一定准则计算窗口内所有像元均值,然后赋予窗口中心像元,作为窗口中心像元滤波后的值。
再逐行或逐列移动窗口,并按上述方法计算,直至每个像元计算完毕。

void MeanFilter(unsigned char* in, unsigned char* out, int W, int H)
	memcpy(void *dest,void *src,unsigned int count
	由src所指内存区赋值count个字节到dest所指内存区
	int sum = W * H * sizeof(unsigned char);   //图像所占容量
	memcpy((unsigned char *)out, (unsigned char*)in, sum);
	for (int j = 1; j < H - 1; j++)
		for (int i = 1; i < W - 1; i++)
			out[j*W + i] = (in[(j - 1)*W + (i - 1)] + in[(j - 1)*W + i] + in[(j - 1)*W + (i + 1)] +
				in[(j)*W + (i - 1)] + in[(j)*W + i] + in[(j)*W + (i + 1)] +
				in[(j + 1)*W + (i - 1)] + in[(j + 1)*W + i] + in[(j + 1)*W + (i + 1)]) / 9;
	cout << "使用<均值滤波>完成图像平滑" << endl;

因为窗口中涉及j-1,j+1,i-1,i+1,所以i和j的范围是从[1,W/H-1).

2. 中值滤波:

基本原理与均值滤波相同,不同的是使用窗口内各点的中值代替窗口中心点的值(一般为奇数窗口)。

void MedianFilter(unsigned char* in, unsigned char* out, int W, int H)
	int sum = W * H * sizeof(unsigned char);   //图像所占容量
	memcpy((unsigned char *)out, (unsigned char*)in, sum);
	for (int j = 1; j < H - 1; j++)
		for (int i = 1; i < W - 1; i++)
			int k = 0;
			unsigned char win[9];
			for (int jj = j - 1; jj < j + 2; jj++)
				for (int ii = i - 1; ii < i + 2; ii++)
					win[k++] = in[jj*W + ii];    //将窗口的九个元素记录到一个数组中
				//排序函数,第5个为中值
				for (int m = 0; m < 5; m++)
					int min = m;
					for (int n = m + 1; n < 9; n++)
						if (win[n] < win[min])
							min = n;
					unsigned char temp = win[m];
					win[m] = win[min];
					win[min] = temp;
				out[j*W + i] = win[4];
	cout << "使用<中值滤波>完成图像平滑" << endl;

3. 完整程序

#include<iostream>
#include<math.h>
#include "gdal_priv.h"
#include "gdalwarper.h"
using namespace std;
void MeanFilter(unsigned char* in, unsigned char* out, int W, int H)
	memcpy(void *dest,void *src,unsigned int count
	由src所指内存区赋值count个字节到dest所指内存区
	int sum = W * H * sizeof(unsigned char);   //图像所占容量
	memcpy((unsigned char *)out, (unsigned char*)in, sum);
	for (int j = 1; j < H - 1; j++)
		for (int i = 1; i < W - 1; i++)
			out[j*W + i] = (in[(j - 1)*W + (i - 1)] + in[(j - 1)*W + i] + in[(j - 1)*W + (i + 1)] +
				in[(j)*W + (i - 1)] + in[(j)*W + i] + in[(j)*W + (i + 1)] +
				in[(j + 1)*W + (i - 1)] + in[(j + 1)*W + i] + in[(j + 1)*W + (i + 1)]) / 9;
	cout << "使用<均值滤波>完成图像平滑" << endl;
void MedianFilter(unsigned char* in, unsigned char* out, int W, int H)
	int sum = W * H * sizeof(unsigned char);   //图像所占容量
	memcpy((unsigned char *)out, (unsigned char*)in, sum);
	for (int j = 1; j < H - 1; j++)
		for (int i = 1; i < W - 1; i++)
			int k = 0;
			unsigned char win[9];
			for (int jj = j - 1; jj < j + 2; jj++)
				for (int ii = i - 1; ii < i + 2; ii++)
					win[k++] = in[jj*W + ii];    //将窗口的九个元素记录到一个数组中
				//排序函数,第5个为中值
				for (int m = 0; m < 5; m++)
					int min = m;
					for (int n = m + 1; n < 9; n++)
						if (win[n] < win[min])
							min = n;
					unsigned char temp = win[m];
					win[m] = win[min];
					win[min] = temp;
				out[j*W + i] = win[4];
	cout << "使用<中值滤波>完成图像平滑" << endl;
void main()
//注册所有的格式驱动
	GDALAllRegister();
	//支持中文路径
	CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO");
	//打开图像
	const char* filepath = "Img.tif";
	GDALDataset* image = (GDALDataset *)GDALOpen(filepath, GA_ReadOnly);
	if (image == NULL)
		//AfxMessageBox("读取图像失败");
		cout << "读取图像失败";
		cout << "读取成功" << endl;
	//定义图像的长宽
	int W = image->GetRasterXSize();
	int H = image->GetRasterYSize();
	int C = image->GetRasterCount();
	GDALDataType ImgType = image->GetRasterBand(1)->GetRasterDataType();   //数字图像类型
	GDALRasterBand *band1 = image->GetRasterBand(1);    //第一个波段的影像读入到数据之中
	unsigned char* bdata = new unsigned char[W*H];  //创建存放数据的内存
	band1->RasterIO(GF_Read, 0, 0, W, H, bdata, W, H, ImgType, 0, 0);   //GDALRasterBand
	//创建保存影像数据集
	GDALDriver* imgDriver = GetGDALDriverManager()->GetDriverByName("GTiff");   //获取驱动
	const char* outFilename1 = "MeanFilter.tif";
	const char* outFilename2 = "MedianFilter.tif";
	GDALDataset* outIMG1 = imgDriver->Create(outFilename1, W, H, 1, ImgType, NULL);
	GDALDataset* outIMG2 = imgDriver->Create(outFilename2, W, H, 1, ImgType, NULL);
	unsigned char* newdata = new unsigned char[W*H];
	MeanFilter(bdata,newdata, W, H);
	outIMG1->GetRasterBand(1)->RasterIO(GF_Write, 0, 0, W, H, newdata, W, H, ImgType, 0, 0);
	MedianFilter(bdata, newdata, W, H);
	outIMG2->GetRasterBand(1)->RasterIO(GF_Write, 0, 0, W, H, newdata, W, H, ImgType, 0, 0);
	//保存影像
	GDALClose(image);
	GDALClose(outIMG1);
	GDALClose(outIMG2);
	delete bdata;
	delete newdata;
	system("pause");
中值滤波器是一种非线性滤波器,常用于消除图像中的椒盐噪声。与低通滤波不同的是,中值滤波有利于保留边缘的尖锐度,但它会洗去均匀介质区域中的纹理。因为椒盐噪声是由灰度值为0或者255产生的点,所以去像素周围像素值得中值得话很容易剔除校验噪声。
#include 
#include 
#include 
using namespace cv;
using namespace std;
				
作者选修了一门关于VC++面向对象编程的课程,大作业要求读取文档数据,在单文档框架下进行波形绘制,并要求对数据进行滤波处理。这里给大家分享一种十分简单的数据处理办法。 想法源于网上关于对图片的处理,均值滤波,对自己连同周围的数据求平均值。 下面举例说明,比如我们要进行5位均值平滑滤波,对数组第i个变量的处理是,它要等于原数组第i-2、i-1、i、i+1、i+2个变量的平均值,对每个变量都进行同样操作,即可实现均值滤波,位数即代表选取周围多少数来进行平均。代码如下...
f=zeros(m,n); f(1,1)=(g(1,1)+g(1,2)+g(2,1)+g(2,2)); f(m,1)=1/4*(g(m-1,1)+g(m-1,2)+g(m,1)+g(m,2)); f(1,n)=1/4*(g(1,n-1)+g(1,n)+g(2,n-1)+g(2,n)); f(m,n)=1/4*(g(m-1,n-1)+g(m-1,n)+g(m,n-1)+g(m,n)); for i=2:m-1 f(i,1)=1/6*(g(i-1,1)+g(i,1)+g(i+1,1)+g(i-1,2)+g(i,2)+g(i+1,2)); f(i,n)=1/6*(g(i-1,n)+g(i,n)+g(i+1,n)+g(i-1,n-1)+g(i,2)+g(i+1,n-1)); for j=2:n-1 f(1,j)=1/6*(g(1,j-1)+g(1,j)+g(1,j+1)+g(2,j-1)+g(2,j)+g(2,j+1)); f(m,j)=1/6*(g(m-1,j-1)+g(m-1,j)+g(m-1,j+1)+g(m,j-1)+g(m,j)+g(m,j+1)); for i=2:m-1 for j=2:n-1 f(i,j)=1/9*(g(i-1,j-1)+g(i,j-1)+g(i+1,j-1)+g(i-1,j)+g(i,j)+g(i+1,j)+g(i-1,j+1)+g(i,j+1)+g(i+1,j+1)); f=uint8(f); figure(2) imshow(f); title('junzhi灰度图像') 原理很简单,如果一个信号是平缓变化的,那么某一点的输出值可以用这点的某个大小的邻域内的所有值的统计中值来代替。这个邻域在信号处理领域称之为窗(window)或者模板(Mask)。模板开的越大,输出的结果就越平滑,但也可能会把我们有用的信号特征给抹掉。所以窗的大小要根据实际的信号和噪声特性来确定。 一般来说这个中值滤波是去除椒盐噪声的非常理想的选择。 ** method to remove noise from the corrupted image by median value * @param corrupted input grayscale binary array with corrup...