基于opencv的EA algorithm实现

本博文直接给出实现的代码

即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/// 

改进版本:

方法二: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::cout << "size:" << msgDate_resize.size() << std::endl;
    // // std::cout << "row:" << msgDate_resize.rows << std::endl;
    // // std::cout << "col:" << msgDate_resize.cols << std::endl;
    // std::cout << "一共的像素数目= "<< msgDate_resize.rows <<std::endl;

    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)//由于是极值点下一个开始寻找
    {
        double value=0;//存放下一个极小值
        double average_gobal_maxmin;//存放阈值
        // cout<<"i="<<i<<endl;
        // cout<<"next_point="<<next_point<<endl;
        // cout<<"Flag_minmax="<<Flag_minmax<<endl;
        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));// Rect_(_Tp _x, _Tp _y, _Tp _width, _Tp _height);
                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*9;j++)//对比的时候是从(i+9,i+n*9)这个区域找,但实际上,是从i区域开始赋值到i+n*9
                    {
                        local_maxmin_threshold.push_back(Point(j,average_gobal_maxmin));
                    }
                    Flag_minmax++;//用于奇偶判断,此循环是偶数才进行,加了后变成奇数,进入求极大值的循环
                    next_point=minIdx1[0]+9;minIdx1[0]为(i+9, (n-1)*9)的最小值坐标。
                    // cout<<"求了一次极小值"<<endl;
                    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<=msgDate_resize.rows;j++)
                    {
                        local_maxmin_threshold.push_back(Point(j,average_gobal_maxmin));
                    }
                    next_point=minIdx2[0]+9;//minIdx2[0]为(i+9, (n)*9)的坐标。
                }
            }  
            maxminVal=value;//求完极小值,将当前的极小值赋值,用于求下一个极大值
            //加判断语句看是否已经到达边缘
            if (i+next_point>=msgDate_resize.rows)//当前的点是否已经不支持下一次判决,一判决就会溢出。那么就将当前的阈值赋上
            {
                for (int j=i;j<=msgDate_resize.rows;j++)
                    {
                        local_maxmin_threshold.push_back(Point(j,average_gobal_maxmin));
                    }
                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*9;j++)//对比的时候是从(i+9,i+n*9)这个区域找,但实际上,是从i区域开始赋值到i+n*9
                    {
                        local_maxmin_threshold.push_back(Point(j,average_gobal_maxmin));
                    }
                    Flag_minmax++;//用于奇偶判断,此循环是偶数才进行,加了后变成奇数,进入求极大值的循环
                    next_point=maxIdx1[0]+9;//maxIdx1[0]为(i+9, (n-1)*9)的坐标。
                    // cout<<"求了一次极大值"<<endl;
                    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<=msgDate_resize.rows;j++)
                    {
                        local_maxmin_threshold.push_back(Point(j,average_gobal_maxmin));
                    }
                    next_point=maxIdx2[0]+9;//maxIdx2[0]为(i+9, (n)*9)的坐标。
                }
            }  
            maxminVal=value;//求完极小值,将当前的极小值赋值,用于求下一个极大值
            //加判断语句看是否已经到达边缘
            if (i+next_point>=msgDate_resize.rows)//当前的点是否已经不支持下一次判决,一判决就会溢出.那么就将当前的阈值赋上
            {
                for (int j=i;j<=msgDate_resize.rows;j++)
                    {
                        local_maxmin_threshold.push_back(Point(j,average_gobal_maxmin));
                    }
                break;//跳出循环
            }
            continue; //结束当前循环,进入下一次  
        }
    }
    cout<<"#####################################"<<endl;
    //再向左寻找#############################################################################################################
    //标志位重新赋值
    Flag_minmax=2;用于奇偶判断
    maxminVal=maxVal;
    next_point=0;
    for (int i=maxIdx[0];i>=0;i=i-next_point)//由于是极值点下一个开始寻找
    {
        double value=0;//存放下一个极小值
        double average_gobal_maxmin;//存放阈值
        cout<<"i="<<i<<endl;
        cout<<"next_point="<<next_point<<endl;
        cout<<"Flag_minmax="<<Flag_minmax<<endl;
        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.insert(local_maxmin_threshold.begin(),Point(j,average_gobal_maxmin));
                        //向前插入https://blog.csdn.net/qq_40788950/article/details/82714495
                    }
                    // cout<<"计算极小值"<<endl;
                    // cout<<"minIdx1[0]="<<minIdx1[0]<<endl;
                    // cout<<"(n-1)="<<(n-1)<<endl;
                    // cout<<"value="<<value<<endl;
                    // cout<<"minVal1="<<minVal1<<endl;
                    // cout<<"maxVal1="<<maxVal1<<endl;
                    // cout<<"maxminVal="<<maxminVal<<endl;
                    Flag_minmax++;//用于奇偶判断,此循环是偶数才进行,加了后变成奇数,进入求极大值的循环
                    next_point=(n-1)*9-minIdx1[0]+9;
                    // cout<<"计算极小值next_point"<<next_point<<endl;
                    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.insert(local_maxmin_threshold.begin(),Point(j,average_gobal_maxmin));
                    }
                    next_point=n*9-minIdx2[0]+9;
                }
            }  
            maxminVal=value;//求完极小值,将当前的极小值赋值,用于求下一个极大值
            //加判断语句看是否已经到达边缘
            if (i-next_point<=0)//当前的点是否已经不支持下一次判决,一判决就会溢出
            {
                for (int j=i;j>=0;j--)
                    {
                        local_maxmin_threshold.insert(local_maxmin_threshold.begin(),Point(j,average_gobal_maxmin));
                    }
                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.insert(local_maxmin_threshold.begin(),Point(j,average_gobal_maxmin));
                    }
                    Flag_minmax++;//用于奇偶判断,此循环是偶数才进行,加了后变成奇数,进入求极大值的循环
                    cout<<"计算极小值"<<endl;
                    next_point=(n-1)*9-maxIdx1[0]+9;
                    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.insert(local_maxmin_threshold.begin(),Point(j,average_gobal_maxmin));
                    }
                    next_point=maxIdx2[0];
                }
            }  
            maxminVal=value;//求完极小值,将当前的极小值赋值,用于求下一个极大值
            //加判断语句看是否已经到达边缘
            if (i-next_point<=0)//当前的点是否已经不支持下一次判决,一判决就会溢出
            {
                for (int j=i;j>=0;j--)
                    {
                        local_maxmin_threshold.insert(local_maxmin_threshold.begin(),Point(j,average_gobal_maxmin));
                    }
                break;//跳出循环
            }
            continue; //结束当前循环,进入下一次  
        }
    }
    cout<<local_maxmin_threshold<<endl;

/方法二:EVA algorithm/// 

结论:

虽然这个算法应该是没有什么问题,但是如果通过minMaxIdx来寻找局部的极值点是有问题的。因为minMaxIdx是找到局部区域的最大与最小

当前区域的最小点,就已经是极小值点了!

更正版本

/方法二: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::cout << "size:" << msgDate_resize.size() << std::endl;
    // // std::cout << "row:" << msgDate_resize.rows << std::endl;
    // // std::cout << "col:" << msgDate_resize.cols << std::endl;
    // std::cout << "一共的像素数目= "<< msgDate_resize.rows <<std::endl;

    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)//由于是极值点下一个开始寻找
    {
        double value=0;//存放下一个极小值
        double average_gobal_maxmin;//存放阈值(每次更新)
        // cout<<"i="<<i<<endl;
        // cout<<"next_point="<<next_point<<endl;
        // cout<<"Flag_minmax="<<Flag_minmax<<endl;
        if (Flag_minmax % 2 == 0)//若为偶数,则执行下面,求############极小值##############
        {
            double minVal1, maxVal1;//最大与最小的像素
            int minIdx1[2] = {}, maxIdx1[2] = {};	//对应的坐标。由于是向量,以0为索引就好了
            Mat maxmin_ROI=msgDate_resize(Rect(0, i+9, 1, 9));// Rect_(_Tp _x, _Tp _y, _Tp _width, _Tp _height);
            minMaxIdx(maxmin_ROI, &minVal1, &maxVal1, minIdx1, maxIdx1);//寻找这个区域内的最大与最小值
            value=in_point[minIdx1[0]].y;//当前值为最小值,将其赋予value
            average_gobal_maxmin=(maxminVal+value)/2;
            next_point=minIdx1[0]+9;minIdx1[0]为(i+9, i+2*9)这个区域的最小值坐标。
            for (int j=i;j<=i+next_point;j++)//对比的时候是从(i+9,i+2*9)这个区域找,但实际上,是上一个极值到当前的极值的位置
            {
                local_maxmin_threshold.push_back(Point(j,average_gobal_maxmin));
            }
            Flag_minmax++;//用于奇偶判断,此循环是偶数才进行,加了后变成奇数,进入求极大值的循环
            // cout<<"计算极小值"<<endl;
            // cout<<"对应的极大值"<<maxminVal<<endl;
            // cout<<"value="<<value<<endl;
            // cout<<"平均"<<average_gobal_maxmin<<endl;
            // cout<<minIdx1[0]<<endl;
            maxminVal=value;//求完极小值,将当前的极小值赋值,用于求下一个极大值
        }
        else//若为奇数,则执行下面,求#########极大值############
        {
            double minVal1, maxVal1;//最大与最小的像素
            int minIdx1[2] = {}, maxIdx1[2] = {};	//对应的坐标。由于是向量,以0为索引就好了
            Mat maxmin_ROI=msgDate_resize(Rect(0, i+9, 1, 9));// Rect_(_Tp _x, _Tp _y, _Tp _width, _Tp _height);
            minMaxIdx(maxmin_ROI, &minVal1, &maxVal1, minIdx1, maxIdx1);//寻找这个区域内的最大与最小值
            value=in_point[maxIdx1[0]].y;//当前值为最大值,将其赋予value
            average_gobal_maxmin=(maxminVal+value)/2;
            next_point=maxIdx1[0]+9;minIdx1[0]为(i+9, i+2*9)这个区域的最大值坐标。
            for (int j=i;j<=i+next_point;j++)//对比的时候是从(i+9,i+2*9)这个区域找,但实际上,是上一个极值到当前的极值的位置
            {
                local_maxmin_threshold.push_back(Point(j,average_gobal_maxmin));
            }
            Flag_minmax++;//用于奇偶判断,此循环是奇数才进行,加了后变成偶数,进入求极小值的循环
            // cout<<"计算极小值"<<endl;
            // cout<<"对应的极大值"<<maxminVal<<endl;
            // cout<<"value="<<value<<endl;
            maxminVal=value;//求完极大值,将当前的极大值赋值,用于求下一个极小值
        }
        if (i+next_point+2*9>=msgDate_resize.rows)//当前的点是否已经不支持下一次判决,一判决就会溢出.那么就将当前的阈值赋上
        {
            double minVal1, maxVal1;//最大与最小的像素
            int minIdx1[2] = {}, maxIdx1[2] = {};	//对应的坐标。由于是向量,以0为索引就好了
            Mat maxmin_ROI=msgDate_resize(Rect(0, i+9, 1, msgDate_resize.rows-(i+9)));// Rect_(_Tp _x, _Tp _y, _Tp _width, _Tp _height);
            minMaxIdx(maxmin_ROI, &minVal1, &maxVal1, minIdx1, maxIdx1);//寻找这个区域内的最大与最小值
            if (Flag_minmax % 2 == 0)//偶数则极小
            {
                value=in_point[minIdx1[0]].y;//当前值为最小值,将其赋予value
            }
            else
            {
                value=in_point[maxIdx1[0]].y;//当前值为最小值,将其赋予value
            }
            average_gobal_maxmin=(maxminVal+value)/2;            
            for (int j=i;j<=msgDate_resize.rows;j++)
            {
                local_maxmin_threshold.push_back(Point(j,average_gobal_maxmin));
            }
            break;//跳出循环
        }
    }
 


    Flag_minmax=2;用于奇偶判断
    maxminVal=maxVal;//初始化是最大值
    next_point=0;
    //向左寻找############################################################################################3
    for (int i=maxIdx[0];i>=0;i=i-next_point)//由于是极值点下一个开始寻找
    {
        double value=0;//存放下一个极小值
        double average_gobal_maxmin;//存放阈值(每次更新)
        // cout<<"i="<<i<<endl;
        // cout<<"next_point="<<next_point<<endl;
        // cout<<"Flag_minmax="<<Flag_minmax<<endl;
        if (Flag_minmax % 2 == 0)//若为偶数,则执行下面,求############极小值##############
        {
            double minVal1, maxVal1;//最大与最小的像素
            int minIdx1[2] = {}, maxIdx1[2] = {};	//对应的坐标。由于是向量,以0为索引就好了
            Mat maxmin_ROI=msgDate_resize(Rect(0, i-2*9, 1, 9));// Rect_(_Tp _x, _Tp _y, _Tp _width, _Tp _height);
            minMaxIdx(maxmin_ROI, &minVal1, &maxVal1, minIdx1, maxIdx1);//寻找这个区域内的最大与最小值
            value=in_point[minIdx1[0]].y;//当前值为最小值,将其赋予value
            average_gobal_maxmin=(maxminVal+value)/2;
            next_point=9-minIdx1[0];minIdx1[0]为(i+9, i+2*9)这个区域的最小值坐标。
            for (int j=i;j>=i-next_point;j--)//对比的时候是从(i+9,i+2*9)这个区域找,但实际上,是上一个极值到当前的极值的位置
            {
                local_maxmin_threshold.insert(local_maxmin_threshold.begin(),Point(j,average_gobal_maxmin));
            }
            Flag_minmax++;//用于奇偶判断,此循环是偶数才进行,加了后变成奇数,进入求极大值的循环
            maxminVal=value;//求完极小值,将当前的极小值赋值,用于求下一个极大值
        }
        else//若为奇数,则执行下面,求#########极大值############
        {
            double minVal1, maxVal1;//最大与最小的像素
            int minIdx1[2] = {}, maxIdx1[2] = {};	//对应的坐标。由于是向量,以0为索引就好了
            Mat maxmin_ROI=msgDate_resize(Rect(0, i-2*9, 1, 9));// Rect_(_Tp _x, _Tp _y, _Tp _width, _Tp _height);
            minMaxIdx(maxmin_ROI, &minVal1, &maxVal1, minIdx1, maxIdx1);//寻找这个区域内的最大与最小值
            value=in_point[maxIdx1[0]].y;//当前值为最大值,将其赋予value
            average_gobal_maxmin=(maxminVal+value)/2;
            next_point=9-maxIdx1[0];minIdx1[0]为(i+9, i+2*9)这个区域的最大值坐标。
            for (int j=i;j>=i-next_point;j--)//对比的时候是从(i+9,i+2*9)这个区域找,但实际上,是上一个极值到当前的极值的位置
            {
                local_maxmin_threshold.insert(local_maxmin_threshold.begin(),Point(j,average_gobal_maxmin));
            }
            Flag_minmax++;//用于奇偶判断,此循环是奇数才进行,加了后变成偶数,进入求极小值的循环
            maxminVal=value;//求完极大值,将当前的极大值赋值,用于求下一个极小值
        }
        if (i-next_point-2*9<=0)//当前的点是否已经不支持下一次判决,一判决就会溢出.那么就将当前的阈值赋上
        {
            double minVal1, maxVal1;//最大与最小的像素
            int minIdx1[2] = {}, maxIdx1[2] = {};	//对应的坐标。由于是向量,以0为索引就好了
            Mat maxmin_ROI=msgDate_resize(Rect(0, 0, 1, 18));// Rect_(_Tp _x, _Tp _y, _Tp _width, _Tp _height);
            minMaxIdx(maxmin_ROI, &minVal1, &maxVal1, minIdx1, maxIdx1);//寻找这个区域内的最大与最小值
            if (Flag_minmax % 2 == 0)//偶数则极小
            {
                value=in_point[minIdx1[0]].y;//当前值为最小值,将其赋予value
            }
            else
            {
                value=in_point[maxIdx1[0]].y;//当前值为最小值,将其赋予value
            }
            average_gobal_maxmin=(maxminVal+value)/2;            
            for (int j=i;j>=0;j--)
            {
                local_maxmin_threshold.insert(local_maxmin_threshold.begin(),Point(j,average_gobal_maxmin));
            }
            break;//跳出循环
        }
    }  
    cout<<local_maxmin_threshold<<endl;
            

/方法二:EVA algorithm/// 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值