您的位置:首页 > 其它

关于轮廓的各种使用

2013-09-02 14:47 162 查看
#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[
1dd7f
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);  

  

}  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: