优化图像处理中均值和方差计算

优化图像处理中均值和方差计算

一、均值和方差的普通优化

图像处理中,有时候会需要计算图像某区域的均值和方差。在我之前的博客中《图像比较之模板匹配》,对计算方差有做简化计算的介绍。详细介绍可以参考我之前的博文。在此,我简单的介绍下计算方差的简化方法:

按照上述方式计算均值和方差,很多应用场景下都比较合适。但是有两个缺陷:

  1. 如果均值远大于标准差,意味着方差计算中相减的两个数非常接近,将引入过度舍入的问题;
  2. 对于新增加一个统计变量重新计算其均值和方差的时候,需要对所有统计变量再重新计算,做了大量的重复工作,效率不高;

 

经过如下方法简化计算之后,如果新增一个变量计算全体统计变量均值和方差的时候,并不需要重新再对所有变量进行统计计算。只需要保存三个变量即可:当前统计变量数量;当前统计变量和;当前统计变量和平方和:

其BASIC语言实现方式为:

 

二、利用直方图信息优化均值和方差的计算

图像处理中,也常常会涉及到直方图。假若我们已知了某幅图像的直方图信息,那么我们还有更加简便有效的方式计算图像的均值和方差。我们知道图像直方图中每个bin中所代表的值是具有相同灰度值像素的数量,相当于把图像像素进行了分组统计。这就方便在计算均值和方差也可进行分组计算累加。因此,我们可以依据直方图的信息按照如下公式进行均值和方差的计算:

                                                                                                                    \mu =\frac{1}{N}\sum_{i=0}^{M-1}iH_{i}

                                                                                                                 \sigma ^{2}=\frac{1}{N}\sum_{i=0}^{M-1}(i-\mu )^{2}H_{i}

 

其BASIC语言实现为:

 

三、在OpenCV的简单应用

int main()
{
	int dims = 1;
	int sizes[] = {256};
	int type = CV_HIST_ARRAY;
	float range[] = {0,255};
	float *ranges[] = {range};
	CvHistogram *hist = NULL;
	IplImage *src_img;
	CvScalar Avg,Std;

	int i,count;
	double Avg_Hist = 0,Std_Hist = 0;

	src_img = cvLoadImage("8Bit_lena.bmp",-1);
	if(src_img  == NULL)
	{
		printf("wrong input pic\n");
		return -1;
	}

	hist = cvCreateHist(dims,sizes,type,ranges,1);
	cvCalcHist(&src_img,hist,0,NULL);

	count = src_img->width*src_img->height;
	for(i = 0;i < 256;i++)
		Avg_Hist += i*cvQueryHistValue_1D(hist,i);
	
	Avg_Hist = Avg_Hist/count;
	printf("Avg from hist:%f\n",Avg_Hist);


	for(i = 0;i < 256;i++)
		Std_Hist += pow((i-Avg_Hist),2)*cvQueryHistValue_1D(hist,i);

	Std_Hist = sqrt(Std_Hist/(count));
	printf("Std from hist:%f\n",Std_Hist);


    cvAvgSdv(src_img,&Avg,&Std,0);
	puts("\n");
	printf("平均值 \n");
	printf("Avg in channel1:%f\n",Avg.val[0]);
	printf("Avg in channel2:%f\n",Avg.val[1]);
	printf("Avg in channel3:%f\n",Avg.val[2]);
	printf("Avg in channel4:%f\n",Avg.val[3]);

	printf("方差\n");
	printf("Std in channel1:%f\n",Std.val[0]);
	printf("Std in channel2:%f\n",Std.val[1]);
	printf("Std in channel3:%f\n",Std.val[2]);
	printf("Std in channel4:%f\n",Std.val[3]);


	printf("\ndiff Avg and Std from hist and function:%f %f\n",fabs(Avg.val[0]-Avg_Hist),fabs(Std.val[0]-Std_Hist));
	cvNamedWindow("Show original image",0);
	cvShowImage("Show original image",src_img);
	cvWaitKey(0);
	cvDestroyWindow("Show original image");
	printf("done\n");
	cvReleaseImage(&src_img);

	return 0;
}

测试图像数据:

测试结果和Opencv函数计算结果一致:

 

 

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值