主要讲解OTSU算法实现图像二值化:
1.统计灰度级图像中每个像素值的个数。
2.计算第一步个数占整个图像的比例。
3.计算每个阈值[0-255]条件下,背景和前景所包含像素值总个数和总概率(就是分别计算背景和前景下第一步和第二步的 和)。
4.比较第三步前景和背景之间方差,找到最大的一个确定为选定的阈值。
OTSU源码:
1 #include <opencv2/opencv.hpp>
2 #include <iostream>
3 #include <windows.h>
4
5 using namespace cv;
6 using namespace std;
7
8 int OTSU(Mat& src);
9 int main(int argc, char**argv)
10 {
11 Mat input_image;
12 input_image = imread("1.jpg");
13
14 if (input_image.data == NULL) {
15 return -1; cout << "can't open image.../";
16 }
17 cvtColor(input_image, input_image, CV_BGR2GRAY);
18 const int thre_num = OTSU(input_image);
19 const int height = input_image.rows;
20 const int width = input_image.cols;
21 for (size_t i = 0; i < height; i++)
22 {
23 for (size_t j = 0; j < width; j++)
24 {
25 input_image.at<uchar>(i, j) = input_image.at<uchar>(i, j) >= thre_num ? 0 : 255;
26 }
27 }
28 imshow("input_image2", input_image);
29 waitKey(0);
30 return 0;
31 }
32
33 int OTSU(Mat& src)
34 {
35 const int height = src.rows;
36 const int width = src.cols;
37 int nCountPix[256] = { 0 };//数量
38 int nProPix[256] = { 0 };//概率
39 //------------统计像素点个数------------//
40 for (size_t i = 0; i < height; i++)
41 {
42 for (size_t j = 0; j < width; j++)
43 {
44 nCountPix[src.at<uchar>(i, j)]++;
45 }
46 }
47 //-------统计每个像素个数占得比例------//
48 for (size_t i = 0; i < 256; i++)
49 {
50 nProPix[i] = nCountPix[i] / (height*width);
51 }
52 double var_max = 100;//设置一个参数,作为比较结果
53 int threashold = 0;
54 for (size_t i = 0; i < height; i++)
55 {
56 //----数量count、概率probility、平均概率average、方差variance----//
57 double c0 = 0, c1 = 0, p0 = 0, p1 = 0, a0 = 0, a1 = 0, var = 0;
58 for (size_t j = 0; j < width; j++)
59 {
60 //----前景和背景的计算
61 if (i < j)//背景
62 {
63 c0 += nCountPix[j];//总数量
64 p0 += nCountPix[j] * nProPix[j];//总概率
65 }
66 else//前景
67 {
68 c1 += nCountPix[j];//总数量
69 p1 += nCountPix[j] * nProPix[j];//总概率
70 }
71 }
72 a0 = p0 / c0;
73 a1 = p1 / c1;
74 var = static_cast<double>(c0*c1*pow((a0 - a1), 0));
75
76 if (var > var_max)
77 {
78 var_max = var;
79 threashold = i;
80 }
81 }
82 return threashold;
83 }
![](https://i-blog.csdnimg.cn/blog_migrate/9125c485d6e7e661ce78288f230dcd78.png)
![](https://i-blog.csdnimg.cn/blog_migrate/0f99df915f8b6a0b7e506d27885a2db9.png)