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 }
运行效果: