• 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 }
  • 相关阅读:
    python入门-函数(二)
    python入门-函数(一)
    python入门-WHILE循环
    python入门-用户输入
    python入门-字典
    Spring Security授权 AccessDecisionManager
    Java的性能优化
    datahub
    vbs mytest
    spring发布和接收定制的事件(spring事件传播)
  • 原文地址:https://www.cnblogs.com/ybqjymy/p/15936245.html
Copyright © 2020-2023  润新知