最大类间方差法

最大类间方差法(Otsu)

 顾名思义该方法利用目标区域与背景区域之间的方差最大的思想,达到分割图像的目的。也就是说,选取最佳阈值T时,目标与背景之间的方差值最大,小于阈值T的区域为D1,大于阈值的区域为D2,如此一来即可将需要的区域区分开来。话不多说,上代码:

//统计灰度直方图,直接在图像转数组中实现
 private unsafe void Image2Byte()
        {
            BitmapData unlock = new BitmapData();
            unlock = _bitmap.LockBits(new Rectangle(0, 0, _w, _h),
            ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
            int stride = unlock.Stride;
            byte* temp = (byte*)unlock.Scan0.ToPointer();
            for (int j = 0; j < _h; j++)
            {
                for (int i = 0; i < _w; i++)
                {
                    // gray =R*0.299 + G*0.587 + B*0.114 
                    int gray = temp[0] * 19595 + temp[1] * 38469 + temp[2] * 7472 >> 16;
                    _grayData[i, j] = (byte)gray;
                    _grayHistogram[gray]++;
                    temp += 3;
                }
                temp += stride - 3 * _w;
            }
            _bitmap.UnlockBits(unlock);
        }
//排除开头和结尾灰度数量为0的部分,减少计算量
   private bool NoneZero(int value)
        {
            return value != 0 ? true : false;
        }
        /// <summary>
        /// 最大类间方差法
        /// </summary>
        private int Otsu()
        {
            Image2Byte();
            int sumPoint = _grayData.Length;     //图像所有点数
            double sumGray = 0;                  //图像总灰度值       
            for (int i = 0; i < 256; i++)    
            {
                sumGray +=i*_grayHistogram[i];
            }
            int minGray = Array.FindIndex(_grayHistogram, NoneZero);   //灰度非零起始点
            int maxGray = Array.FindLastIndex(_grayHistogram, NoneZero);//灰度非零结束点

            int threshold = minGray;                  //初始最大类间方差
            double maxVariance = 0;                   //初始最大方差
            double desSumGray = 0;                    // 初始目标质量矩
            double desSumPoint = 0;                   // 初始目标点数

            for (int i = minGray; i < maxGray; i++)
            {
                if (_grayHistogram[i] == 0) continue;

                desSumPoint += _grayHistogram[i];      //目标区域总点数
                desSumGray += i * _grayHistogram[i];   //灰度值点数 * 灰度值 = 目标区域总灰度值

                double diference = desSumGray/desSumPoint- sumGray / sumPoint;
                double variance = (diference * diference )*( desSumPoint / (sumPoint - 
                                   desSumPoint));
                if (variance > maxVariance)
                {
                    maxVariance = variance;
                    threshold = i;
                }
            }
            return threshold;
        }

总结:该方法在图像灰度直方图呈现单峰时效果较好。但图像在光照不均匀,噪声点大等情况下分割效果不佳,具体应用可参考最大类间方差法的思想,将目标与背景分为两个部分,分别处理,在合一起考虑的思想。

 

参考文献:[1]Otsu N. A threshold selection method from gray-level histograms[J]. Automatica, 1975, 11(285-296): 23-27.

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值