求阈值最佳方法

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 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 <cv.h>
2.#include <highgui.h>
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 <width;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.}。

相关文档
最新文档