本博文直接给出实现的代码
即Mat元素连续求极大极小值
/////////////////////////////////////////方法二:EVA algorithm///////////////////////////////////////////////
double minVal, maxVal;//最大与最小的像素
int minIdx[2] = {}, maxIdx[2] = {}; //对应的坐标
minMaxIdx(msgDate_resize, &minVal, &maxVal, minIdx, maxIdx);//https://blog.csdn.net/qq_29796317/article/details/73136083
//https://blog.csdn.net/fangyan90617/article/details/100540020
std::cout << "最大像素= "<< maxVal <<std::endl;
std::cout << "最大像素坐标= "<< maxIdx[0] <<std::endl;//由于是一个一维的矩阵,经测试,0为索引
std::cout << "最大像素123= "<< in_point[maxIdx[0]].y <<std::endl;//in_point为(x,y)x就是第几个像素,y就是对应像素值
std::vector<Point> local_maxmin_threshold {};//(x,y)x就是第几个像素,y就是对应像的阈值
int Flag_minmax=2;////用于奇偶判断
double maxminVal=maxVal;
int next_point=0;
//先向右寻找
for (int i=maxIdx[0];i<=msgDate_resize.rows;i=i+(next_point-maxIdx[0]))//由于是极值点下一个开始寻找
{
double value=0;//存放下一个极小值
double average_gobal_maxmin;//存放阈值
if (Flag_minmax % 2 == 0)//若为偶数,则执行下面,求############极小值##############
{
for (int n=2;i+(n+1)*9<=msgDate_resize.rows;n++)
{
double minVal1, maxVal1;//最大与最小的像素
double minVal2, maxVal2;//最大与最小的像素
int minIdx1[2] = {}, maxIdx1[2] = {}; //对应的坐标
int minIdx2[2] = {}, maxIdx2[2] = {}; //对应的坐标
Mat maxmin_ROI1=msgDate_resize(Rect(0, i+9, 1, (n-1)*9));
Mat maxmin_ROI2=msgDate_resize(Rect(0, i+9, 1, n*9));
minMaxIdx(maxmin_ROI1, &minVal1, &maxVal1, minIdx1, maxIdx1);
minMaxIdx(maxmin_ROI2, &minVal2, &maxVal2, minIdx2, maxIdx2);
if (in_point[minIdx1[0]].x== in_point[minIdx2[0]].x)//如果第二个区域与第一个区域的最小值是同一个点,则(i+9, (n-1)*9)区域找到最小值
{
value=in_point[minIdx1[0]].y;//当前值为最小值,将其赋予value
average_gobal_maxmin=(maxminVal+value)/2;
for (int j=i;j<=i+(n-1)*9;j++)
{
local_maxmin_threshold.push_back(Point(j,average_gobal_maxmin));
}
Flag_minmax++;//用于奇偶判断,此循环是偶数才进行,加了后变成奇数,进入求极大值的循环
next_point=minIdx1[0];
break;//跳出当前循环 break语句对if-else的条件语句不起作用。只跳出for
}//否则,即当前(i+9, n*9)区域的为最小值。n++,下一个区域计算,与当前区域比较
if (i+(n+1)*9==msgDate_resize.rows)//假如一直都是下一个区域是最小值,那么这个循环可以一直运行到最后,而在最后的时候,条件满足,进入当前条件语句。那么最后一个也可以保留出来
{
value=in_point[minIdx2[0]].y;//当前值为最小值,将其赋予value
average_gobal_maxmin=(maxminVal+value)/2;
for (int j=i;j<=i+n*9;j++)
{
local_maxmin_threshold.push_back(Point(j,average_gobal_maxmin));
}
next_point=minIdx2[0];
}
}
maxminVal=value;//求完极小值,将当前的极小值赋值,用于求下一个极大值
//加判断语句看是否已经到达边缘
if (i+(next_point-maxIdx[0])+2*9>=msgDate_resize.rows)//当前的点是否已经不支持下一次判决,一判决就会溢出
{
break;//跳出循环
}
continue; //结束当前循环,进入下一次
}
else //若为奇数,则执行下面,求#########极大值############
{
for (int n=2;i+(n+1)*9<=msgDate_resize.rows;n++)
{
double minVal1, maxVal1;//最大与最小的像素
double minVal2, maxVal2;//最大与最小的像素
int minIdx1[2] = {}, maxIdx1[2] = {}; //对应的坐标
int minIdx2[2] = {}, maxIdx2[2] = {}; //对应的坐标
Mat maxmin_ROI1=msgDate_resize(Rect(0, i+9, 1, (n-1)*9));
Mat maxmin_ROI2=msgDate_resize(Rect(0, i+9, 1, n*9));
minMaxIdx(maxmin_ROI1, &minVal1, &maxVal1, minIdx1, maxIdx1);
minMaxIdx(maxmin_ROI2, &minVal2, &maxVal2, minIdx2, maxIdx2);
if (in_point[maxIdx1[0]].x== in_point[maxIdx2[0]].x)//如果第二个区域与第一个区域的最大值是同一个点,则(i+9, (n-1)*9)区域找到最大值
{
value=in_point[maxIdx1[0]].y;//(i+9, (n-1)*9)区域的值为最大值,将其赋予value
average_gobal_maxmin=(maxminVal+value)/2;
for (int j=i;j<=i+(n-1)*9;j++)
{
local_maxmin_threshold.push_back(Point(j,average_gobal_maxmin));
}
Flag_minmax++;//用于奇偶判断,此循环是偶数才进行,加了后变成奇数,进入求极大值的循环
next_point=minIdx1[0];
break;//跳出当前循环 break语句对if-else的条件语句不起作用。只跳出for
}//否则,即当前(i+9, n*9)区域的为最大值。n++,下一个区域计算,与当前区域比较
if (i+(n+1)*9==msgDate_resize.rows)//假如一直都是下一个区域是最大值,那么这个循环可以一直运行到最后,而在最后的时候,条件满足,进入当前条件语句。那么最后一个也可以保留出来
{
value=in_point[maxIdx2[0]].y;//当前值为最大值,将其赋予value
average_gobal_maxmin=(maxminVal+value)/2;
for (int j=i;j<=i+n*9;j++)
{
local_maxmin_threshold.push_back(Point(j,average_gobal_maxmin));
}
next_point=minIdx2[0];
}
}
maxminVal=value;//求完极小值,将当前的极小值赋值,用于求下一个极大值
//加判断语句看是否已经到达边缘
if (i+(next_point-maxIdx[0])+2*9>=msgDate_resize.rows)//当前的点是否已经不支持下一次判决,一判决就会溢出
{
break;//跳出循环
}
continue; //结束当前循环,进入下一次
}
}
//再向左寻找
//标志位重新赋值
Flag_minmax=2;////用于奇偶判断
maxminVal=maxVal;
next_point=0;
for (int i=maxIdx[0];i>=0;i=i-(maxIdx[0]-next_point))//由于是极值点下一个开始寻找
{
double value=0;//存放下一个极小值
double average_gobal_maxmin;//存放阈值
if (Flag_minmax % 2 == 0)//若为偶数,则执行下面,求############极小值##############
{
for (int n=2;i-(n+1)*9>=0;n++)
{
double minVal1, maxVal1;//最大与最小的像素
double minVal2, maxVal2;//最大与最小的像素
int minIdx1[2] = {}, maxIdx1[2] = {}; //对应的坐标
int minIdx2[2] = {}, maxIdx2[2] = {}; //对应的坐标
Mat maxmin_ROI1=msgDate_resize(Rect(0, i-n*9, 1, (n-1)*9));
Mat maxmin_ROI2=msgDate_resize(Rect(0, i-(n+1)*9, 1, n*9));
minMaxIdx(maxmin_ROI1, &minVal1, &maxVal1, minIdx1, maxIdx1);
minMaxIdx(maxmin_ROI2, &minVal2, &maxVal2, minIdx2, maxIdx2);
if (in_point[minIdx1[0]].x== in_point[minIdx2[0]].x)//如果第二个区域与第一个区域的最小值是同一个点,则(i+9, (n-1)*9)区域找到最小值
{
value=in_point[minIdx1[0]].y;//当前值为最小值,将其赋予value
average_gobal_maxmin=(maxminVal+value)/2;
for (int j=i;j>=i-(n-1)*9;j--)
{
local_maxmin_threshold.push_back(Point(j,average_gobal_maxmin));
}
Flag_minmax++;//用于奇偶判断,此循环是偶数才进行,加了后变成奇数,进入求极大值的循环
next_point=minIdx1[0];
break;//跳出当前循环 break语句对if-else的条件语句不起作用。只跳出for
}//否则,即当前(i+9, n*9)区域的为最小值。n++,下一个区域计算,与当前区域比较
if (i-(n+1)*9==0)//假如一直都是下一个区域是最小值,那么这个循环可以一直运行到最后,而在最后的时候,条件满足,进入当前条件语句。那么最后一个也可以保留出来
{
value=in_point[minIdx2[0]].y;//当前值为最小值,将其赋予value
average_gobal_maxmin=(maxminVal+value)/2;
for (int j=i;j<=i+n*9;j++)
{
local_maxmin_threshold.push_back(Point(j,average_gobal_maxmin));
}
next_point=minIdx2[0];
}
}
maxminVal=value;//求完极小值,将当前的极小值赋值,用于求下一个极大值
//加判断语句看是否已经到达边缘
if (i-(maxIdx[0]-next_point)-2*9<=0)//当前的点是否已经不支持下一次判决,一判决就会溢出
{
break;//跳出循环
}
continue; //结束当前循环,进入下一次
}
else //若为奇数,则执行下面,求#########极大值############
{
for (int n=2;i-(n+1)*9>=0;n++)
{
double minVal1, maxVal1;//最大与最小的像素
double minVal2, maxVal2;//最大与最小的像素
int minIdx1[2] = {}, maxIdx1[2] = {}; //对应的坐标
int minIdx2[2] = {}, maxIdx2[2] = {}; //对应的坐标
Mat maxmin_ROI1=msgDate_resize(Rect(0, i-n*9, 1, (n-1)*9));
Mat maxmin_ROI2=msgDate_resize(Rect(0, i-(n+1)*9, 1, n*9));
minMaxIdx(maxmin_ROI1, &minVal1, &maxVal1, minIdx1, maxIdx1);
minMaxIdx(maxmin_ROI2, &minVal2, &maxVal2, minIdx2, maxIdx2);
if (in_point[maxIdx1[0]].x== in_point[maxIdx2[0]].x)//如果第二个区域与第一个区域的最大值是同一个点,则(i+9, (n-1)*9)区域找到最大值
{
value=in_point[maxIdx1[0]].y;//(i+9, (n-1)*9)区域的值为最大值,将其赋予value
average_gobal_maxmin=(maxminVal+value)/2;
for (int j=i;j>=i-(n-1)*9;j--)
{
local_maxmin_threshold.push_back(Point(j,average_gobal_maxmin));
}
Flag_minmax++;//用于奇偶判断,此循环是偶数才进行,加了后变成奇数,进入求极大值的循环
next_point=minIdx1[0];
break;//跳出当前循环 break语句对if-else的条件语句不起作用。只跳出for
}//否则,即当前(i+9, n*9)区域的为最大值。n++,下一个区域计算,与当前区域比较
if (i-(n+1)*9==0)//假如一直都是下一个区域是最大值,那么这个循环可以一直运行到最后,而在最后的时候,条件满足,进入当前条件语句。那么最后一个也可以保留出来
{
value=in_point[maxIdx2[0]].y;//当前值为最大值,将其赋予value
average_gobal_maxmin=(maxminVal+value)/2;
for (int j=i;j<=i+n*9;j++)
{
local_maxmin_threshold.push_back(Point(j,average_gobal_maxmin));
}
next_point=minIdx2[0];
}
}
maxminVal=value;//求完极小值,将当前的极小值赋值,用于求下一个极大值
//加判断语句看是否已经到达边缘
if (i-(maxIdx[0]-next_point)-2*9<=0)//当前的点是否已经不支持下一次判决,一判决就会溢出
{
break;//跳出循环
}
continue; //结束当前循环,进入下一次
}
}
/////////////////////////////////////////方法二:EVA algorithm///////////////////////////////////////////////