均值滤波的快速实现

时间复杂度比较高的版本,每个像素点做(hor_radius * 2 + 1) * (ver_radius * 2 + 1) 次加法和1次除法

void MeanFilter(uint8* img, int width, int height, int pitch, 
	int hor_radius, int ver_radius) // filter size
{
	uint8* temp = new uint8[height * pitch];
	memcpy(temp, img, sizeof(uint8) * height * pitch);
	int n = (hor_radius * 2 + 1) * (ver_radius * 2 + 1);

	for(int ver = ver_radius; ver < height - ver_radius; ++ver) {
		for(int hor = hor_radius; hor < width - hor_radius; ++hor) {
			int sum = 0;
			for(int row = ver - ver_radius; row <= ver + ver_radius; ++row) {
				for(int col = hor - hor_radius; col <= hor + hor_radius; ++col) {
					sum += temp[row * pitch + col];
				}
			}
			img[ver * pitch + hor] = sum / n;
		}
	}

	delete [] temp;
}


无论滤波器的尺寸多大,平均每个像素点只做4次加减法,1次除法

void FastMeanFilter(uint8* img, int width, int height, int pitch, 
	int hor_radius, int ver_radius) // filter size
{
	uint8* temp = new uint8[(height + 1) * pitch];
	memset(temp, 0, pitch);
	uint8* srcp = temp + pitch;
	memcpy(srcp, img, sizeof(uint8) * height * pitch);
	
	int* buf = new int[width+1];
	memset((void*)buf, 0, sizeof(int) * (width + 1) );
	int* bufp = buf + 1;

	int filter_width = hor_radius * 2 + 1;
	int filter_height = ver_radius * 2 + 1;
	int n = filter_width * filter_height;

	uint8* dstp = img + ver_radius * pitch + hor_radius;
	int inc = pitch - width;
	int offset = filter_height * pitch;

	// 计算图像最上面的filter_height-1行中,每一列的像素值之和
	int ver, hor;
	for(ver = 0; ver < filter_height - 1; ++ver) {
		for(hor = 0; hor < width; ++hor) {
			*bufp += *srcp++;
			bufp++;
		}
		srcp += inc;
	}

	for(; ver < height; ++ver) {
		int blk_sum = 0;
		bufp = buf + 1;
		for(hor = 0; hor < filter_width - 1; ++hor) {
			*bufp += *srcp - *(srcp - offset);
			blk_sum += *bufp;
			++srcp;
			++bufp;
		}

		for(; hor < width; ++hor) {
			// 加上最下行的像素值,减去最上行的像素值,得到列像素值的和
			*bufp += *srcp - *(srcp - offset);
			// 加上最右边列的像素值和,减去最左边列的像素值和,得到块的和
			blk_sum += *bufp - *(bufp - filter_width); 
			*dstp++ = blk_sum / n;
			++srcp;
			++bufp;
		}

		srcp += inc;
		dstp += inc + filter_width - 1;
	}

	delete [] buf;
	delete [] temp;
}






 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值