关于轮廓的各种使用


  1. #include "cv.h"   
  2. #include "highgui.h"   
  3. #include "cvaux.h"  
  4. #include "cxcore.h"  
  5. #include <stdio.h>  
  6. #include <vector>  
  7. using namespace std;  
  8. using namespace cv;  
  9.   
  10. #define PI 3.14159f  
  11. void DrawBox(CvBox2D box,IplImage* img)  
  12. {  
  13.     CvPoint2D32f points[4];   
  14.     cvBoxPoints(box,points);  
  15.   
  16.     CvPoint pt[4];   
  17.     for (int i=0; i<4; i++)   
  18.     {   
  19.         pt[i].x = (int)points[i].x;   
  20.         pt[i].y = (int)points[i].y;   
  21.     }   
  22.     cvLine( img, pt[0], pt[1],CV_RGB(255,0,0), 2, 8, 0 );   
  23.     cvLine( img, pt[1], pt[2],CV_RGB(255,0,0), 2, 8, 0 );   
  24.     cvLine( img, pt[2], pt[3],CV_RGB(255,0,0), 2, 8, 0 );   
  25.     cvLine( img, pt[3], pt[0],CV_RGB(255,0,0), 2, 8, 0 );   
  26. }  
  27.   
  28. void main()  
  29. {  
  30.     IplImage* img1 = cvLoadImage("5.jpg",1);  
  31.     IplImage* img1_gray =cvCreateImage(cvGetSize(img1),8,1);  
  32.     cvCvtColor(img1,img1_gray,CV_BGR2GRAY);  
  33.     IplImage* img_edge1 = cvCreateImage(cvGetSize(img1),8,1);  
  34.     cvThreshold(img1_gray,img_edge1,240,255,CV_THRESH_BINARY);  
  35.   
  36.     printf("图1:\n\n");  
  37.     CvMemStorage* storage1 = cvCreateMemStorage();  
  38.     CvSeq* contour1 = NULL;  
  39.     int Nc1= cvFindContours(img_edge1,storage1,&contour1,sizeof(CvContour),CV_RETR_LIST);//最后一个参数的可变性  
  40.     printf("轮廓数:%d\n",Nc1);  
  41.       
  42.     //轮廓的矩   
  43.     CvMoments *moments1=new CvMoments();   
  44.     cvMoments(contour1,moments1,0);  
  45.     //Hu矩  
  46.     CvHuMoments *huMonents1=new CvHuMoments();  
  47.     cvGetHuMoments(moments1,huMonents1);  
  48.     printf("遍历三阶矩:\n");  
  49.     for (int xOrder = 0; xOrder <= 3; xOrder++)  
  50.         for (int yOrder = 0; yOrder <= 3; yOrder++)  
  51.         {  
  52.             if (xOrder + yOrder <= 3)  
  53.             {  
  54.                 double spatialMoment =cvGetSpatialMoment(moments1,xOrder, yOrder);  
  55.                 double centralMoment =cvGetCentralMoment(moments1,xOrder, yOrder);  
  56.                 double normalizedCentralMoment =cvGetNormalizedCentralMoment(moments1,xOrder, yOrder);  
  57.                 printf("  %d,%d : 空间距-%.2f, 中心距-%.2f, 归一化中心距-%.2f\n",xOrder,yOrder,spatialMoment,centralMoment,normalizedCentralMoment);  
  58.             }  
  59.         }  
  60.     printf("Hu矩:%f,%f,%f,%f,%f,%f,%f\n",huMonents1->hu1,huMonents1->hu2,huMonents1->hu3,huMonents1->hu3,huMonents1->hu5,huMonents1->hu6,huMonents1->hu7);  
  61.   
  62.     printf("\n图2:\n\n");  
  63.     IplImage* img2 = cvLoadImage("6.jpg",1);  
  64.     IplImage* img2_gray =cvCreateImage(cvGetSize(img2),8,1);  
  65.     cvCvtColor(img2,img2_gray,CV_BGR2GRAY);  
  66.     IplImage* img_edge2 = cvCreateImage(cvGetSize(img2),8,1);  
  67.     cvThreshold(img2_gray,img_edge2,128,255,CV_THRESH_BINARY);  
  68.   
  69.     CvMemStorage* storage2 = cvCreateMemStorage();  
  70.     CvSeq* contour2 = NULL;  
  71.     int Nc2 = cvFindContours(img_edge2,storage2,&contour2,sizeof(CvContour),CV_RETR_LIST);  
  72.     printf("轮廓数:%d\n\n",Nc2);  
  73.   
  74.     printf("遍历三阶矩:\n");  
  75.     CvMoments*moments2=new CvMoments();   
  76.     cvMoments(contour2,moments2,0);   
  77.     CvHuMoments *huMonents2=new CvHuMoments();  
  78.     cvGetHuMoments(moments2,huMonents2);  
  79.     for (int xOrder = 0; xOrder <= 3; xOrder++)  
  80.         for (int yOrder = 0; yOrder <= 3; yOrder++)  
  81.         {  
  82.             if (xOrder + yOrder <= 3)  
  83.             {  
  84.                 double spatialMoment =cvGetSpatialMoment(moments2,xOrder, yOrder);  
  85.                 double centralMoment =cvGetCentralMoment(moments2,xOrder, yOrder);  
  86.                 double normalizedCentralMoment =cvGetNormalizedCentralMoment(moments2,xOrder, yOrder);  
  87.                 printf("  %d,%d : 空间距-%.2f, 中心距-%.2f, 归一化中心距-%.2f\n",xOrder,yOrder,spatialMoment,centralMoment,normalizedCentralMoment);  
  88.             }  
  89.         }  
  90.     printf("Hu矩:%f,%f,%f,%f,%f,%f,%f\n",huMonents2->hu1,huMonents2->hu2,huMonents2->hu3,huMonents2->hu3,huMonents2->hu5,huMonents2->hu6,huMonents2->hu7);  
  91.   
  92.     //Hu矩匹配  
  93.     double hu = cvMatchShapes(contour1,contour2,CV_CONTOURS_MATCH_I1,0);  
  94.     printf("\n\nHu矩匹配:%f\n",hu);  
  95.   
  96.     //轮廓树匹配  
  97.     CvMemStorage* storage3 = cvCreateMemStorage();  
  98.     CvMemStorage* storage4= cvCreateMemStorage();  
  99.     CvContourTree* tree1 = cvCreateContourTree(contour1,storage3,200);  
  100.     CvContourTree* tree2 = cvCreateContourTree(contour2,storage4,200);  
  101.     double tree = cvMatchContourTrees(tree1,tree2,CV_CONTOURS_MATCH_I1,200);  
  102.     printf("\n轮廓树匹配:%.4f\n\n",tree);  
  103.   
  104.     //将轮廓线画出  
  105.     double s1,len1,h1,d1;  
  106.     CvRect rect1;  
  107.     CvBox2D box1,ellipse1;  
  108.     CvPoint2D32f center1;  
  109.     float radius1;  
  110.     IplImage* mask1=cvCreateImage(cvGetSize(img1),8,1);  
  111.     IplImage* dst1=cvCreateImage(cvGetSize(img1),8,3);  
  112.   
  113.     //轮廓的成对几何直方图匹配        
  114.     int sizes[2] = {60, 200};  
  115.     float ranges[2][2] = {{0,PI}, {0,200}};  
  116.     float** rangesPtr = new float* [2];  
  117.     rangesPtr[0] = ranges[0];  
  118.     rangesPtr[1] = ranges[1];  
  119.   
  120.     CvHistogram* hist1,*hist2;  
  121.     hist1 = cvCreateHist(2, sizes, CV_HIST_ARRAY, rangesPtr, 1);  
  122.     hist2 = cvCreateHist(2, sizes, CV_HIST_ARRAY, rangesPtr, 1);  
  123.     cvCalcPGH(contour1, hist1);   
  124.     cvCalcPGH(contour2, hist2);  
  125.     cvNormalizeHist(hist1, 1);  
  126.     cvNormalizeHist(hist2, 1);  
  127.   
  128.     double hist= cvCompareHist(hist1,hist2, CV_COMP_INTERSECT);  
  129.     printf("\n成对几何直方图匹配:%.2f\n\n\n", hist);  
  130.   
  131.     printf("图1:\n\n");  
  132.     forint i=1; contour1!= 0; contour1 = contour1->h_next,i++)     
  133.     {     
  134.         IplImage* img1_copy =cvCloneImage(img1);  
  135.         printf("\n第%d个轮廓:\n",i);  
  136.         CvScalar color = CV_RGB( 0, 0,255);     
  137.         cvZero( mask1);   
  138.         cvZero( dst1 );    
  139.         cvDrawContours(mask1, contour1, color, color, -1, 1);//边界线的厚度,默认为 1,得到的是轮廓外形这里设置为 -1即CV_FILLED,  
  140.         //是指对轮廓内的区域进行填充,通过cvCopy可将原图轮廓中的内容保留下来  
  141.         cvCopy(img1_copy, dst1, mask1); //可将原图轮廓中的内容保留下来  
  142.         cvSaveImage("111.bmp",dst1);//debug查看效果  
  143.         s1 = fabs(cvContourArea(contour1));//轮廓面积  
  144.         printf("  轮廓面积:%f\n",s1);  
  145.         len1=cvArcLength(contour1);  
  146.         printf("  轮廓周长:%f\n",len1);  
  147.         rect1=cvBoundingRect(contour1);//轮廓的边界框  
  148.         cvRectangle(img1_copy,cvPoint(rect1.x,rect1.y),cvPoint(rect1.x+rect1.width,rect1.y+rect1.height),CV_RGB(255,255,0));  
  149.         box1=cvMinAreaRect2(contour1);//最小矩形  
  150.         DrawBox(box1,img1_copy);  
  151.         cvMinEnclosingCircle(contour1,¢er1,&radius1);//外围圆  
  152.         cvCircle(img1_copy,cvPoint((int)center1.x,(int)center1.y),radius1,CV_RGB(0,255,0));  
  153.         ellipse1=cvFitEllipse2(contour1);//外围椭圆  
  154.         cvEllipseBox(img1_copy,ellipse1,CV_RGB(0,0,255));  
  155.         cvSaveImage("222.bmp",img1_copy);//debug查看效果  
  156.         int flag=cvCheckContourConvexity(contour1);//凹凸性,检测不准确???  
  157.         if (flag)  
  158.             printf("  为凸包\n");  
  159.         else  
  160.             printf("  为凹包\n");  
  161.         CvSeq* convexHull1=cvConvexHull2(contour1,NULL,1,1);//凸外多边形  
  162.         //当return_points=0时,用cvConvexHull2函数得到的凸外形,包含的是轮廓的定点的指针或下标,  
  163.         //而当return_points为非0时,得到的是外形点的本身。大家知道计算整个轮廓或部分轮廓的面积的函数定义为:   
  164.         cvZero( mask1);   
  165.         cvZero( dst1 );    
  166.         cvDrawContours(mask1,convexHull1, color, color, -1, 2);  
  167.         cvCopy(img1_copy, dst1, mask1); //可将原图轮廓中的内容保留下来  
  168.         cvSaveImage("333.bmp",dst1);//debug查看效果  
  169.         h1 = fabs(cvContourArea(convexHull1));//轮廓面积  
  170.         printf("  凸外多边形面积为:%f\n",h1);  
  171.         //CvSeq *defects1=cvConvexityDefects(contour1,convexHull1);//缺陷  
  172.         //Seq<CvConvexityDefect> defects2=cvConvexityDefects(contour1,convexHull1);//为什么都不可以  
  173.         //d1 = fabs(cvContourArea(defects1));//轮廓面积  
  174.         //printf("  缺陷面积为:%f\n",d1);  
  175.     }  
  176.     cvReleaseMemStorage(&storage1);  
  177.     cvReleaseMemStorage(&storage2);  
  178.     cvReleaseMemStorage(&storage3);  
  179.     cvReleaseMemStorage(&storage4);  
  180.   
  181. }  

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值