① 设灰度级为L,灰度值i的像素出现的频数为。分别为所纷呈的两个像素类的面积比,即
② 分别为两个像素类的平均灰度值,即
③计算类间方差,并找出最大类间方差以及对应的阈值。
④ 求为最大值时的t,作为图像分割的最佳阈值T。
int otsu(IplImage* image)
{assert(NULL != image);int width = image->width;int height = image->height;int x = 0, y = 0;int pixelCount[256];float pixelPro[256];int i, j, pixelSum = width * height, threshold = 0;uchar* data = (uchar*)image->imageData;//初始化for (i = 0; i < 256; i++){pixelCount[i] = 0;pixelPro[i] = 0;}//统计灰度级中每个像素在整幅图像中的个数for (i = y; i < height; i++){for (j = x; j < width; j++){pixelCount[data[i * image->widthStep + j]]++;}}//计算每个像素在整幅图像中的比例for (i = 0; i < 256; i++){pixelPro[i] = (float)(pixelCount[i]) / (float)(pixelSum);}//经典ostu算法,得到前景和背景的分割//遍历灰度级[0,255],计算出方差最大的灰度值,为最佳阈值float w0, w1, u0tmp, u1tmp, u0, u1, u, deltaTmp, deltaMax = 0;for (i = 0; i < 256; i++){w0 = w1 = u0tmp = u1tmp = u0 = u1 = u = deltaTmp = 0;for (j = 0; j < 256; j++){if (j <= i) //背景部分{//以i为阈值分类,第一类总的概率w0 += pixelPro[j];u0tmp += j * pixelPro[j];}else //前景部分{//以i为阈值分类,第二类总的概率w1 += pixelPro[j];u1tmp += j * pixelPro[j];}}u0 = u0tmp / w0; //第一类的平均灰度u1 = u1tmp / w1; //第二类的平均灰度u = u0tmp + u1tmp; //整幅图像的平均灰度//计算类间方差deltaTmp = w0 * (u0 - u) * (u0 - u) + w1 * (u1 - u) * (u1 - u);//找出最大类间方差以及对应的阈值if (deltaTmp > deltaMax){deltaMax = deltaTmp;threshold = i;}}//返回最佳阈值;return threshold;
}
代码如下:(可直接运行使用)
https://download.csdn.net/download/chengxuyuanliwanwan/12601166