• OpenCV 根据点集(轮廓)拟合圆


      1 #include <opencv2/core/core.hpp>
      2 #include <opencv2/highgui/highgui.hpp>
      3 #include <opencv2/imgproc/imgproc.hpp>
      4 #include <opencv2/opencv.hpp>
      5  
      6 #include <vector>
      7 #include <iostream>
      8  
      9 using namespace cv;
     10 using namespace std;
     11  
     12  
     13 typedef struct Box
     14 {
     15     double x;
     16     double y;
     17     double r;
     18 }Box;
     19  
     20 Box circleLeastFit(const vector<CvPoint *> &points)
     21 {
     22  
     23     Box box;
     24     box.x = 0.0f;
     25     box.y = 0.0f;
     26     box.r = 0.0f;
     27  
     28     if (points.size() < 3)
     29     {
     30         return box;
     31     }
     32  
     33     int i=0;
     34  
     35     double X1=0;
     36     double Y1=0;
     37     double X2=0;
     38     double Y2=0;
     39     double X3=0;
     40     double Y3=0;
     41     double X1Y1=0;
     42     double X1Y2=0;
     43     double X2Y1=0;
     44  
     45     int Sum = points.size();
     46     for (i=0;i<Sum;i++)
     47     {
     48         X1 = X1 + points[i]->x;
     49         Y1 = Y1 + points[i]->y;
     50         X2 = X2 + points[i]->x*points[i]->x;
     51         Y2 = Y2 + points[i]->y*points[i]->y;
     52         X3 = X3 + points[i]->x*points[i]->x*points[i]->x;
     53         Y3 = Y3 + points[i]->y*points[i]->y*points[i]->y;
     54         X1Y1 = X1Y1 + points[i]->x*points[i]->y;
     55         X1Y2 = X1Y2 + points[i]->x*points[i]->y*points[i]->y;
     56         X2Y1 = X2Y1 + points[i]->x*points[i]->x*points[i]->y;
     57     }
     58  
     59     double C,D,E,G,H,N;
     60     double a,b,c;
     61     N = points.size();
     62     C = N*X2 - X1*X1;
     63     D = N*X1Y1 - X1*Y1;
     64     E = N*X3 + N*X1Y2 - (X2+Y2)*X1;
     65     G = N*Y2 - Y1*Y1;
     66     H = N*X2Y1 + N*Y3 - (X2+Y2)*Y1;
     67     a = (H*D-E*G)/(C*G-D*D);
     68     b = (H*C-E*D)/(D*D-G*C);
     69     c = -(a*X1 + b*Y1 + X2 + Y2)/N;
     70  
     71     double A,B,R;
     72     A = a/(-2);
     73     B = b/(-2);
     74     R = sqrt(a*a+b*b-4*c)/2;
     75  
     76     box.x= A;
     77     box.y = B;
     78     box.r = R;
     79     
     80     return box;
     81 }
     82  
     83 //获取自定义核
     84 void f_GetElement(int **p,IplImage *src)//为什么p一定要是二级指针???
     85 {
     86     int length = (src->width)*(src->height);//图片大小
     87     *p = (int*)malloc(sizeof(int)*length);//动态分配内存,大小为(sizeof(int)*length)
     88     memset(*p,0,sizeof(int)*length);//初始化内存区间 p为0
     89  
     90     for(int y=0; y<src->height; y++)
     91     {
     92         uchar *ptr = (uchar*)(src->imageData + y*src->widthStep);
     93  
     94         int b = y*src->widthStep;//???
     95         for(int x=0; x<src->width; x++)
     96         {
     97             if(ptr[x]==255)
     98             {
     99                 (*p)[b+x] = 1;
    100             }
    101             else 
    102             {
    103                 (*p)[b+x] = 0;
    104             }
    105         }
    106     }
    107 }
    108  
    109  
    110 int main()
    111 { 
    112     
    113     IplImage* src = cvLoadImage("5.bmp",1);
    114     
    115     IplImage *gray_image = cvCreateImage(cvGetSize(src),8,1);
    116     IplImage *rgb_image = cvCreateImage(cvGetSize(src),8,3);
    117     cvZero(gray_image);
    118     cvZero(rgb_image);
    119  
    120     cvCvtColor(src,gray_image,CV_RGB2GRAY);
    121         
    122     cvCvtColor(gray_image,rgb_image,CV_GRAY2BGR);
    123     
    124  
    125     CvMemStorage *storage = cvCreateMemStorage(0);
    126     CvSeq *first_contours = NULL,*temp_contours = NULL;
    127  
    128     int n = cvFindContours(gray_image,storage,&first_contours,sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);
    129     printf("n = %d\n",n);
    130     
    131     temp_contours = first_contours;
    132     
    133     for (;temp_contours != NULL; temp_contours = temp_contours->h_next)
    134     {
    135         vector <CvPoint*> pt_vec;
    136         CvPoint *pt;
    137         //cvDrawContours(rgb_image, temp_contours, CV_RGB(0, 0, 255), CV_RGB(0, 0, 255), 0,2,CV_FILLED, cvPoint(0, 0));    
    138          CvRect rc =cvBoundingRect(temp_contours,0);    
    139         
    140         cvRectangle(rgb_image, cvPoint(rc.x, rc.y), cvPoint(rc.x + rc.width, rc.y + rc.height),CV_RGB(255, 0, 0), 1, 8, 0);
    141         
    142         for (int i = 0; i < temp_contours->total;i++)
    143         {
    144             pt = (CvPoint *)cvGetSeqElem(temp_contours,i);
    145             pt_vec.push_back(pt);
    146         }
    147  
    148         double x = 0.0;
    149         double y = 0.0;
    150         double r = 0.0;
    151         vector<Box *>  box;
    152         Box box1;
    153         box1 = circleLeastFit(pt_vec);
    154         printf("%lf %lf %lf \n",box1.x,box1.y,box1.r);
    155         cvCircle(rgb_image,cvPoint(box1.x,box1.y),box1.r,cvScalar(155,255,0),5,8,0);
    156         cvCircle(rgb_image,cvPoint(box1.x,box1.y),5,cvScalar(155,255,155),5,8,0);
    157  
    158     }
    159  
    160      cvNamedWindow("32");
    161      cvShowImage("32",rgb_image);
    162      cvWaitKey(0);
    163  
    164     return 0;
    165 }
  • 相关阅读:
    HDU1029 Ignatius and the Princess IV
    UVA11039 Building designing【排序】
    UVA11039 Building designing【排序】
    POJ3278 HDU2717 Catch That Cow
    POJ3278 HDU2717 Catch That Cow
    POJ1338 Ugly Numbers(解法二)
    POJ1338 Ugly Numbers(解法二)
    UVA532 Dungeon Master
    UVA532 Dungeon Master
    POJ1915 Knight Moves
  • 原文地址:https://www.cnblogs.com/ybqjymy/p/15936245.html
Copyright © 2020-2023  润新知