这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 企业专区 » OpenVINO生态社区 » 【原创】OpenCV-Python系列之单应性查找对象实战篇(五十五)

共2条 1/1 1 跳转至

【原创】OpenCV-Python系列之单应性查找对象实战篇(五十五)

高工
2020-08-05 17:14:51     打赏

OpenCV-Python系列之单应性查找对象实战篇

之前我们讨论到cv2.findHomography()函数里有四个算法,这次我们来简述最后两个算法。

LMEDS

LMEDS又称最小中值平方法,LMedS的经典步骤是:

1. 随机采样

2. 计算模型参数

3. 计算相对模型的点集偏差err,并求出偏差中值Med(err)

4. 迭代2. 3.步直至获得符合阈值的最优解:Med(err)最小

5. 精确优化模型参数(LM算法迭代优化)

LMedS的函数接口 参照OpenCV来说主要需要2-3个参数(第三个不是必须的)

1. 置信度confidence:设置之后代表RANSAC采样n次过程中会出现(至少一次)采样点数据集中的点都为内点的概率,这个值设置的太大,会增加采样次数。太小,会使结果不太理想。一般取0.95-0.99

2. 最大采样迭代次数maxIters:为了防止一直在采样计算

3.最大精细迭代次数refineIters:在采样之后,选取最优解。可以增加精确优化,比如使用LM算法获得更优解。

RANSAC的阈值在具有物理意义或者几何意义的时候比较容易确定,但是当阈值不具有这些特征的时候,就成了一个不太好调整的参数了。这时LMedS可以自适应迭代获得最优解。

PROSAC

渐进一致采样法(PROSAC) 是对经典的 RANSAC中采样的一种优化。相比经典的 RANSAC 方法均匀地从整个集合中采样,PROSAC 方法是从不断增大的最佳对应点集合中进行采样的。所以这种方法可以节省计算量,提高运行速度。由于涉及到机器学习相关的知识,在这里并不过多的详述,我们看一下原论文作者的算法:

image.png

OpenCV中的使用

基本步骤

1)使用SHIT检测特征点

2)使用FLANN匹配器进行匹配

3)选取好的匹配

4)根据原图像和目标图像中对应的特征点,使用上述其中一种算法求变换矩阵

5)最后将原图像的边界经变换矩阵变换后画到目标图像上

获取变换矩阵的函数:

retval, mask = cv2.findHomography(srcPoints, dstPoints, method, ransacReprojThreshold, maxIters, confidence)

·         retval输出的矩阵

·         srcPoints原图像中对应的特征点坐标

·         dstPoints目标图像中对应的特征点坐标

·         method计算单应矩阵的方法,总共包括:

                       0使用所有点的常规方法,即最小二乘法

                       RANSAC基于RANSAC的方法

                       LMEDS最小中值稳健方法

                       RHO基于PROSAC的方法

·         ransacReprojThreshold将点对视为内点的最大允许重投影错误(仅用于RANSACRHO方法)。也就是说,如果

\left \| dstPoints_{i} - convertPointsHomogeneous (H*srcPoints_{i}) \right \|_{2}> ransacReprojThreshold 那么点被认为是异常。如果以像素为单位测量srcPointsdstPoints,则将此参数设置在110的范围内通常是有意义的。

·         mask可选输出掩码由稳健方法(RANSACLMEDS)设置。

·         maxItersRANSAC迭代的最大数量。

·         confidence置信水平,介于01之间。

现在我们使用示例图片,模板图片:

image.png

原图:

image.png

现在我们来看代码:

import numpy as np
 import cv2
 from matplotlib import pyplot as plt
 
 MIN_MATCH_COUNT = 10
 img1 = cv2.imread('box.png', 0)  # 
原图像
 img2 = cv2.imread('box_in_scene.png', 0)  # 
待搜索图像,下面称目标图像
 # 
启动
SIFT
检测器
 sift = cv2.xfeatures2d.SIFT_create()
 # 
使用
SIFT
查找关键点和描述符
 kp1, des1 = sift.detectAndCompute(img1, None)
 kp2, des2 = sift.detectAndCompute(img2, None)
 
 # 
使用
FLANN
匹配器进行匹配
 FLANN_INDEX_KDTREE = 1
 index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5)
 search_params = dict(checks=50)
 flann = cv2.FlannBasedMatcher(index_params, search_params)
 matches = flann.knnMatch(des1, des2, k=2)  # 
获得匹配结果
 
 # 
按照
Lowe
的比率存储所有好的匹配。
 good = []
 for m, n in matches:
     if m.distance < 0.7 * n.distance:
         good.append(m)
 
 # 
只有好的匹配点多于
10
个才查找目标,否则显示匹配不足
 if len(good) > MIN_MATCH_COUNT:
     # 
获取匹配点在原图像和目标图像中的的位置
     # kp1
:原图像的特征点
     # m.queryIdx
:匹配点在原图像特征点中的索引
     # .pt
:特征点的坐标
     src_pts = np.float32([kp1[m.queryIdx].pt for m in good]).reshape(-1, 1, 2)
     dst_pts = np.float32([kp2[m.trainIdx].pt for m in good]).reshape(-1, 1, 2)
     # 
获取变换矩阵,采用
RANSAC
算法
     M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)
     matchesMask = mask.ravel().tolist()
     # 
图像变换,将原图像变换为检测图像中匹配到的形状
     # 
获得原图像尺寸
     h, w = img1.shape
     # 
使用得到的变换矩阵对原图像的四个角进行变换,获得在目标图像上对应的坐标。
     pts = np.float32([[0, 0], [0, h - 1], [w - 1, h - 1], [w - 1, 0]]
                      ).reshape(-1, 1, 2)
     # 
对角点进行变换
     dst = cv2.perspectiveTransform(pts, M)
     # 
画出边框
     img2 = cv2.polylines(img2, [np.int32(dst)], True, 255, 5, cv2.LINE_AA)
 else:
     print("Not enough matches are found - {}/{}".format(len(good), MIN_MATCH_COUNT))
     matchesMask = None
 
 # 
画出匹配点
 draw_params = dict(matchColor=(0, 0, 255),  # draw matches in green color
                    singlePointColor=None,
                    matchesMask=matchesMask,  # draw only inliers
                    flags=2)
 img3 = cv2.drawMatches(img1, kp1, img2, kp2, good, None, **draw_params)
 plt.imshow(img3), plt.title('Result'),
 plt.axis('off')
 plt.show()

结果:

image.png

可以看到,即便是在诸多的干扰性的图像中,特征匹配仍然相当的准确。目前此代码只实验了RANSAC算法,至于我们之前讲到的其他的算法,大家自行实验。

 


对计算机视觉感兴趣?这个社区推荐给你~

>>点击了解OpenVINO生态开发社区



工程师
2020-08-05 23:06:19     打赏
2楼

期待继续更新


共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]