using OpenCvSharp; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace SmartCoalApplication.Base.CommTool { public class HistTools { /// /// 灰度图 /// /// public static float[] CalcHist(Mat gray) { float[] hist_int = new float[255]; Mat hist = new Mat(); //设置计算直方图的维度 int dims = 1; int[] histSize = { 255 }; Rangef[] pranges = new Rangef[1]; pranges[0] = new Rangef(0.0F, 256.0F); //计算直方图 Cv2.CalcHist(new Mat[1] { gray }, new int[] { 0 }, new Mat(), hist, dims, histSize, pranges); //创建数据,便于计算 for (int w = 0; w < hist.Height; w++) { hist_int[w] = hist.At(0, w); } return hist_int; } /// /// 直方图平滑 /// /// /// /// public static int[] Smooth(float[] arr, int step, int num=256) { int start = step - step / 2; int end = num - step / 2; double temp = 0; int[] res = new int[num]; for (int i = start; i < end; i++) { temp = 0; for (int j = 0 - step / 2; j < step / 2; j++) { temp += arr[i + j]; } temp /= step; res[i] = (int)temp; } return res; } /// /// 寻找峰 /// /// /// /// /// /// /// /// /// public static void FindTopAndBetweenWithOutWT123(int[] hists_new, int leftValue, int rightValue, List mountainsList, List mountainsArrList, List mountainsArrListBackUp, List str, int smoothStep) { //获得去除左右值的最高波峰 int topValue = leftValue; for (int y = leftValue; y < rightValue; y++) { if (hists_new[y] > hists_new[topValue]) { topValue = y; } } if (topValue == 0 || topValue == leftValue || topValue == rightValue) return; mountainsList.Add(topValue); //获得波峰左右的波谷 int leftTrough = topValue; int leftTroughBackUp = 0; //从波峰点向左侧找波谷点 for (int y = topValue - 1; y > leftValue; y--) { if (hists_new[y] >= 0 && hists_new[y] <= hists_new[leftTrough]) { leftTrough = y; } else { break; } } //微调 //if (smoothStep >= 30) { for (int y = leftTrough + 1; y < topValue; y++) { if (hists_new[y] == hists_new[leftTrough])// || hists_new[y] < hists_new[topValue] / 10 { leftTroughBackUp = y; } } } if (leftTroughBackUp == 0) leftTroughBackUp = leftTrough; int rightTrough = topValue; int rightTroughBackUp = 0; //从波峰点向右侧找波谷点 for (int y = topValue + 1; y < rightValue; y++) { if (hists_new[y] >= 0 && hists_new[y] <= hists_new[rightTrough]) { rightTrough = y; } else { break; } } //微调 //if (smoothStep >= 30) { for (int y = rightTrough - 1; y > topValue; y--) { if (hists_new[y] == hists_new[rightTrough])// || hists_new[y] < hists_new[topValue] / 10 { rightTroughBackUp = y; } } } if (rightTroughBackUp == 0) rightTroughBackUp = rightTrough; int[] arr = new int[2]; arr[0] = leftTroughBackUp; arr[1] = rightTroughBackUp; mountainsArrList.Add(arr); int[] arr1 = new int[2]; arr1[0] = leftTroughBackUp > 0 ? leftTroughBackUp : leftTrough; arr1[1] = rightTroughBackUp > 0 ? rightTroughBackUp : rightTrough; mountainsArrListBackUp.Add(arr1); if (leftValue < leftTrough - 1) { if (!str.Contains(leftValue + "|" + leftTrough)) { str.Add(leftValue + "|" + leftTrough); FindTopAndBetweenWithOutWT123(hists_new, leftValue, leftTrough, mountainsList, mountainsArrList, mountainsArrListBackUp, str, smoothStep); } } if (rightValue > rightTrough + 1) { if (!str.Contains(rightValue + "|" + rightTrough)) { str.Add(rightValue + "|" + rightTrough); FindTopAndBetweenWithOutWT123(hists_new, rightTrough, rightValue, mountainsList, mountainsArrList, mountainsArrListBackUp, str, smoothStep); } } } } }