一杯清酒邀明月
天下本无事,庸人扰之而烦耳。
  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 }

 

posted on 2022-02-25 15:20  一杯清酒邀明月  阅读(2000)  评论(0编辑  收藏  举报