当前位置:   article > 正文

使用opencv-python的薄板样条插值(ThinPlateSpline)实现图像和坐标变换_python薄板样条差值代码

python薄板样条差值代码

使用opencv-python的薄板样条插值(tps)实现图像和坐标变换

自己用opencv-python做基于薄板样条图像配准时踩了不少坑。网上现有关于thinplatetransformer的内容太少,这里跟大家分享下错误经验。

opencv安装

需要注意opencv-python、opencv-python-contrib、numpy版本一定要匹配,不然会出现查看不了注释的情况,详见: Pycharm配置opencv与numpy

我是用的版本是如下:
python-3.8.0
numpy-1.22.4+kml
opencv&opencv-contrib-4.5.5 (.62)

如果想自己下可以点击这里:
在这里插入图片描述
在这里插入图片描述

tps模块使用方法

类说明文档: ThinPlateSplineShapeTransformer OpenCV Documentation

我自己写的例程如下:

  1. def TPSTransformWithPoints(pts1, pts2, img=None, ptm=None):
  2. """
  3. Editor: 五月的白杨 CSDN
  4. Perform thin plate spline transform
  5. inputs:
  6. pts1---marker points on moving image, with size (m,2), ndarray, dtpye numeric, float or int
  7. pts2---marker points on fixed image, with size (m,2), ndarray, dtpye numeric, float or int
  8. img ---moving image, an cv2 image
  9. ptm ---other points needed to be transformed on moving image,
  10. outputs:
  11. result registrated moving image
  12. p_iter registrated points of moving image
  13. """
  14. m = pts1.shape[0]
  15. # Reshape pts1 & pts2
  16. pts1 = pts1.reshape(1, -1, 2)
  17. pts2 = pts2.reshape(1, -1, 2)
  18. matches = []
  19. # Create Matches
  20. for i in range(m):
  21. matches.append(cv2.DMatch(i, i, 0))
  22. # Estimate Transformation
  23. tps_img = cv2.createThinPlateSplineShapeTransformer()
  24. tps_pts = cv2.createThinPlateSplineShapeTransformer()
  25. tps_img.estimateTransformation(pts2, pts1, matches)
  26. tps_pts.estimateTransformation(pts1, pts2, matches)
  27. # Outputs
  28. p = ptm.reshape(1, -1, 2)
  29. if ptm is not None:
  30. p_iter_tps = tps_pts.applyTransformation(p)
  31. else:
  32. p_iter_tps = None
  33. if img is not None:
  34. result_tps = tps_img.warpImage(img)
  35. else:
  36. result_tps = None
  37. return result_tps, p_iter_tps

注意事项:

1. 创建对象一般用 cv2.createThinPlateSplineShapeTransformer(),用到的函数为estimateTransformation(),但我这里对浮动图像(img)做变换和对浮动图像上的点(pts)做变换,使用了两个transformer对象: tps_img 和 tps_pts 分别算了一次。

原因是opencv封装的ThinPlateSpline模块从2017年就有一个没修的bug,estimatetransformation的说明文档的输入顺序如下:source_points,target_points,matches. 但开发者搞反了输入顺序,如果对图像变换,source 和 target 点应该互换,但对浮动图像选的点做变换又是正确的(崩溃)参考这个opencv的issue: 点此查看 https://github.com/opencv/opencv/issues/7084

简而言之

  1. # 对图像变换用这个
  2. tps_img = cv2.createThinPlateSplineShapeTransformer()
  3. tps_img.estimateTransformation(target_points, source_points, matches)
  4. pts = tps_img.warpImage(img)
  5. # 对点变换用这个
  6. tps_pts = cv2.createThinPlateSplineShapeTransformer()
  7. tps_pts.estimateTransformation(source_points, target_points, matches)
  8. pts = tps_pts.applyTransformation(p)
  9. """两个target和source的顺序是相反的"""

2.  如果输入的pts1 pts2为(m,2)的ndarray,下面两句是必要的,因为opencv的ThinPlateSpline模块estimateTransformation只接受输入为(1,m,2)的tuple貌似,不然就会报错

  1. pts1 = pts1.reshape(1, -1, 2)
  2. pts2 = pts2.reshape(1, -1, 2)

3. 最后补充一个注意事项,输入的坐标点必须转为np.float32 np.float32 np.float32 重要的事情说三遍,不然真的被坑惨了。。。

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

闽ICP备14008679号