前言
无
一、OTSU算法是什么?
OTSU算法又名最大类间方差法,是由日本学者大津展之于1979 年提出,利用整副图像的直方图特性,选择全局阈值T。文字图片和背景通常会出现两个驼峰,确定一个灰度值作为阈值,将灰度值小于阈值的点作为目标,大于等于阈值的点作为背景。遍历整副图像灰度值,选择类间方差最大时对应的灰度值作为阈值,OTSU算法为目前比较好的确定阈值的算法。
二、算法详解
该博文由该算法的原理:
OpenCV — Otsu 算法_FlyDremever的博客-CSDN博客_opencv otsu
2.算法实现
代码如下(示例):
//算法实现步骤
//Step1 计算灰度图像的全局期望
//Step2 遍历灰度值从0到255将灰度图像分为前景与背景
//Step2.1 求前景的期望与概率
//Step2.2 求背景的期望与概率
//Step2.3 由间类方差定义求当前阈值的间类方差
//遍历过程中,不断比较求得最大的间类方差
int thresh_otsu(Mat input)
{
int histogram[256] = { 0 };//计算各灰度级的像素数目
double global_mean = 0;//全局期望
int imgSize = input.size().area();//图像的大小
//遍历图像
for (int i = 0; i < input.rows; i++)
{
uchar *data = input.ptr<uchar>(i);//当前行地址
for (int j = 0; j < input.cols; j++)//遍历当前行
{
histogram[data[j]]++;//当前灰度级为data[j]的数值
global_mean += data[j];//统计整幅图像的像素值之和
}
}
//期望(平均) = 总和 / 个数
global_mean /= imgSize;//统计完后根据均值定义求得图像的均值
double p1 = 0, p2 = 0, m1 = 0, m2 = 0;
//p1 m1 分别为背景的概率与背景的期望
//p2 m2 分别为前景的概率与前景的期望
double sg = 0;//间类方差
double temp_sg = -1;//用于交换的变量
int k = 0;
//遍历i求当前阈值i得到的间类方差,找到间类方差最大值对应的阈值i
for (int i = 0; i < 256; i++)
{
//小于阈值i为前景(目标)
for (int j = 0; j <= i; j++)
{
p2 += histogram[j];//统计前景的像素值 个数 总和 即小于阈值i的像素点个数之和
m2 += (histogram[j] * j);//统计前景的像素值 总和 即小于阈值i的像素值之和
}
m2 = m2 / p2;//由期望公式得到期望 (前景)
//大于阈值i为背景
for (int j = i + 1; j < 256; j++)
{
p1 += histogram[j];
m1 += (histogram[j] * j);
}
m1 /= p1;//由期望公式得到期望 (背景)
p2 /= imgSize;//求前景的概率 = 前景像素点个数 / 图像总像素个数
p1 = 1 - p2;//求背景的概率
sg = p1 * p2*(m1 - m2)*(m1 - m2); //计算当前阈值i的类间方差
//找出 阈值i分割的前景与背景的最大间类方差
if (sg > temp_sg)
{
temp_sg = sg;
k = i;
}
p1 = 0, p2 = 0, m1 = 0, m2 = 0;//求完后这些数据要重置为0 计算新的阈值的相应的数据
}
//cout<<"k = "<<k<<endl;
return k;
}
总结
无