int Otsu2_accel(cv::Mat _src, int _width, int _height)
{
int pixelCount[256] = { 0 };
float pixelPro[256] = { 0 };
// 统计灰度级中每个像素在整幅图像中的个数
for (int y = 0; y < _height; y++)
{
int offset = y * _width;
const unsigned char* src = _src.data + _src.step * y;
for (int x = 0; x < _width; x++)
{
int value = src[x];
CUTOFF(value, 0, 255);
pixelCount[value]++;
}
}
float sum_u = 0;
// 计算每个像素在整幅图像中的比例
for (int i = 0; i < 256; i++)
{
pixelPro[i] = (float)pixelCount[i] / (float)(_width * _height);
sum_u = sum_u + pixelPro[i] * i;
}
// 经典ostu算法,得到前景和背景的分割
// 遍历灰度级[0, 255],计算出方差最大的灰度值,为最佳阈值
float deltaMax = 0.0f;
int threshold = 0;
float w0 = 0.0f;
float u0tmp = 0.0f;
float w1 = 0.0f;
float u1tmp = 0.0f;
for (int i = 0; i < 256; i++)
{
// 背景部分
// 以i为阈值分类,第一类总的概率
w0 += pixelPro[i];
u0tmp += i * pixelPro[i];
//float u0 = u0tmp / w0; // 第一类的平均灰度
//float u1 = u1tmp / w1; // 第二类的平均灰度
//float u = u0tmp + u1tmp; // 整幅图像的平均灰度
//计算类间方差
float deltaTmp = (w0*sum_u-u0tmp)*(w0*sum_u - u0tmp)*1.0/(w0*(1-w0));
//找出最大类间方差以及对应的阈值
if (i == 255)
{
printf("aaa");
}
if (deltaTmp > deltaMax)
{
deltaMax = deltaTmp;
threshold = i;
}
}
return threshold;
}