C++:OTSU确定标线点云分割阈值

端午节快乐呀。

闲来无事,想着分割一下标线点云,但是阈值怎么确定呢?感觉OTSU应该可以。

一、OTSU简介

OTSU(大津法、最大类间方差法)算法是由日本学者OTSU于1979年提出的一种对图像进行二值化的高效算法。

1.1 原理

利用阈值将原图像分成前景、背景。当取最佳阈值时,背景应该与前景差别最大。otsu中衡量差别的标准是最大类间方差。

1.2 性能

类间方差法对噪音和目标大小十分敏感,它仅对类间方差为单峰的图像产生较好的分割效果。

当目标与背景的大小比例悬殊时,类间方差准则函数可能呈现双峰或多峰,此时效果不好,但是类间方差法是用时最少的。

1.3 公式推导:

k为前景与背景的分割阈值,前景点数占图像比例为w0,平均灰度为u0;背景点数占图像比例为w1,平均灰度为u1

则图像的总平均灰度为:u=w0*u0+w1*u1

前景和背景图象的方差:g = w0*(u0-u)*(u0-u)+w1*(u1-u)*(u1-u) = w0*w1*(u0-u1)*(u0-u1)

当方差g最大时,认为此时前景和背景差异最大,此时的灰度k是最佳阈值。

二、分享给有需要的人,代码质量勿喷

/* The returned threshold of intensity is obtained by OTSU. */
uint xjGetIntensityByOTSU(ccPointCloud* cloud)
{
	uint thrIntensity = 1;

	/* 1 强度直方图 */
	uint histogramIntensity[65536] = { 0 };
	uint maxIntensity = 0, minIntensity = 666666;//最大最小强度值
	uint pcCount = cloud->size();
	ccScalarField* ccSF = static_cast(cloud->getScalarField(cloud->getScalarFieldIndexByName("Intensity")));
	for (int i = 0; i < pcCount; i++)
	{
		uint vIntensity = ccSF->getValue(i);
		if (vIntensity > maxIntensity)
		{
			maxIntensity = vIntensity;
		}
		if (vIntensity < minIntensity)
		{
			minIntensity = vIntensity;
		}
		++histogramIntensity[vIntensity];
	}

	/* 2 总质量矩 += 强度 * 点数 */
	double sumIntensity = 0.0;
	for (int k = minIntensity; k <= maxIntensity; k++)
	{
		sumIntensity += (double)k * (double)histogramIntensity[k];
	}

	/* 3 遍历计算 */
	double otsu = -1.0;
	int w0 = 0;//小于等于当前阈值的点数(前景点数)
	double sumFore = 0.0;//前景质量矩
	for (int k = minIntensity; k <= maxIntensity; k++)
	{
		w0 += histogramIntensity[k];
		int w1 = pcCount - w0;//(后景点数)
		if (w0 == 0)
			continue;
		if (w1 == 0)
			break;

		sumFore += (double)k * histogramIntensity[k];

		double u0 = sumFore / w0; //前景的平均灰度
		double u1 = (sumIntensity - sumFore) / w1; //背景的平均灰度
		double g = (double)w0 * (double)w1 * (u0 - u1) * (u0 - u1); //类间方差

		if (g > otsu)
		{
			otsu = g;
			thrIntensity = k;
		}
	}

	return thrIntensity;
}

三、实验测试

截取一段标线点云,通过OTSU计算得到阈值为44,与统计规律相符合。原图、强度统计直方图、分割结果如下。

C++:OTSU确定标线点云分割阈值_第1张图片

C++:OTSU确定标线点云分割阈值_第2张图片

C++:OTSU确定标线点云分割阈值_第3张图片

你可能感兴趣的:(点云,C++)