根據《面向飛機蒙皮接縫的線結構光檢測技術研究_張卡》論文中的原理,編寫了自適應閾值函數
原理:
1 //計算灰度最大最小值 2 void MaxGrayValue(Mat image,int &max,int &min) 3 { 4 max = 0; 5 min = 255; 6 Mat *im = reinterpret_cast<Mat*>((void*)&image); 7 int height = image.rows; 8 int width = image.cols; 9 int N = height * width; 10 //cout << "125" << " " << "125" << " " << static_cast<int>(im->at<uchar>(Point(182, 190))) << endl; 11 for (int i = 0; i < height; i++) 12 { 13 for (int j = 0; j < width; j++) 14 { 15 if ((static_cast<int>(im->at<uchar>(Point(j, i))))>max) 16 max = static_cast<int>(im->at<uchar>(Point(j, i))); 17 else if ((static_cast<int>(im->at<uchar>(Point(j, i))))<min) 18 min = static_cast<int>(im->at<uchar>(Point(j, i))); 19 } 20 } 21 }
1 //自適應閾值 注:傳入的只能是灰度圖像 2 void adapthreshold(Mat &image) 3 { 4 int max, min; //保存最大和最小灰度值 5 MaxGrayValue(image, max, min); //計算出最大最小灰度值 6 int grayvalue; //用於暫時存取每個點的灰度值 7 int Threshold = (max + min)/2; //初始閾值 8 int Temp_Threshold = Threshold; //用於存取每次迭代后的閾值 9 int big_than_th; //用於累加大於閾值的灰度值 10 int bigcount; //用於存放大於閾值灰度值的像素點數量 11 int sma_than_th; //用於累加小於閾值的灰度值 12 int smacount; //用於存放小於閾值灰度值的像素點數量 13 Mat *im = reinterpret_cast<Mat*>((void*)&image); //獲取像素點信息 14 //Mat *im = ℑ 15 int height = image.rows; //獲取圖像高度 16 int width = image.cols; //獲取圖像寬度 17 18 19 for (int k = 0; k < 50; k++) //計算閾值,最大迭代50次 20 { 21 big_than_th = 0; 22 bigcount = 0; 23 sma_than_th = 0; 24 smacount = 0; 25 for (int i = 0; i < height; i++) 26 { 27 for (int j = 0; j < width; j++) 28 { 29 grayvalue = static_cast<int>(im->at<uchar>(Point(j, i))); //獲取指定點灰度值 30 if (grayvalue>Threshold) //如果灰度值大於閾值,加到總灰度值,數量+1 31 { 32 big_than_th += grayvalue; 33 bigcount++; 34 } 35 else if (grayvalue < Threshold) //如果灰度值小於閾值,加到總灰度值,數量+1 36 { 37 sma_than_th += grayvalue; 38 smacount++; 39 } 40 } 41 } 42 Temp_Threshold = ((big_than_th*1.0 / bigcount) + (sma_than_th*1.0 / smacount)) / 2; //計算新的閾值 43 if (abs(Temp_Threshold - Threshold) < 2) //如果新的閾值和舊的閾值差值的絕對值小於10,則退出 44 break; 45 else 46 Threshold = Temp_Threshold; //否則舊閾值等於新閾值 47 } 48 for (int i = 0; i < height; i++) //對圖像進行二值化處理 49 { 50 uchar* data = image.ptr<uchar>(i); 51 for (int j = 0; j < width; j++) 52 { 53 grayvalue = static_cast<int>(im->at<uchar>(Point(j, i))); 54 if (grayvalue>Threshold) 55 data[j] = 255; 56 else if (grayvalue < Threshold) 57 data[j] = 0; 58 } 59 } 60 }