参考数字图像处理(三) Pg 480
Otsu 方法的处理:选取合适的阈值k,使得类间方差最大P1*(m1-mg)*(m1-mg)+ P2*(m2-mg)*(m1-mg)最大
P1为像素分到C1的概率,即C1类像素占全部像素的比例,
P1为像素分到C2的概率,即C2类像素占全部像素的比例,
m1位C1类像素的平均灰度,计算公式 (0*n0 + 1*n1 +2*n2 ...k*nk ) / (n0 + n1 +n2 ...nk) 其中ni 表示灰度值为i像素的个数 。
代码如下:
<span style="font-size:18px;">//otsu 选取合适的阈值k,使得类间方差最大P1(m1-mg)平方 + P2(m2-mg)平方,k从0-255之间遍历,选取最合适的
//P1为像素分到C1的概率,即C1类像素占全部像素的比例,计算公式(n0 +n1 + n2 +...nk)/ (size总像素点数)。 m1位C1类像素的平均灰度,计算公式 (0*n0 + 1*n1 +2*n2 ...k*nk ) / (n0 + n1 +n2 ...nk) *****ni 表示各像素的个数 直方图
// mg为总的像素平均灰度值
int otsu_threshold( Mat gray)
{
int img_width ;
int img_height;
int size;
float P1 ,P2;
float m1=0, m2=0 , mg=0;
int k_otsu; //最终找到的阈值
float deltaTmp=0,deltaMax=0; //类间方差
int n0_k = 0; //即(n0 +n1 + n2 +...nk)
int nk_255 = 0;
int nk_X_k =0; // 表示(0*n0 + 1*n1 +2*n2 ...k*nk )
int nk_X_k2 =0; // 表示
int pixel_count[256]; //存储0-255每个像素的个数 即ni
img_width = gray.cols;
img_height = gray.rows;
size = img_width * img_height;
for(int i=0; i<256; i++)
{
pixel_count[i] = 0;
}
//归一化直方图,统计每个像素点个数 即pi
for(int i=0 ; i<img_height; i++)
{
for( int j= 0; j<img_width; j++)
{
pixel_count[ gray.at<unsigned char>(i,j)]++;
}
}
//计算mg , mg为总的像素平均灰度值
for (int i= 0; i<256; i++)
{
mg += pixel_count[i] *i;
}
mg = mg /size;
for (int k=1; k<256; k++) //类间方差统计 阈值k从0-255,筛选出最大方差的k
{
n0_k = 0;
nk_X_k = 0;
nk_X_k2 = 0;
for (int i=0; i<=k ; i++)
{
n0_k += pixel_count[i]; // P1 = n0_k / size
nk_X_k += pixel_count[i] *i; // m1 = nk_X_k / n0_k
}
for (int j=k+1; j<256; j++) //计算m2
{
nk_X_k2 += pixel_count[j]*j;
}
P1 = n0_k /(float) size;
m1 = nk_X_k / n0_k;
P2 = 1-P1;
m2 = nk_X_k2 / (float)(size - n0_k);
deltaTmp = P1*(m1-mg)*(m1-mg) + P2*(m2-mg)*(m2-mg); //类间方差
if(deltaTmp > deltaMax)
{
deltaMax = deltaTmp;
k_otsu = k;
}
}
return k_otsu;
}
int main()
{
Mat origin_img, gray, result;
int k;
origin_img = imread("C://Users/Administrator/Desktop/车牌/2.jpg");
cvtColor(origin_img,gray,CV_BGR2GRAY); //灰度化
k = otsu_threshold(gray);
threshold(gray,result,k,255,CV_THRESH_BINARY); //阈值化得到二值图
namedWindow("result",WINDOW_NORMAL );
imshow("result",result);
waitKey(0);
}</span>