我的应用程序应该使用欧元硬币作为参考估计对象的长度(以毫米为单位)。这是一个截图示例:
为了获得拍摄硬币的直径,我首先计算通过这3个点的圆的方程式
x^2 + y^2 + ax + by + c = 0
然后我的直径
2 * square_root((a/2)^2 + (b/2)^2 -c)
。
最后,我可以执行以下比例来获得红笔的长度:
/* length_estimated_pen (mm) : distance_green_pins (points) = real_diameter_coin (mm) : diameter_on_screen (points) */
let distanceGreen:Double = Double(sqrt(pow(self.greenLocationA.center.x - self.greenLocationB.center.x, 2.0) + pow(self.greenLocationA.center.y - self.greenLocationB.center.y, 2.0)))
let estimatedMeasure:Double = (distanceGreen * Double(ChosenMeter.moneyDiameter)) / diameter
在ChosenMeter.moneyDiameter
中,存储所选硬币的实际直径作为参考(通过单击下面3个按钮之一)。
我需要使用Double
代替CGFloat
因为this教程来解决线性方程组(得到a,b,c系数的圆方程)与Double一起使用
问题是红笔的估计长度总是被高估 超过10毫米。 我想我应该考虑其他因素来应用校正因子或使微积分复杂化,但是哪个?你能给我一些提示吗?任何帮助对我都有用。
答案 0 :(得分:3)
找到硬币(green
边界框矩形)
手动或通过某些搜索特定的颜色,图案,霍夫变换,分割...这将限制搜索后续步骤的区域
找到边界(颜色强度明显red
边缘)
所以创建一个作为硬币边界的点列表(小心阴影),只需扫描足够高的强度凸起。
计算圈子中心
所有边境点的平均值......
测试min/max
到中心距离的所有边界点
如果倾斜很小,那么你将有许多具有最小和最大半径的点,所以从它们中间取出。如果|max-min|
非常小,那么你就没有倾斜。最小/最大距离点和中心之间的线为您提供black
基础向量。
使用black
基础向量来衡量
因此,选择2个点(red
d行)来测量和投射green
光线并与基础矢量平行。他们的交集将创建2
行a,b
。很容易:
d = sqrt((a*a)+(b*b))
其中a,b
是单位行的大小。你可以像以下一样获得它:
a_size_unit = a_size_pixel * coin_r_unit / rmax_pixel
b_size_unit = b_size_pixel * coin_r_unit / rmin_pixel
<强> [注] 强>
选择此图像是为了强调歪斜,但是您应该使用几乎平行于芯片表面的平面图像,以避免透视变形。这个图像不是一个很好的例子,立方体距离相机更远,然后硬币...