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);
}
}
}
}
}