1 #include <iostream> 2 #include <opencv2/core.hpp> 3 #include <opencv2/highgui.hpp> 4 #include <opencv2/imgproc.hpp> 5 6 int Otsu(cv::Mat& src, cv::Mat& dst, int thresh){ 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 graynum[ptr[j]]++; 15 } 16 } 17 18 double P[Grayscale] = { 0 }; 19 double PK[Grayscale] = { 0 }; 20 double MK[Grayscale] = { 0 }; 21 double srcpixnum = r*c, sumtmpPK = 0, sumtmpMK = 0; 22 for (int i = 0; i < Grayscale; ++i){ 23 P[i] = graynum[i] / srcpixnum; //每个灰度级出现的概率 24 PK[i] = sumtmpPK + P[i]; //概率累计和 25 sumtmpPK = PK[i]; 26 MK[i] = sumtmpMK + i*P[i]; //灰度级的累加均值 27 sumtmpMK = MK[i]; 28 } 29 30 //计算类间方差 31 double Var=0; 32 for (int k = 0; k < Grayscale; ++k){ 33 if ((MK[Grayscale-1] * PK[k] - MK[k])*(MK[Grayscale-1] * PK[k] - MK[k]) / (PK[k] * (1 - PK[k])) > Var){ 34 Var = (MK[Grayscale-1] * PK[k] - MK[k])*(MK[Grayscale-1] * PK[k] - MK[k]) / (PK[k] * (1 - PK[k])); 35 thresh = k; 36 } 37 } 38 39 //阈值处理 40 src.copyTo(dst); 41 for (int i = 0; i < r; ++i){ 42 uchar* ptr = dst.ptr<uchar>(i); 43 for (int j = 0; j < c; ++j){ 44 if (ptr[j]> thresh) 45 ptr[j] = 255; 46 else 47 ptr[j] = 0; 48 } 49 } 50 return thresh; 51 } 52 53 54 int main(){ 55 cv::Mat src = cv::imread("E://lena.jpg"); 56 if (src.empty()){ 57 return -1; 58 } 59 if (src.channels() > 1) 60 cv::cvtColor(src, src, CV_RGB2GRAY); 61 62 cv::Mat dst,dst2; 63 int thresh=0; 64 double t2 = (double)cv::getTickCount(); 65 thresh=Otsu(src , dst, thresh); //Otsu 66 std::cout << "Mythresh=" << thresh << std::endl; 67 t2 = (double)cv::getTickCount() - t2; 68 double time2 = (t2 *1000.) / ((double)cv::getTickFrequency()); 69 std::cout << "my_process=" << time2 << " ms. " << std::endl << std::endl; 70 double Otsu = 0; 71 72 Otsu=cv::threshold(src, dst2, Otsu, 255, CV_THRESH_OTSU + CV_THRESH_BINARY); 73 std::cout << "OpenCVthresh=" << Otsu << std::endl; 74 75 cv::namedWindow("src", CV_WINDOW_NORMAL); 76 cv::imshow("src", src); 77 cv::namedWindow("dst", CV_WINDOW_NORMAL); 78 cv::imshow("dst", dst); 79 cv::namedWindow("dst2", CV_WINDOW_NORMAL); 80 cv::imshow("dst2", dst2); 81 82 cv::waitKey(0); 83 }