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 }