int myOtsu(Mat & src, double &maxVal)
{
int th;
int GrayScale = round(maxVal) + 1; //单通道图像总灰度maxVal+1级
int *pixCount = (int*)malloc(sizeof(int)*GrayScale);//每个灰度值所占像素个数
memset(pixCount, 0, sizeof(int)*GrayScale);
int pixSum = src.cols * src.rows;//图像总像素点
float *pixPro = (float*)malloc(sizeof(float)*GrayScale);//每个灰度值所占总像素比例
memset(pixPro, 0, sizeof(float)*GrayScale);
float w0, w1, u0tmp, u1tmp, u0, u1, deltaTmp, deltaMax = 0;
for (int i = 0; i < src.cols; i++)
{
for (int j = 0; j < src.rows; j++)
{
int integel = round(src.at<float>(j, i));
pixCount[integel]++;//统计每个灰度级中像素的个数
}
}
for (int i = 0; i < GrayScale; i++)
{
pixPro[i] = pixCount[i] * 1.0 / pixSum;//计算每个灰度级的像素数目占整幅图像的比例
}
for (int i = 0; i < GrayScale; i++)//遍历所有从0到GrayScale灰度级的阈值分割条件,测试哪一个的类间方差最大
{
w0 = w1 = u0tmp = u1tmp = u0 = u1 = deltaTmp = 0;
for (int j = 0; j < GrayScale; j++)
{
if (j <= i)//背景
{
w0 += pixPro[j];
u0tmp += j * pixPro[j];
}
else//前景
{
w1 += pixPro[j];
u1tmp += j * pixPro[j];
}
}
u0 = u0tmp / w0;
u1 = u1tmp / w1;
deltaTmp = (float)(w0 *w1* pow((u0 - u1), 2)); //类间方差公式 g = w1 * w2 * (u1 - u2) ^ 2
if (deltaTmp > deltaMax)
{
deltaMax = deltaTmp;
th = i;
}
}
free(pixCount);
free(pixPro);
return th;
}