当前位置:   article > 正文

点云拟合平面原理和实现(Halcon)_get_object_model_3d_params

get_object_model_3d_params

最近学习了一下拟合平面的原理,看了这篇文章最小二乘拟合平面(C++版) - 知乎

讲到了以下几种方法,我这里在halcon中对其一一实现。

一、算法原理

1,直接求解法

2.使用拉格朗日乘子法

3 SVD分解法  

二、Halcon实现

1.各方法对比

在halcon中其实有对应的算子直接实现拟合平面Ax+By+C=D

如fit_primitives_object_model_3d 

我这里取了一张点云图,对其中一小块点云进行平面拟合测试

取红色圈内一部分数据测试

直接使用halcon算子 fit_primitives_object_model_3d得到的结果

[0.376856, -0.602116, -0.703873, -0.553981]

使用拉格朗日乘子的那个方法得到的结果

[0.376856, -0.602116, -0.703873, -0.553981]

第一个直接求解法得到的结果

[0.376656, -0.601768, -0.704277, -0.554283]

用SVD方法求解的结果

[-0.376856, 0.602116, 0.703873, 0.553981]

结果都一样,除了那个直接求解法的,没有做去质心处理,可能有点细微的差别

2.halcon代码

  1. read_image (XYZ, '3d_machine_vision/segmentation/3d_primitives_xyz_01.tif')
  2. access_channel (XYZ, X, 1)
  3. access_channel (XYZ, Y, 2)
  4. access_channel (XYZ, Z, 3)
  5. gen_ellipse (ROI_0, 84.5473, 95.7705, rad(-35.9506), 10.9232, 8.60448)
  6. reduce_domain (Z, ROI_0, ImageReduced)
  7. xyz_to_object_model_3d (X, Y, ImageReduced, ObjectModel3D)
  8. *直接使用halcon拟合平面算子处理
  9. fit_primitives_object_model_3d (ObjectModel3D, 'primitive_type', 'plane', ObjectModel3DOut)
  10. get_object_model_3d_params (ObjectModel3DOut, 'primitive_parameter', Result1)
  11. get_object_model_3d_params (ObjectModel3DOut, 'primitive_rms', GenParamValue1)
  12. *获取截取的3d模型x、y、z的坐标值
  13. get_object_model_3d_params (ObjectModel3D, 'point_coord_x', pX)
  14. get_object_model_3d_params (ObjectModel3D, 'point_coord_y', pY)
  15. get_object_model_3d_params (ObjectModel3D, 'point_coord_z', pZ)
  16. *测试用拉格朗日乘子法
  17. Num:=|pX|
  18. *求均值
  19. XM:=mean(pX)
  20. YM:=mean(pY)
  21. ZM:=mean(pZ)
  22. *去质心
  23. DX:=pX-XM
  24. DY:=pY-YM
  25. DZ:=pZ-ZM
  26. *求矩阵各个位置的值
  27. MA11 := sum(DX * DX)
  28. MA22 := sum(DY * DY)
  29. MA33 := sum(DZ * DZ)
  30. MA12 := sum(DX * DY)
  31. MA13 := sum(DX * DZ)
  32. MA23 := sum(DY * DZ)
  33. create_matrix (3, 3, [MA11,MA12,MA13,MA12,MA22,MA23,MA13,MA23,MA33], MatrixID)
  34. *实对称矩阵,求特征值和特征向量
  35. eigenvalues_symmetric_matrix (MatrixID, 'true', EigenvaluesID, EigenvectorsID)
  36. *特征值按小到大排列,所以平面法向量是第一列特征向量
  37. get_value_matrix (EigenvectorsID, 0, 0, NX)
  38. get_value_matrix (EigenvectorsID, 1, 0, NY)
  39. get_value_matrix (EigenvectorsID, 2, 0, NZ)
  40. *算C 平面方程NX*X+NY*Y+NZ*Z=C
  41. C := NX * XM + NY * YM + NZ * ZM
  42. Result2:=[NX,NY,NZ,C]
  43. *对应使用直接求解法
  44. *算矩阵各个位置的值
  45. MB11:=sum(pX*pX)
  46. MB12:=sum(pX*pY)
  47. MB13:=sum(pX)
  48. MB22:=sum(pY*pY)
  49. MB23:=sum(pY)
  50. MB33:=|pX|
  51. MC1:=sum(pX*pZ)
  52. MC2:=sum(pY*pZ)
  53. MC3:=sum(pZ)
  54. create_matrix (3, 3, [MB11,MB12,MB13,MB12,MB22,MB23,MB13,MB23,MB33], MB)
  55. create_matrix (3, 1, [MC1,MC2,MC3], MC)
  56. solve_matrix (MB, 'general', 0, MC, MatrixResultID)
  57. get_full_matrix (MatrixResultID, Values)
  58. *要求a^2+b^2+c^2=1 求解真正的a、c
  59. dd:=Values[0]*Values[0]+Values[1]*Values[1]+1
  60. a:=Values[0]/sqrt(dd)
  61. b:=Values[1]/sqrt(dd)
  62. c:=-1/sqrt(dd)
  63. *因为这里的平面方程为a*x+b*y+c*z=d 与文章中方程A*x+B*y+C*z+D=0中d相差个负号,所以
  64. d:=-Values[2]/sqrt(dd)
  65. Result3:=[a,b,c,d]
  66. *SVD分解法
  67. create_matrix (3, Num, [DX,DY,DZ], A)
  68. transpose_matrix_mod (A)
  69. svd_matrix (A, 'full', 'both', U, S, V)
  70. get_full_matrix (V, VValues)
  71. get_value_matrix (V, 0, 2, Value1)
  72. get_value_matrix (V, 1, 2, Value2)
  73. get_value_matrix (V, 2, 2, Value3)
  74. Value4:=Value1*XM+Value2*YM+Value3*ZM
  75. Result4:=[Value1,Value2,Value3,Value4]

那个求各个位置的值,可以直接用矩阵相乘好了,简写成

  1. *求特征向量法
  2. create_matrix(3,Num,[DX,DY,DZ],B)
  3. mult_matrix (B, B, 'ABT', MatrixMultID)
  4. eigenvalues_symmetric_matrix (MatrixMultID, 'true', EigenvaluesID1, EigenvectorsID1)
  5. get_full_matrix (EigenvectorsID1, Values3)
  6. aa:=Values3[0]
  7. bb:=Values3[3]
  8. cc:=Values3[6]
  9. dd:=aa*XM+bb*YM+cc*ZM
  10. Result5:=[aa,bb,cc,dd]

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/109076
推荐阅读
相关标签
  

闽ICP备14008679号