最大轮廓和投影

最大轮廓和投影
    
    最近非常多的用到了最大轮廓和投影运算。回想起来,这两种算法的确是属于非常常见的基础算法。这里加以总结和提取。
      最大轮廓:
      前提是图像经过了灰度和阈值处理,也可以直接处理canny的结果,有些时候需要预先经过色彩域的转换。最后得到的结果,应该是一个contour,当然可以采用一定的方法处理得到外接矩形。
//寻找最大的轮廓
vector <cv : :Point > FindBigestContour(Mat src)
{    
     int imax  =  0//代表最大轮廓的序号
     int imaxcontour  =  - 1//代表最大轮廓的大小
    std : :vector <std : :vector <cv : :Point >>contours;    
    findContours(src,contours,CV_RETR_LIST,CV_CHAIN_APPROX_SIMPLE);
     for ( int i = 0;i <contours.size();i ++)
    {
         int itmp  =  contourArea(contours[i]); //这里采用的是轮廓大小
         if (imaxcontour  < itmp )
        {
            imax  = i;
            imaxcontour  = itmp;
        }
    }
     return contours[imax];
}
 调用方法,得到外接矩阵
                    Rect boundRect = boundingRect(Mat(FindBigestContour(canny)));
     投影处理
      这里的前提和最大轮廓是非常相似的。投影主要关心的是通过投影图像,获得原始图像中的ROI,或者获得有多少个上波形多少个下波形这些定量的结果。

    Vector < int > vectorV;  //横向循环
    Vector < int > vectorH;  //纵向循环
    Vector < int > VUpper;
    Vector < int > VDown;
    vector < int > HUpper;
    vector < int > HDower;

    // 做横向循环
     for ( int i = 0;i <ostu.cols;i ++)
    {
        Mat data  = ostu.col(i);
         int itmp  = countNonZero(data);
        vectorV.push_back(itmp);
    }
     //上波形为VUpper,下波形为VDown
     for ( int i = 1;i <vectorV.size();i ++)
    {
         if (vectorV[i - 1==  0  && vectorV[i] > 0)
        {
            VUpper.push_back(i);
        }
         if (vectorV[i - 1] > 0  && vectorV[i]  ==  0)
        {
            VDown.push_back(i);
        }
    }
    //做纵向循环,这个往往处理的是横向循环的结果图片
       for ( int j = 0;j <ostu.rows;j ++)
        {
            Mat data  = roitmp.row(j);
             int itmp  = countNonZero(data);
            vectorH.push_back(itmp);
        }
         for ( int j = 0;j <vectorH.size() - 1;j ++)
        {   
             if (vectorH[j] > 0  && vectorH[j + 1==  0)
            {
                HDower.push_back(j);
            }
             if (vectorH[j]  ==  0  && vectorH[j + 1] > 0)
            {
                HUpper.push_back(j);
            }
        }

      //由于处理的上波形和下波形可能会有问题,需要进行一定的处理
      //这里的一个处理就是提出哪些短暂的空白区域
     for ( int j = 0;j <HDower.size() - 1;j ++)
            {
                 //得出之间空白的区域
                 int iwidth  = HUpper[j + 1- HDower[j];
                 if (iwidth  >  10)
                {
                    iresult  = iresult  + 1;
                }
            }





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值