求阈值最佳方法
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
OTSU算法是由日本学者OTSU于1979年提出的一种对图像进行二值化的高效算法。
1. OTSU算法原理简介
对于一幅图像,设当前景与背景的分割阈值为t时,前景点占图像比例为w0,均值为u0,背景点占图像比例为w1,均值为u1。则整个图像的均值为u = w0*u0+w1*u1。建立目标函数g(t)=w0*(u0-u)^2+w1*(u1-u)^2,g(t)就是当分割阈值为t时的类间方差表达式。OTSU算法使得g(t)取得全局最大值,当g(t)为最大时所对应的t称为最佳阈值。OTSU算法又称为最大类间方差法。
2.OTSU算法例程
下面是OSTU算法的C语言代码及其测试,代码基于opencv。
[cpp]view plaincopy
1.#include
2.#include
3.
4.int otsu(IplImage *image)
5.{
6. assert(NULL != image);
7.
8.int width = image->width;
9.int height = image->height;
10.int x=0,y=0;
11.int pixelCount[256];
12.float pixelPro[256];
13.int i, j, pixelSum = width * height, threshold = 0;
14.
15. uchar* data = (uchar*)image->imageData;
16.
17.//初始化
18.for(i = 0; i < 256; i++)
19. {
20. pixelCount[i] = 0;
21. pixelPro[i] = 0;
22. }
23.
24.//统计灰度级中每个像素在整幅图像中的个数
25.for(i = y; i < height; i++)
26. {
27.for(j = x;j 28. { 29. pixelCount[data[i * image->widthStep + j]]++; 30. } 31. } 32. 33. 34.//计算每个像素在整幅图像中的比例 35.for(i = 0; i < 256; i++) 36. { 37. pixelPro[i] = (float)(pixelCount[i]) / (float)(pixelSum); 38. } 39. 40.//经典ostu算法,得到前景和背景的分割 41.//遍历灰度级[0,255],计算出方差最大的灰度值,为最佳阈值 42.float w0, w1, u0tmp, u1tmp, u0, u1, u,deltaTmp, deltaMax = 0; 43.for(i = 0; i < 256; i++) 44. { 45. w0 = w1 = u0tmp = u1tmp = u0 = u1 = u = deltaTmp = 0; 46. 47.for(j = 0; j < 256; j++) 48. { 49.if(j <= i) //背景部分 50. { 51.//以i为阈值分类,第一类总的概率 52. w0 += pixelPro[j]; 53. u0tmp += j * pixelPro[j]; 54. } 55.else//前景部分 56. { 57.//以i为阈值分类,第二类总的概率 58. w1 += pixelPro[j]; 59. u1tmp += j * pixelPro[j]; 60. } 61. } 62. 63. u0 = u0tmp / w0; //第一类的平均灰度 64. u1 = u1tmp / w1; //第二类的平均灰度 65. u = u0tmp + u1tmp; //整幅图像的平均灰度 66.//计算类间方差 67. deltaTmp = w0 * (u0 - u)*(u0 - u) + w1 * (u1 - u)*(u1 - u); 68.//找出最大类间方差以及对应的阈值 69.if(deltaTmp > deltaMax) 70. { 71. deltaMax = deltaTmp; 72. threshold = i; 73. } 74. } 75.//返回最佳阈值; 76.return threshold; 77.} 78. 79.int main(int argc, char* argv[]) 80.{ 81. IplImage* srcImage = cvLoadImage("D:\\technology\\CV\\Database\\image\ \rice.png",0); 82. assert(NULL != srcImage); 83. 84. cvNamedWindow("src"); 85. cvShowImage("src",srcImage); 86. 87. IplImage* biImage = cvCreateImage(cvGetSize(srcImage),8,1); 88. 89.//计算最佳阈值 90.int threshold = otsu(srcImage); 91.//对图像二值化 92. cvThreshold(srcImage,biImage,threshold,255,CV_THRESH_BINARY); 93. 94. cvNamedWindow("binary"); 95. cvShowImage("binary",biImage); 96. 97. cvWaitKey(0); 98. 99. cvReleaseImage(&srcImage); 100. cvReleaseImage(&biImage); 101. cvDestroyWindow("src"); 102. cvDestroyWindow("binary"); 103. 104.return 0; 105.}