用opencv函数替代skimage函数生成相似矩阵

人脸识别之前通常需要做校准工作,使得标准人脸和待识别人脸均位于"统一规范化"的条件下做比对;这里校准工作用的是相似变换SimilarityTransform【注:与仿射变换不同】,即:等距变换+均匀尺度缩放,而等距变换则是平移+旋转变换。
对应的变换矩阵:
在这里插入图片描述

目前大部分的做法是:采用python库中的skimage.transform模块生成变换矩阵,再利用opencv中的仿射变换函数cv2.warpAffine,将img生成"标准人脸"dst;过程如下:

from skimage import transform as trans
import numpy as np
import cv2
src = np.array([
    [38.2946, 51.6963],
    [73.5318, 51.5014],
    [56.0252, 71.7366],
    [41.5493, 92.3655],
    [70.7299, 92.2041] ], dtype=np.float32)
dst = np.array([
    [30, 50],
    [72, 51],
    [5672],
    [41, 92],
    [71, 92] ], dtype=np.float32)
tform = trans.SimilarityTransform()
res =tform.estimate(dst, src)
M = tform.params
dst = cv2.warpAffine(img, M, (img_im.shape[1], img_im.shape[0]))

最近在工程化过程中,需要把opencv库移植到硬件上,但由于生成的相似矩阵是调用skimage库生成的,所以工程需要移植两个库,比较麻烦。现在需求是直接用opencv库生成相似矩阵,这样就只需一个库就行了。
网上查看了不少资料,发现cv2中求变换矩阵的函数太多了,最终发现了对应的相似变换函数:
python2中的opencv库对应的生成相似矩阵函数是cv2.estimateRigidTransform,但该函数只能输入3个点用于生成相似矩阵,而且鲁棒性差,误差值大的点,容易生成失败。猜想主要是这个原因导致大家一直都用skimage库,而不用opencv库。
python3中opencv库对应的函数是estimateAffinePartial2D,但该函数直接使用有坑。需要指定迭代的方法,否则采用默认的cv2.RANSAC方法只会用到两组对应点用于迭代,估计的得到的结果与skimage库几乎完全不一致,仔细看了estimateAffinePartial2D介绍,并尝试发现,设定cv2.LMEND为评估方法,则结果和skimage库几乎完全一致,(小数点后好好好好好几位都一致).具体使用

M_cv=cv2.estimateAffinePartial2D(dst,src,method=cv2.LMEND)
M=M[0]

另外,附一个网友提供的c++版本,用opencv库直接搭出skimage.SimilarityTransform的实现:skimage-SimilarityTransform的C++实现
验证可用。


有帮助点个赞

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值