//计算圆的圆心,输入为自定义图片类input,输出为三元组(x,y,r) //对input的限制:只包含单圆环 public circle doFind(myPicture input) { //从圆周上对称取10组点 int cnt = 0; LinkedList <myPair> arr = new LinkedList <myPair>(); for (int i = 2; i < input.width; i += 8) { for (int j = 5; j < input.height; ++j) { if (input.grayDegree[i, j] == 255) { cnt++; arr.AddLast(new myPair(i, j)); for (int k = input.height - 5; k >= 0; --k) { if (input.grayDegree[i, k] == 255) { arr.AddLast(new myPair(i, k)); break; } } break; } } if (cnt == 10) { break; } } //最小二乘法求解圆心 A = new matrix(2 * cnt, 3); AT = new matrix(3, 2 * cnt); B = new matrix(2 * cnt, 1); int cur = 0; foreach (myPair p in arr) { int x = p.x; int y = p.y; A.a[cur, 0] = x; A.a[cur, 1] = y; A.a[cur, 2] = 1; AT.a[0, cur] = x; AT.a[1, cur] = y; AT.a[2, cur] = 1; B.a[cur, 0] = 1.0 * x * x + 1.0 * y * y; cur++; } matrix coef = AT.doMul(A); matrix b = AT.doMul(B); matrix mat = new matrix(3, 4); for (int i = 0; i < 3; ++i) { for (int j = 0; j < 3; ++j) { mat.a[i, j] = coef.a[i, j]; } } mat.a[0, 3] = b.a[0, 0]; mat.a[1, 3] = b.a[1, 0]; mat.a[2, 3] = b.a[2, 0]; return(cal(mat)); }