基于移动平均的图像瓜分

基于移动平均的图像分割

阈值处理直观、实现简单且计算速度快,因此图像阈值处理在图像分割中处于核心地位。阈值处理可分为全局阈值处理和局部阈值处理(可变阈值处理)。本文简单介绍基于移动平均的图像分割,并给出C语言源代码。

移动平均是一种局部阈值处理方法,该方法以一幅图像的扫描行计算移动平均为基础。移动平均分割能减少光照偏差,且计算简单。冈萨雷斯《数字图像处理》中文第三版的P491~P492对移动平均进行了详细的描述,在此特别指出,当感兴趣的物体与图像尺寸相比较小(或较细)时,基于移动平均的阈值处理会工作的很好。打印图像和手写文本图像满足这一条件。

下面给出移动平均分割的代码,使用的工具是OpenCV2.0+VS2008.

#include <cv.h>
#include <highgui.h>

/*	
对输入图像作移动平均分割
src为单通道灰度图像
num表示计算平均的点数
*/
void averMovingSegmentation(const IplImage* src,IplImage* dst,int num)
{
	assert(src->nChannels==1 && dst->nChannels==1);
	assert(src->height==dst->height && src->width==dst->width);
	
	uchar* dstdata = (uchar*)dst->imageData;
	uchar* data = (uchar*)src->imageData;
	int w = src->width, h = src->height;
	int step = src->widthStep;
	float n = (float)num;
	float m_pre = data[0]/n, m_now;
	float b = 0.5;
	for(int i=0;i<h;i++)
	{
		for(int j=0;j<w;j++)
		{
			int index = i*step+j;
			float dif;
			if(index<num+1)
				dif = data[index];		
			else
				dif = data[index]-data[index-num-1];

			dif *= 1/n;
			m_now = m_pre + dif;
			m_pre = m_now;

			if(data[index]>cvRound(b*m_now))
				dstdata[index] = 255;
			else
				dstdata[index] = 0;		
		}
	}
	
}
int main()
{
	char* filename = "D:\\technology\\CV\\Databases\\image\\spot_shaded_text_image.tif";
	IplImage* src_image = cvLoadImage(filename,0);
	if(!src_image)
		return -1;
	cvNamedWindow("src",0);
	cvShowImage("src",src_image);
	IplImage* dst_image = cvCreateImage(cvGetSize(src_image),8,1);
	
	averMovingSegmentation(src_image,dst_image,20);

	cvNamedWindow("dst",0);
	cvShowImage("dst",dst_image);

	cvWaitKey(0);

	cvReleaseImage(&src_image);
	cvDestroyWindow("src");
	cvReleaseImage(&dst_image);
	cvDestroyWindow("dst");

	return 0;
}
基于移动平均的图像瓜分