画极线

OpenCV学习日记5

2017-05-27 10:44:35 1000sprites 阅读数 2339更多

分类专栏: 计算机视觉

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/shengshengwang/article/details/72779289

1. solvePnP,cvPOSIT(过时),solvePnPRansac [1][2]

解析:给定物体3D点集与对应的图像2D点集,以及摄像头内参数的情况下计算物体的3D姿态。solvePnP和cvPOSIT

的输出都是旋转矩阵和位移向量,不过solvePnP是精确解,cvPOSIT是近似解。因为solvePnP调用的是

cvFindExtrinsicCameraParams2,通过已知的内参进行未知外参求解;而cvPOSIT是用仿射投影模型近似透视投影模

型,不断迭代计算出估计值(在物体深度变化相对于物体到摄像机的距离比较大时,该算法可能不收敛)。

solvePnP和solvePnPRansac函数原型,如下所示:

(1)cv2.solvePnP(objectPoints, imagePoints, cameraMatrix, distCoeffs[, rvec[, tvec[, useExtrinsicGuess[, flags]]]]) 

→ retval, rvec, tvec

(2)cv2.solvePnPRansac(objectPoints, imagePoints, cameraMatrix, distCoeffs[, rvec[, tvec[, useExtrinsicGuess[, 

iterationsCount[, reprojectionError[, minInliersCount[, inliers[, flags]]]]]]]]) → rvec, tvec, inliers

 

2. 对极几何(Epipolar Geometry)

解析:

在双目立体视觉系统中,有两个摄像机在不同角度拍摄物理空间中的同一实体点,在两副图像上分别有两个成像点。

立体匹配就是已知其中的一个成像点,在另一副图像上找出该成像点的对应点。极线几何约束是一种常用的匹配约束

技术,它是一种点对直线的约束,将对应点匹配从整幅图像寻找压缩到在一条直线上寻找。

 
  1. import cv2

  2. import numpy as np

  3. from matplotlib import pyplot as plt

  4.  
  5. img1 = cv2.imread('myleft.jpg',0) #queryimage # left image

  6. img2 = cv2.imread('myright.jpg',0) #trainimage # right image

  7.  
  8. sift = cv2.SIFT()

  9. # find the keypoints and descriptors with SIFT

  10. kp1, des1 = sift.detectAndCompute(img1,None)

  11. kp2, des2 = sift.detectAndCompute(img2,None)

  12.  
  13. # FLANN parameters

  14. FLANN_INDEX_KDTREE = 0

  15. index_params = dict(algorithm=FLANN_INDEX_KDTREE,trees=5)

  16. search_params = dict(checks=50)

  17. flann = cv2.FlannBasedMatcher(index_params,search_params)

  18. matches = flann.knnMatch(des1,des2,k=2)

  19.  
  20. good = []

  21. pts1 = []

  22. pts2 = []

  23.  
  24. # ratio test as per Lowe's paper

  25. for i,(m,n) in enumerate(matches):

  26. if m.distance < 0.8*n.distance:

  27. good.append(m)

  28. pts2.append(kp2[m.trainIdx].pt)

  29. pts1.append(kp1[m.queryIdx].pt)

  30.  
  31. pts1 = np.float32(pts1)

  32. pts2 = np.float32(pts2)

  33. F, mask = cv2.findFundamentalMat(pts1,pts2,cv2.FM_LMEDS)

  34.  
  35. # we select only inlier points

  36. pts1 = pts1[mask.ravel()==1]

  37. pts2 = pts2[mask.ravel()==1]

  38.  
  39. def drawlines(img1,img2,lines,pts1,pts2):

  40. ''' img1 - image on which we draw the epilines for the points in img2

  41. lines - corresponding epilines

  42. '''

  43. r,c = img1.shape

  44. img1 = cv2.cvtColor(img1,cv2.COLOR_GRAY2BGR)

  45. img2 = cv2.cvtColor(img2,cv2.COLOR_GRAY2BGR)

  46. for r,pt1,pt2 in zip(lines,pts1,pts2):

  47. color = tuple(np.random.randint(0,255,3).tolist())

  48. x0,y0 = map(int, [0,-r[2]/r[1]])

  49. x1,y1 = map(int, [c,-(r[2]+r[0]*c)/r[1]])

  50. img1 = cv2.line(img1, (x0,y0), (x1,y1), color, 1)

  51. img1 = cv2.circle(img1,tuple(pt1),5,color,-1)

  52. img2 = cv2.circle(img2,tuple(pt2),5,color,-1)

  53. return img1,img2

  54.  
  55. # find epilines corresponding to points in right image (second image) and

  56. # drawing its lines on left image

  57. lines1 = cv2.computeCorrespondEpilines(pts2.reshape(-1,1,2), 2,F)

  58. lines1 = lines1.reshape(-1,3)

  59. img5,img6 = drawlines(img1,img2,lines1,pts1,pts2)

  60.  
  61. # find epilines corresponding to points in left image (first image) and

  62. # drawing its lines on right image

  63. lines2 = cv2.computeCorrespondEpilines(pts1.reshape(-1,1,2), 1,F)

  64. lines2 = lines2.reshape(-1,3)

  65. img3,img4 = drawlines(img2,img1,lines2,pts2,pts1)

  66.  
  67. plt.subplot(121),plt.imshow(img5)

  68. plt.subplot(122),plt.imshow(img3)

  69. plt.show()

结果输出,如下所示:

说明:findFundamentalMat和computeCorrespondEpilines函数原型,如下所示:

(1)cv2.findFundamentalMat(points1, points2[, method[, param1[, param2[, mask]]]]) → retval, mask

(2)cv2.computeCorrespondEpilines(points, whichImage, F[, lines]) → lines

 

3. 立体图像中的深度地图

解析:如果同一场景有两幅图像,那么就可以获得图像的深度信息。如下所示:

构建立体图像中的深度地图过程,如下所示:

 
  1. import cv2

  2. from matplotlib import pyplot as plt

  3.  
  4. imgL = cv2.imread('tsukuba_l.png',0)

  5. imgR = cv2.imread('tsukuba_r.png',0)

  6. stereo = cv2.createStereoBM(numDisparities=16, blockSize=15)

  7. disparity = stereo.compute(imgL,imgR)

  8. plt.imshow(disparity,'gray')

  9. plt.show()

结果输出,如下所示:

说明:左侧为原始图像,右侧为深度图像。结果中的噪音可以通过调整numDisparities和blockSize得到更好的结果。

createStereoBM函数原型为cv2.createStereoBM([numDisparities[, blockSize]]) → retval。

 

4. BRIEF算子详解 [4]

解析:BRIEF(Binary Robust Independent Elementary Features)是一种对特征点描述子计算和匹配的快速方法,

但它不提供查找特征的方法,原始文献推荐使用CenSurE特征检测器。同时它不具备旋转不变性和尺度不变性而且对

噪声敏感。如下所示:

 
  1. import cv2

  2.  
  3. img = cv2.imread('simple.jpg',0)

  4. # initiate STAR detector

  5. star = cv2.FeatureDetector_create("STAR")

  6. # initiate BRIEF extractor

  7. brief = cv2.DescriptorExtractor_create("BRIEF")

  8. # find the keypoints with STAR

  9. kp = star.detect(img,None)

  10. # compute the descriptors with BRIEF

  11. kp, des = brief.compute(img, kp)

  12. print brief.getInt('bytes')

  13. print des.shape

说明:在OpenCV中CenSurE检测器叫做STAR检测器。

 

5.opencv-4.0.0和Windows 7:ImportError: ERROR: recursion is detected during loading of "cv2" binary extensions. Check OpenCV installation

解析:

(1)将D:\opencv-4.0.0\build\python\cv2\python-3.6\cv2.cp36-win_amd64.pyd修改为cv2.pyd,然后拷贝到D:\Anaconda3\Lib\site-packages目录。

(2)将D:\opencv-4.0.0\build\x64\vc15\bin目录下的.dll文件拷贝到D:\Anaconda3\Library\bin目录。

 

参考文献:

[1] Camera Calibration and 3D Reconstruction:

http://docs.opencv.org/2.4/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html

[2] 三维姿态:关于solvePnP与cvPOSIT:http://blog.csdn.net/abc20002929/article/details/8520063

[3] 极线约束(epipolar constraint):http://blog.csdn.net/tianwaifeimao/article/details/19544861

[4] createStereoBM:http://docs.opencv.org/3.0-

beta/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html#cv2.createStereoBM

[5] 特征工程BRIEF:http://dnntool.com/2017/03/27/brief/

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值