3.6.1直方图&最大熵分割

  1 ////////////////////////////////////////////////////////////////////////////////////
  2 ////源码来源于:https://blog.csdn.net/fanhongweifd/article/details/47305823
  3 ///////////////////////////////////////////////////////////////////////////////////
  4 #include <opencv2\opencv.hpp>
  5 #include<opencv2\imgproc\imgproc.hpp>
  6 #include <iostream>
  7 #include <string>
  8 #include <windows.h>
  9 //#include "Plate.h"
 10 #include <stdlib.h>
 11 #include <ctime>
 12 #define window_name "均衡化后直接二值化,呵呵"
 13 
 14 using namespace cv;
 15 using namespace std;
 16 
 17 //typedef enum { back, object } entropy_state;
 18 float total;
 19 //绘制hist;  
 20 Mat drawHist(Mat hist, int bins, int height, Scalar rgb)
 21 {
 22     double maxVal = 0;
 23     minMaxLoc(hist, 0, &maxVal, 0, 0);
 24     int scale = 1;
 25     Mat histImg = Mat::zeros(height, bins, CV_8UC3);
 26     float *binVal = hist.ptr<float>(0);
 27     for (int i = 0; i<bins; i++)
 28     {
 29         int intensity = cvRound(binVal[i] * height / maxVal);
 30         rectangle(histImg, Point(i*scale, 0),
 31             Point((i + 1)*scale, (intensity)), rgb, CV_FILLED);
 32     }
 33     //flip(histImg, histImg, 0);
 34     return histImg;
 35 }
 36 //计算直方图;  
 37 Mat Hist(const Mat& src)
 38 {
 39     Mat hist;
 40     int bins = 256;
 41     int histSize[] = { bins };
 42     float range[] = { 0,256 };
 43     const float* ranges[] = { range };
 44     int channels[] = { 0 };
 45     calcHist(&src, 1, channels, Mat(), hist, 1, histSize, ranges, true, false);
 46     Mat histImg = drawHist(hist, bins, 200, Scalar(255, 0, 0));
 47     imshow("histRGB", histImg);
 48     return hist;
 49 }
 50 //计算当前熵;  
 51 float calEntropy(const Mat& hist, int threshold)
 52 {
 53     float total_back = 0, total_object = 0;
 54     float entropy_back = 0, entropy_object = 0;
 55     float entropy = 0;
 56     int i = 0;
 57     const float* hist_p = (float*)hist.ptr<float>(0);
 58     total = 0;
 59     for (i = 0; i<hist.cols; i++)  //total是总的点数
 60     {
 61         total += hist_p[i];
 62     }
 63     for (i = 0; i<threshold; i++)
 64     {
 65         total_back += hist_p[i];
 66     }
 67     total_object = total - total_back;
 68 
 69     //背景熵;  
 70     for (i = 0; i<threshold; i++)
 71     {
 72         //      if(hist_p[i]==0)  
 73         //          continue;  
 74         float percentage = hist_p[i] / total_back;
 75         if (percentage >0)
 76         {
 77             entropy_back += -percentage * logf(percentage); // 能量的定义公式 
 78         }
 79     }
 80     //前景熵;  
 81     for (i = threshold; i<hist.cols; i++)
 82     {
 83         //      if(hist_p[i]==0)  
 84         //      {  
 85         //          continue;  
 86         //      }  
 87         float percentage = hist_p[i] / total_object;
 88         if (percentage >0)
 89         {
 90             entropy_object += -percentage * logf(percentage); // 能量的定义公式; 
 91         }
 92     }
 93 
 94     entropy = entropy_object + entropy_back;
 95     //entropy =entropy_object;  
 96     return entropy;
 97 }
 98 
 99 float LeftBackEntropy(const Mat& hist, int threshold)  //这个函数是测试随着阈值不断增加,左侧也就是背景熵的变化
100 {
101     float total_back = 0, total_object = 0;
102     float entropy_back = 0, entropy_object = 0;
103     float entropy = 0;
104     int i = 0;
105     const float* hist_p = (float*)hist.ptr<float>(0);
106     total = 0;
107     for (i = 0; i<hist.cols; i++)  //total是总的点数
108     {
109         total += hist_p[i];
110     }
111     for (i = 0; i<threshold; i++)
112     {
113         total_back += hist_p[i];
114     }
115     total_object = total - total_back;
116 
117     //背景熵;  
118     for (i = 0; i<threshold; i++)
119     {
120         //      if(hist_p[i]==0)  
121         //          continue;  
122         float percentage = hist_p[i] / total_back;
123         if (percentage >0)
124         {
125             entropy_back += -percentage * logf(percentage); // 能量的定义公式 
126         }
127     }
128 
129     entropy = entropy_back;
130     //entropy =entropy_object;  
131     return entropy;
132 }
133 
134 
135 
136 void MaxEntropy(Mat img, Mat hist)
137 {
138     total = sum(hist)[0];
139     float MaxEntropyValue = 0.0, MaxEntropyThreshold = 0.0;
140     float tmp;
141 
142 
143     cout << hist.size() << endl;
144 
145     for (int i = 0; i<hist.cols; i++)
146     {
147         tmp = calEntropy(hist, i);
148 
149         if (tmp>MaxEntropyValue)
150         {
151             MaxEntropyValue = tmp;
152             MaxEntropyThreshold = i;
153         }
154     }
155     threshold(img, img, MaxEntropyThreshold, 255, CV_THRESH_BINARY);
156     imshow("thresholdImg", img);
157     //imwrite("D:/thresholdImg.png",img);  
158     cout << MaxEntropyThreshold << endl;
159     cout << MaxEntropyValue << endl;
160 }
161 
162 void LeftEntropy(Mat img, Mat hist)   //这个函数是测试随着阈值不断增加,左侧也就是背景熵的变化
163 {
164 
165     total = sum(hist)[0];
166     float MaxEntropyValue = 0.0, MaxEntropyThreshold = 0.0;
167     float tmp;
168     Mat SingleHist(hist.size(), CV_32FC1);//测试左边图像的熵值
169 
170 
171     for (int i = 0; i<hist.cols; i++)
172     {
173         tmp = LeftBackEntropy(hist, i);
174         SingleHist.at<float>(0, i) = tmp;//这是测试左边图像的熵值
175 
176     }
177 
178     Mat histImg = drawHist(SingleHist, 256, 200, Scalar(255, 0, 0));
179     imshow("SingleHist", histImg);
180 
181 }
182 
183 int main(int argc, char *argv[])
184 {
185     //Mat img = imread("smallpicture.jpg");
186     //Mat src = imread("smallpicture.jpg", 0);
187     Mat src = imread("D:\\液晶屏数字.jpg", 0);
188     imshow("SRC", src);
189     Mat src_t = Hist(src);//(256, 1)
190     Mat hist = Hist(src).t();//(1, 256)
191     MaxEntropy(src, hist);
192     LeftEntropy(src, hist);
193     /*
194     cout<<hist.size()<<endl;
195     const float* hist_p = (float*) hist.ptr<float>(0);
196     int threshold=50;
197     float total_back=0,total_object=0;
198     float entropy_back=0,entropy_object=0;
199     float entropy = 0;
200     int i=0;
201     //const float* hist_p = (float*) hist.ptr<float>(0);
202     total=0;
203     for (i=0; i<hist.cols; i++)  //total是总的点数
204     {
205     total+=hist_p[i];
206     }
207     for (i=0; i<threshold; i++)
208     {
209     total_back += hist_p[i];
210     }
211     total_object=total-total_back;
212 
213     //背景熵;
214     for (i=0; i<threshold; i++)
215     {
216     //      if(hist_p[i]==0)
217     //          continue;
218     float percentage = hist_p[i]/total_back;
219     if(percentage>0)
220     {
221     entropy_back += -percentage * logf(percentage); // 能量的定义公式
222     }
223     }
224     //前景熵;
225     for (i=threshold; i<hist.cols; i++)
226     {
227     //      if(hist_p[i]==0)
228     //      {
229     //          continue;
230     //      }
231     float percentage = hist_p[i]/total_object;
232     if(percentage>0)
233     {
234     entropy_object += -percentage * logf(percentage); // 能量的定义公式;
235     }
236     }
237 
238     entropy = entropy_object+entropy_back;
239     float percentage = hist_p[0]/total_back;
240     if(percentage)
241     {
242     entropy_back = -percentage * logf(percentage); // 能量的定义公式
243     cout<<entropy_back<<endl;
244     }
245     cout<<total_object<<"  "<<total_back<<"  "<<total<<endl;
246     cout<<entropy<<endl;
247     /*
248     int i;
249     for(i=0;i<50;i++)
250     {
251     cout<<hist_p[i]<< "  ";
252     }
253     for(i=0;i++;i<50)
254     {
255     cout<<endl;
256     float sum=calEntropy(hist,50);
257     cout<<sum<<"  "<<endl;
258     }
259     */
260 
261 
262     waitKey();
263     return 1;
264 
265 }
View Code

运行效果:

posted @ 2018-08-08 16:40  BreakofDawn  阅读(452)  评论(0编辑  收藏  举报