• 关于轮廓的各种使用


    注解:楼主现在处于学习中,大部分是转载。
    #include "cv.h" 
    #include "highgui.h" 
    #include "cvaux.h"
    #include "cxcore.h"
    #include <stdio.h>
    #include <vector>
    using namespace std;
    using namespace cv;
    
    #define PI 3.14159f
    void DrawBox(CvBox2D box,IplImage* img)
    {
        CvPoint2D32f points[4]; 
        cvBoxPoints(box,points);
    
        CvPoint pt[4]; 
        for (int i=0; i<4; i++) 
        { 
            pt[i].x = (int)points[i].x; 
            pt[i].y = (int)points[i].y; 
        } 
        cvLine( img, pt[0], pt[1],CV_RGB(255,0,0), 2, 8, 0 ); 
        cvLine( img, pt[1], pt[2],CV_RGB(255,0,0), 2, 8, 0 ); 
        cvLine( img, pt[2], pt[3],CV_RGB(255,0,0), 2, 8, 0 ); 
        cvLine( img, pt[3], pt[0],CV_RGB(255,0,0), 2, 8, 0 ); 
    }
    
    void main()
    {
        IplImage* img1 = cvLoadImage("5.jpg",1);
        IplImage* img1_gray =cvCreateImage(cvGetSize(img1),8,1);
        cvCvtColor(img1,img1_gray,CV_BGR2GRAY);
        IplImage* img_edge1 = cvCreateImage(cvGetSize(img1),8,1);
        cvThreshold(img1_gray,img_edge1,240,255,CV_THRESH_BINARY);
    
        printf("图1:\n\n");
        CvMemStorage* storage1 = cvCreateMemStorage();
        CvSeq* contour1 = NULL;
        int Nc1= cvFindContours(img_edge1,storage1,&contour1,sizeof(CvContour),CV_RETR_LIST);//最后一个参数的可变性
        printf("轮廓数:%d\n",Nc1);
        
        //轮廓的矩 
        CvMoments *moments1=new CvMoments(); 
        cvMoments(contour1,moments1,0);
        //Hu矩
        CvHuMoments *huMonents1=new CvHuMoments();
        cvGetHuMoments(moments1,huMonents1);
        printf("遍历三阶矩:\n");
        for (int xOrder = 0; xOrder <= 3; xOrder++)
            for (int yOrder = 0; yOrder <= 3; yOrder++)
            {
                if (xOrder + yOrder <= 3)
                {
                    double spatialMoment =cvGetSpatialMoment(moments1,xOrder, yOrder);
                    double centralMoment =cvGetCentralMoment(moments1,xOrder, yOrder);
                    double normalizedCentralMoment =cvGetNormalizedCentralMoment(moments1,xOrder, yOrder);
                    printf("  %d,%d : 空间距-%.2f, 中心距-%.2f, 归一化中心距-%.2f\n",xOrder,yOrder,spatialMoment,centralMoment,normalizedCentralMoment);
                }
            }
        printf("Hu矩:%f,%f,%f,%f,%f,%f,%f\n",huMonents1->hu1,huMonents1->hu2,huMonents1->hu3,huMonents1->hu3,huMonents1->hu5,huMonents1->hu6,huMonents1->hu7);
    
        printf("\n图2:\n\n");
        IplImage* img2 = cvLoadImage("6.jpg",1);
        IplImage* img2_gray =cvCreateImage(cvGetSize(img2),8,1);
        cvCvtColor(img2,img2_gray,CV_BGR2GRAY);
        IplImage* img_edge2 = cvCreateImage(cvGetSize(img2),8,1);
        cvThreshold(img2_gray,img_edge2,128,255,CV_THRESH_BINARY);
    
        CvMemStorage* storage2 = cvCreateMemStorage();
        CvSeq* contour2 = NULL;
        int Nc2 = cvFindContours(img_edge2,storage2,&contour2,sizeof(CvContour),CV_RETR_LIST);
        printf("轮廓数:%d\n\n",Nc2);
    
        printf("遍历三阶矩:\n");
        CvMoments*moments2=new CvMoments();    
        cvMoments(contour2,moments2,0);    
        CvHuMoments    *huMonents2=new CvHuMoments();
        cvGetHuMoments(moments2,huMonents2);
        for (int xOrder = 0; xOrder <= 3; xOrder++)
            for (int yOrder = 0; yOrder <= 3; yOrder++)
            {
                if (xOrder + yOrder <= 3)
                {
                    double spatialMoment =cvGetSpatialMoment(moments2,xOrder, yOrder);
                    double centralMoment =cvGetCentralMoment(moments2,xOrder, yOrder);
                    double normalizedCentralMoment =cvGetNormalizedCentralMoment(moments2,xOrder, yOrder);
                    printf("  %d,%d : 空间距-%.2f, 中心距-%.2f, 归一化中心距-%.2f\n",xOrder,yOrder,spatialMoment,centralMoment,normalizedCentralMoment);
                }
            }
        printf("Hu矩:%f,%f,%f,%f,%f,%f,%f\n",huMonents2->hu1,huMonents2->hu2,huMonents2->hu3,huMonents2->hu3,huMonents2->hu5,huMonents2->hu6,huMonents2->hu7);
    
        //Hu矩匹配
        double hu = cvMatchShapes(contour1,contour2,CV_CONTOURS_MATCH_I1,0);
        printf("\n\nHu矩匹配:%f\n",hu);
    
        //轮廓树匹配
        CvMemStorage* storage3 = cvCreateMemStorage();
        CvMemStorage* storage4= cvCreateMemStorage();
        CvContourTree* tree1 = cvCreateContourTree(contour1,storage3,200);
        CvContourTree* tree2 = cvCreateContourTree(contour2,storage4,200);
        double tree = cvMatchContourTrees(tree1,tree2,CV_CONTOURS_MATCH_I1,200);
        printf("\n轮廓树匹配:%.4f\n\n",tree);
    
        //将轮廓线画出
        double s1,len1,h1,d1;
        CvRect rect1;
        CvBox2D box1,ellipse1;
        CvPoint2D32f center1;
        float radius1;
        IplImage* mask1=cvCreateImage(cvGetSize(img1),8,1);
        IplImage* dst1=cvCreateImage(cvGetSize(img1),8,3);
    
        //轮廓的成对几何直方图匹配        
        int sizes[2] = {60, 200};
        float ranges[2][2] = {{0,PI}, {0,200}};
        float** rangesPtr = new float* [2];
        rangesPtr[0] = ranges[0];
        rangesPtr[1] = ranges[1];
    
        CvHistogram* hist1,*hist2;
        hist1 = cvCreateHist(2, sizes, CV_HIST_ARRAY, rangesPtr, 1);
        hist2 = cvCreateHist(2, sizes, CV_HIST_ARRAY, rangesPtr, 1);
        cvCalcPGH(contour1, hist1);    
        cvCalcPGH(contour2, hist2);
        cvNormalizeHist(hist1, 1);
        cvNormalizeHist(hist2, 1);
    
        double hist= cvCompareHist(hist1,hist2, CV_COMP_INTERSECT);
        printf("\n成对几何直方图匹配:%.2f\n\n\n", hist);
    
        printf("图1:\n\n");
        for( int i=1; contour1!= 0; contour1 = contour1->h_next,i++)   
        {   
            IplImage* img1_copy =cvCloneImage(img1);
            printf("\n第%d个轮廓:\n",i);
            CvScalar color = CV_RGB( 0, 0,255);   
            cvZero( mask1); 
            cvZero( dst1 );  
            cvDrawContours(mask1, contour1, color, color, -1, 1);//边界线的厚度,默认为 1,得到的是轮廓外形这里设置为 -1即CV_FILLED,
            //是指对轮廓内的区域进行填充,通过cvCopy可将原图轮廓中的内容保留下来
            cvCopy(img1_copy, dst1, mask1); //可将原图轮廓中的内容保留下来
            cvSaveImage("111.bmp",dst1);//debug查看效果
            s1 = fabs(cvContourArea(contour1));//轮廓面积
            printf("  轮廓面积:%f\n",s1);
            len1=cvArcLength(contour1);
            printf("  轮廓周长:%f\n",len1);
            rect1=cvBoundingRect(contour1);//轮廓的边界框
            cvRectangle(img1_copy,cvPoint(rect1.x,rect1.y),cvPoint(rect1.x+rect1.width,rect1.y+rect1.height),CV_RGB(255,255,0));
            box1=cvMinAreaRect2(contour1);//最小矩形
            DrawBox(box1,img1_copy);
            cvMinEnclosingCircle(contour1,¢er1,&radius1);//外围圆
            cvCircle(img1_copy,cvPoint((int)center1.x,(int)center1.y),radius1,CV_RGB(0,255,0));
            ellipse1=cvFitEllipse2(contour1);//外围椭圆
            cvEllipseBox(img1_copy,ellipse1,CV_RGB(0,0,255));
            cvSaveImage("222.bmp",img1_copy);//debug查看效果
            int flag=cvCheckContourConvexity(contour1);//凹凸性,检测不准确???
            if (flag)
                printf("  为凸包\n");
            else
                printf("  为凹包\n");
            CvSeq* convexHull1=cvConvexHull2(contour1,NULL,1,1);//凸外多边形
            //当return_points=0时,用cvConvexHull2函数得到的凸外形,包含的是轮廓的定点的指针或下标,
            //而当return_points为非0时,得到的是外形点的本身。大家知道计算整个轮廓或部分轮廓的面积的函数定义为: 
            cvZero( mask1); 
            cvZero( dst1 );  
            cvDrawContours(mask1,convexHull1, color, color, -1, 2);
            cvCopy(img1_copy, dst1, mask1); //可将原图轮廓中的内容保留下来
            cvSaveImage("333.bmp",dst1);//debug查看效果
            h1 = fabs(cvContourArea(convexHull1));//轮廓面积
            printf("  凸外多边形面积为:%f\n",h1);
            //CvSeq *defects1=cvConvexityDefects(contour1,convexHull1);//缺陷
            //Seq<CvConvexityDefect> defects2=cvConvexityDefects(contour1,convexHull1);//为什么都不可以
            //d1 = fabs(cvContourArea(defects1));//轮廓面积
            //printf("  缺陷面积为:%f\n",d1);
        }
        cvReleaseMemStorage(&storage1);
        cvReleaseMemStorage(&storage2);
        cvReleaseMemStorage(&storage3);
        cvReleaseMemStorage(&storage4);
    
    }


  • 相关阅读:
    随机数组找丢失数据
    js打开新页面 关闭当前页 关闭父页面
    Markdown测试
    ThinkPHP中的时间自动填充 无法获取时间
    页面在谷歌浏览器和IE浏览器顶部多出空白行,火狐显示正常
    Thinkphp中验证码不显示解决办法
    106运用SWITCH语句打印星期几的单词
    声明两个变量并赋值计算出矩形的面积
    不用*用移位运算符计算21*16的数值是多少
    97.经典实例,计算球形的面积和体积
  • 原文地址:https://www.cnblogs.com/polly333/p/4498445.html
Copyright © 2020-2023  润新知