赞
踩
最近有个项目用到了TPS算子,即薄板函数模型进行图像几何纠正。opencv中的TPS算子接口并不复杂,主要是在opencv中输入特征匹配点的数据类型有很多种,而opencv封装的TPS算子的输入数据类型只能是Point2f。目前用到的很少,所以资料很少,为大家在进行研究的时候避坑,特写此文。具体理论可以参考论文:On the Bijectivity of Thin-Plate Splines,Anders P. Erikson and Kalle A° stro¨m。
本人写的测试代码如下:https://download.csdn.net/download/qq_29860971/11025391
前面我是用了一个SIFT特征匹配,注意这里用到特征点是KeyPoint类型的
vector<KeyPoint> keypoints_pattern, keypoints_target; //存放SIFT特征点
之后进行了一个匹配点筛选,效果如下
可以看出两幅图是有部分不同的几何扭曲的地方。
在做tps之前需要先将特征点的KeyPoint类数据通过convert转换成Point2f数据。这是非常必要的,我在这里卡了很久,最后看ThinPlateSplineShapeTransformer才发现这个问题。
vector<Point2f> TPSpoints_pattern, TPSpoints_target, testpoints; //上一步的匹配点(不同匹配算子的数据结构不同)必须转换成Point2f
KeyPoint::convert(keypoints_pattern, TPSpoints_pattern);
KeyPoint::convert(keypoints_target, TPSpoints_target);
下一步就是开始TPS纠正了,这里主要通过estimateTransformation输入模板和目标的特征点,以及前面筛选后的匹配点。下一笔通过applyTransformation对需要纠正的目标的特征点进行变形,输出变形后的特征点,这里我用respic,注意这里respic是Mat类型。最后一步warpImage就是把需要纠正的图像进行变形输出了,这里输入输出都是Mat图像。
Ptr<ThinPlateSplineShapeTransformer> tps = createThinPlateSplineShapeTransformer(0);
tps->estimateTransformation(TPSpoints_pattern, TPSpoints_target, good_matches); //匹配点拟合 接口(模板特征点,目标特征点,匹配点)
tps->applyTransformation(TPSpoints_target, respic); //匹配点变形 接口(目标特征点,输出变形后的特征点)
tps->warpImage(target, out_image);
其中,若在tps->estimateTransformation(TPSpoints_pattern, TPSpoints_target, good_matches); 出现问题中间需加入
transpose(TPSpoints_pattern, TPSpoints_pattern);
对Point2f矩阵进行转置。
最后对纠正之后的图片再进行一次特征匹配,效果如下
我们可以发现TPS算子的效果是由模板匹配决定的,匹配点越多,纠正效果越好。进一步验证可以对图片做一次减法,这里我就不继续了。
本人写的测试代码如下:https://download.csdn.net/download/qq_29860971/11025391欢迎交流讨论!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。