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