【图像处理】积分图及均值滤波c++

@转载请注明出处
积分图:
假设原图图幅wxh,则积分图图幅为(w+1)*(h+1)。
积分图第一行和第一列全为0,其余点为图像像素点左上角所有像素值的和。
计算方法有两种:

  • 方法1.计算前一行当前列的和,加上当前行,该列前所有像素值的和。
  • 方法2.左边像素点的积分和,加上上一行当前列的积分和,减去上一行左边像素的积分和,加上当前像素值。
    假设要求像素点(x,y)的积分和,左边像素点为(x-1,y),上一行当前列(x,y-1),上一行左边像素(x-1,y-1)。
    ii(x,y) = ii(x-1,y) + ii(x,y-1) - ii(x-1,y-1) + f(x,y).

均值滤波
主要用于降噪。一般计算3x3或5x5区域的平均值。因而可以用积分图,计算3x3区域的和,然后求平均值。

#include <opencv2/opencv.hpp>
#include <iostream>

int* create_integra_map(unsigned char* src, int rows, int cols)
{
	int r,c,size;
	int* map;
	unsigned char* ptr;
	int* maplast;
	int* mapnow;
	int sum = 0;
	size = sizeof(int)*(rows+1)*(cols+1);
	map = (int*)malloc(size);
	memset(map,0,size);

	for(r = 0; r < rows; r++)
	{
		ptr = src + r*cols;
		maplast = map + r * (cols + 1) + 1;
		mapnow = map + (r + 1) * (cols + 1) + 1;
		mapnow[-1] = 0;
		for(c = 0, sum = 0; c < cols; c++)
		{
			sum += ptr[c];
			mapnow[c] = maplast[c] +sum;
		}
	}
	return map;
}

void meanBlur(unsigned char* src, int rows, int cols, unsigned char* dst)
{
	unsigned char* ptr;
	int r,c,sum;
	int *maplast, *mapnext;
	unsigned char* out;
	int* maps = create_integra_map(src, rows, cols);
	for(r = 1; r < rows - 1; r++)
	{
		ptr = src + r*cols;
		maplast = maps + (r-1)*(cols+1) + 1;
		mapnext = maps + (r+2)*(cols+1) + 1;
		out = dst + r * cols;
		for(c = 1; c < cols - 1; c++)
		{
			sum = mapnext[c+1] + maplast[c-2] - (mapnext[c-2] + maplast[c+1]);
			out[c] = (int)(sum / 9.0f);
		}
	}
	free(maps);
}
int main()
{
	cv::Mat src = cv::imread("lena.jpg", 0);
	cv::Mat dst(src.size(),src.type(),cv::Scalar::all(0));
	meanBlur(src.data, src.rows, src.cols, dst.data);
	cv::imshow("meanblur.jpg", dst);
	cv::waitKey(0);
	return 0;
}
发布了35 篇原创文章 · 获赞 13 · 访问量 6331

猜你喜欢

转载自blog.csdn.net/qq_35306281/article/details/96561047