• 最大轮廓和投影 转


    转自:http://www.opencv.org.cn/forum.php?mod=viewthread&tid=37839&page=1

    最大轮廓和投影
        
        最近非常多的用到了最大轮廓和投影运算。回想起来,这两种算法的确是属于非常常见的基础算法。这里加以总结和提取。
          最大轮廓:
          前提是图像经过了灰度和阈值处理,也可以直接处理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;
                    }
                }

  • 相关阅读:
    【网络编程3】网络编程基础-arp请求(局域网主机扫描)
    【CTF MISC】隐写术wireshark找出图片-“强网杯”网络安全挑战赛writeup
    【网络编程2】网络编程基础-发送ICMP包(Ping程序)
    【网络编程1】网络编程基础-TCP、UDP编程
    【漏洞分析】两个例子-数组溢出修改返回函数与strcpy覆盖周边内存地址
    【Python】zip文件密码破解
    【bzoj1923】[Sdoi2010]外星千足虫 高斯消元
    spring cloud zuul在使用中遇到的坑 : 转发时自动去掉prefix
    Eclipse MAT:浅堆 vs 保留堆
    Java SDK夯住(Hang)问题排查
  • 原文地址:https://www.cnblogs.com/wolfplan/p/6516989.html
Copyright © 2020-2023  润新知