1 #include <iostream>
2 #include <opencv2/core.hpp>
3 #include <opencv2/highgui.hpp>
4 #include <opencv2/imgproc.hpp>
5
6
7 int Max_Entropy(cv::Mat& src, cv::Mat& dst, int thresh, int p){
8 const int Grayscale = 256;
9 int Graynum[Grayscale] = { 0 };
10 int r = src.rows;
11 int c = src.cols;
12 for (int i = 0; i < r; ++i){
13 const uchar* ptr = src.ptr<uchar>(i);
14 for (int j = 0; j < c; ++j){
15 if (ptr[j] == 0) //排除掉黑色的像素点
16 continue;
17 Graynum[ptr[j]]++;
18 }
19 }
20
21 float probability = 0.0; //概率
22 float max_Entropy = 0.0; //最大熵
23 int totalpix = r*c;
24 for (int i = 0; i < Grayscale; ++i){
25
26 float HO = 0.0; //前景熵
27 float HB = 0.0; //背景熵
28
29 //计算前景像素数
30 int frontpix = 0;
31 for (int j = 0; j < i; ++j){
32 frontpix += Graynum[j];
33 }
34 //计算前景熵
35 for (int j = 0; j < i; ++j){
36 if (Graynum[j] != 0){
37 probability = (float)Graynum[j] / frontpix;
38 HO = HO + probability*log(1/probability);
39 }
40 }
41
42 //计算背景熵
43 for (int k = i; k < Grayscale; ++k){
44 if (Graynum[k] != 0){
45 probability = (float)Graynum[k] / (totalpix - frontpix);
46 HB = HB + probability*log(1/probability);
47 }
48 }
49
50 //计算最大熵
51 if(HO + HB > max_Entropy){
52 max_Entropy = HO + HB;
53 thresh = i + p;
54 }
55 }
56
57 //阈值处理
58 src.copyTo(dst);
59 for (int i = 0; i < r; ++i){
60 uchar* ptr = dst.ptr<uchar>(i);
61 for (int j = 0; j < c; ++j){
62 if (ptr[j]> thresh)
63 ptr[j] = 255;
64 else
65 ptr[j] = 0;
66 }
67 }
68 return thresh;
69 }
70
71
72 int main(){
73 cv::Mat src = cv::imread("E://lena.jpg");
74 if (src.empty()){
75 return -1;
76 }
77 if (src.channels() > 1)
78 cv::cvtColor(src, src, CV_RGB2GRAY);
79
80 cv::Mat dst, dst2;
81 int thresh = 0;
82 double t2 = (double)cv::getTickCount();
83 thresh = Max_Entropy(src, dst, thresh,10); //Max_Entropy
84 std::cout << "Mythresh=" << thresh << std::endl;
85 t2 = (double)cv::getTickCount() - t2;
86 double time2 = (t2 *1000.) / ((double)cv::getTickFrequency());
87 std::cout << "my_process=" << time2 << " ms. " << std::endl << std::endl;
88
89 double Otsu = 0;
90 Otsu = cv::threshold(src, dst2, Otsu, 255, CV_THRESH_OTSU + CV_THRESH_BINARY);
91 std::cout << "Otsuthresh=" << Otsu << std::endl;
92
93
94 cv::namedWindow("src", CV_WINDOW_NORMAL);
95 cv::imshow("src", src);
96 cv::namedWindow("dst", CV_WINDOW_NORMAL);
97 cv::imshow("dst", dst);
98 cv::namedWindow("dst2", CV_WINDOW_NORMAL);
99 cv::imshow("dst2", dst2);
100
101 cv::waitKey(0);
102 }

