Otsu及变种
Otsu基本上最简单的分割了,原理很简单,就是将像素分类,找到使类间方差最大的阈值。就和机器学习中聚类思想一致。
其变种就是多阈值处理,和基于局部的阈值。
过程总结如下:
代码如下:
1 int Otsu_local(Mat src) 2 { 3 int hist[256] = { 0 }; 4 int IMGH = src.rows; 5 int IMGW = src.cols; 6 7 for (int i = 0; i < IMGH; i++) 8 { 9 for (int j = 0; j < IMGW; j++) 10 { 11 hist[int(src.at<uchar>(i,j))]++; 12 } 13 } 14 float w0 ; 15 float w1 ; 16 float u0 ; 17 float u1 ; 18 float maxvar = 0; 19 int T; 20 for (int k = 0; k < 256; k++) 21 { 22 w0 = 0; 23 w1 = 0; 24 u0 = 0; 25 u1 = 0; 26 for (int i = 0; i < k; i++) 27 { 28 w0 += hist[i]; 29 u0 += i*hist[i]; 30 } 31 for (int j = k; j < 256; j++) 32 { 33 w1 += hist[j]; 34 u1 += j*hist[j]; 35 } 36 37 w0 /= (IMGW*IMGH); 38 w1 /= (IMGW*IMGH); 39 u0 /= w0; 40 u1 /= w1; 41 42 float var = w0*w1*(u1 - u0)*(u1 - u0); 43 if (var > maxvar){ 44 maxvar = var; 45 T = k; 46 } 47 48 } 49 return T; 50 51 }
使用opencv自带的算法做验证,结果一致
1 int n=threshold(gray, temp, 0, 255, CV_THRESH_OTSU);