zoukankan      html  css  js  c++  java
  • 轮廓随机均匀采样

    context shape形状上下文中对轮廓点随机采样的实现
    http://www.cnblogs.com/xiaotie/ 用C#实现了该算法且有详细的说明,我用opencv实现了一下。
     
    效果图:
     
     
    // shapeContenx.cpp : 定义控制台应用程序的入口点。
    //
    #include "stdafx.h"
    #include "highgui.h"
    #include "cv.h"
    #include "cxcore.h"
    #include "ml.h"
    #include <list>
    using namespace std;
    #ifdef DEBUG
    #pragma comment(lib,"opencv_core231d.lib")
    #pragma comment(lib,"opencv_features2d231d.lib")
    #pragma comment(lib,"opencv_flann231d.lib")
    #pragma comment(lib,"opencv_gpu231d.lib")
    #pragma comment(lib,"opencv_highgui231d.lib")
    #pragma comment(lib,"opencv_imgproc231d.lib")
    #pragma comment(lib,"opencv_ml231d.lib")
    #else
    #pragma comment(lib,"opencv_core231.lib")
    #pragma comment(lib,"opencv_features2d231.lib")
    #pragma comment(lib,"opencv_flann231.lib")
    #pragma comment(lib,"opencv_gpu231.lib")
    #pragma comment(lib,"opencv_highgui231.lib")
    #pragma comment(lib,"opencv_imgproc231.lib")
    #pragma comment(lib,"opencv_ml231.lib")
    #endif
    typedef struct _pairDistance
    {
        int i;
        int j;
        int distance;
        _pairDistance(int ni , int nj , int ndistance):i(ni),j(nj),distance(ndistance)
        {
        }
        bool operator < (const _pairDistance &pd)const
        {
            return distance < pd.distance;
        }
    }pairDistance;
    /*
        函数:contoursample 
        功能:轮廓抽样
        参数:seq ------ 轮廓点序列
         samplearry --- 用于存放抽样点
             samplearry ---- 抽样点数
    */

    void contoursample(CvSeq * seq , CvPoint *samplearry, int samplenum)
    {
        int num = 0
        for (CvSeq *s = seq ; s !=NULL;s=s->h_next)
            num +=s->total;
        CvPoint *pointarray = (CvPoint *)malloc(num * sizeof(CvPoint));
        
        int accum = 0
        for (CvSeq *s =seq ; s!=NULL;s=s->h_next)
        {
            cvCvtSeqToArray( s, pointarray +accum);
            accum +=s->total;
            
        }
        
        if ( num < samplenum)
        {
            free(pointarray);
            return
        }
        // 轮廓点随机打乱
        CvRNG rng; 
        rng = cvRNG(cvGetTickCount());
        CvPoint pointtemp;
        int tagtemp = -1;
        for (int i = 0 ; i < num ; ++i)
        {
            int index = cvRandInt(&rng)%(num-i)+i;
            if(index !=i)
            {
                pointtemp = pointarray[index];
                pointarray[index] = pointarray[i];
                pointarray[i] = pointtemp;
                
            }
        }
        // 如果*samplenum > num 即取样点数远远小于轮廓点数随即抽取samplenum个点节省运算时间
        if (num > 3 * samplenum)
        {
            
            CvPoint *pointarray2 = (CvPoint *)malloc(3*samplenum * sizeof(CvPoint));
            for (int i = 0;i < 3*samplenum;++i)
            {
                pointarray2[i] = pointarray[i];
            }
            free(pointarray);
            pointarray = pointarray2;
            num = 3 * samplenum;
        }
        // 计算轮廓点与点间距离
        list<pairDistance> list_pair;
        for (int i = 0 ; i < num ; i++)
        {
            for (int j = i +1 ; j < num ; ++j)
            {
                list_pair.push_back(pairDistance( i , j ,(pointarray[i].x -pointarray[j].x) * (pointarray[i].x -pointarray[j].x) + 
                    (pointarray[i].y -pointarray[j].y) * (pointarray[i].y -pointarray[j].y)));
            }
        }
        // 排序
        list_pair.sort();
        // 删除最小距离点对中的其中一个点直到满足samplenum
        int nneedremove = num - samplenum;
        int *mask = (int *)malloc( num * sizeof(int));
        memset(mask,0,num * sizeof(int));
        //list<pairDistance>::iterator iter = list_pair.begin();
        list<pairDistance>::iterator iter = list_pair.begin();
        while (nneedremove > 0)
        {
            int index0 = (*iter).i;
            int index1 = (*iter).j;
            if (mask[index0] == 0 && mask[index1] ==0)
            {
                mask[index1] = 1 ;
                nneedremove --;
            }
            iter++;
        }
        // 将抽样点存放到samplearry中
        int nstartindex = 0 ;
        for (int i = 0 ; i < num ; ++i)
        {
            if (mask[i] ==0)
            {
                samplearry[nstartindex] = pointarray[i];
                nstartindex++;
            }
        }
        free(pointarray);
    }
    int _tmain(int argc, _TCHAR* argv[])
    {
        //1 . 验证对数极坐标的缩放不变性
        //IplImage * im_a1 = cvLoadImage("W1.jpg",CV_LOAD_IMAGE_GRAYSCALE);
        //IplImage * im_a2 = cvLoadImage("W2.jpg",CV_LOAD_IMAGE_GRAYSCALE);
        //cvNot(im_a1,im_a1);
        //cvNot(im_a2,im_a2);
        //IplImage * im_show1 = cvCreateImage(cvSize(360,360),8,1);
        //IplImage * im_show2 = cvCreateImage(cvSize(360,360),8,1);
        //cvLogPolar(im_a1,im_show1,cvPoint2D32f(im_a1->width/2,im_a1->height/2),40,CV_INTER_NN+CV_WARP_FILL_OUTLIERS);
        //cvLogPolar(im_a2,im_show2,cvPoint2D32f(im_a2->width/2,im_a2->height/2),40,CV_INTER_NN+CV_WARP_FILL_OUTLIERS);
        //cvShowImage("a1",im_show1);
        //cvShowImage("a2",im_show2);
        IplImage * im_src = cvLoadImage("a.PNG",CV_LOAD_IMAGE_GRAYSCALE);
        IplImage * im_show = cvLoadImage("a.PNG");
        IplImage * im_threshold = cvCreateImage(cvGetSize(im_src),8,1);
        // 1 . 统一尺寸大小
            
        cvThreshold(im_src,im_threshold,128,255,CV_THRESH_BINARY_INV);    
        // 2 . 轮廓提取
        CvMemStorage * storage = cvCreateMemStorage();
        CvSeq * contour = NULL;
        cvFindContours(im_threshold,storage,&contour,sizeof(CvContour),CV_RETR_LIST,CV_CHAIN_APPROX_NONE );
        
        //for (CvSeq *s = contour ; s!=NULL ;s=s->h_next)
        //{
        //    cvDrawContours(im_show,s,CV_RGB(255,0,0),CV_RGB(255,0,0),0);
        //}
        //cvShowImage("s",im_show);
        // 3 . 轮廓抽样
        int num = 100;
        CvPoint *samplearray = (CvPoint *)malloc(num * sizeof(CvPoint));
        
        contoursample(contour,samplearray,num);
        
        for (int i = 0 ; i< num ; ++i)
        {
            cvDrawCircle(im_show,samplearray[i],3,CV_RGB(255,0,0));
        }
        cvShowImage("samplepoint",im_show);
        // 4 . 以抽样点的切线作为X轴正方向建立logr-theta 直方图
        
        // 5 . 计算const 找对应点
        free(samplearray);
        cvReleaseMemStorage(&storage);
        cvWaitKey(-1);
        return 0;
    }





    作者: 小马_xiao

    出处:http://www.cnblogs.com/xiaomaLV2/>

    关于作者:专注halcon\opencv\机器视觉

    本文版权归作者,未经作者同意必须保留此段声明,且在文章页面明显位置给出 原文链接

  • 相关阅读:
    全球2/3的DNS瘫痪 顶级域名根服务器故障
    PHP多种形式发送邮件
    IOS开发的基础知识
    Java数字图像处理基础
    将HTML5 Canvas的内容保存为图片
    C# SortedList类概念和示例
    实例对比剖析c#引用参数的用法
    如何理解css中的float
    创建Google网站地图Sitemap.xml
    c#生成静态html文件,封装类
  • 原文地址:https://www.cnblogs.com/xiaomaLV2/p/2593671.html
Copyright © 2011-2022 走看看