Epipolar Geometry
จาก Morange Wiki
Epipolar Geometry
วัตถุประสงค์
- เรียนรู้เกี่ยวกับการใช้งาน multiview geometry แบบพื้นฐาน
- เพื่อรู้และแยกแยะระหว่าง epipole , epipolar line , epipolar constraint และอื่นๆ
Basic Concepts
- เมื่อนำรูปมาเข้ากระบวนการ pin-hole camera เราจะสูญเสียความสำคัญของสารสนเทศไปเช่น ความลึกของภาพ หรือ ระยะห่างของจุดในรูปภาพ หากนำเข้าโดยกล้องธรรมดาและนำมาเข้ากระบวนการ 3D-to-2D conversion
- เพื่อให้เห็นถึงความสำคัญของสิ่งเหล่านั้นโดย การหา ความลึกของของรูปนั้นด้วยกล้อง และจะสามารถใช้กล้องมากกว่าหลายๆตัวมาช่วยให้สามารถหาความลึกและโดยวิธีนี้เรียก stereo vision โดยใน OpenCV นั้นจะมีการทำไว้แล้ว
- (Learning OpenCV by Gary Bradsky has a lot of information in this field.)
- ก่อนจะหาความลึกของรูปภาพนั้น อันดับแรกจะต้องเข้าใจแนวคิดพื้นฐานของโปรแกรมหรือสูตรในรูปแบบ เรขาคณิตของ MultiView ในส่วนนี้จะสามารถจัดการกับรูปภาพต่างๆเพื่อหาค่าที่ต้องการในรูปรงเรขาคณิตหรือ epipolar โดยดูจากภาพด้านล่างนี้เพื่อให้เห็นภาพได้ชัดเจนมากขึ้น
มีข้อผิดพลาดในการสร้างรูปย่อ: ไฟล์สูญหาย
มีข้อผิดพลาดในการสร้างรูปย่อ: ไฟล์สูญหาย
Code Example
import cv2 import numpy as np from matplotlib import pyplot as plt img1 = cv2.imread('myleft.jpg',0) #queryimage # left image img2 = cv2.imread('myright.jpg',0) #trainimage # right image sift = cv2.SIFT() # find the keypoints and descriptors with SIFT kp1, des1 = sift.detectAndCompute(img1,None) kp2, des2 = sift.detectAndCompute(img2,None) # FLANN parameters FLANN_INDEX_KDTREE = 0 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) good = [] pts1 = [] pts2 = [] # ratio test as per Lowe's paper for i,(m,n) in enumerate(matches): if m.distance < 0.8*n.distance: good.append(m) pts2.append(kp2[m.trainIdx].pt) pts1.append(kp1[m.queryIdx].pt)
- ต่อมาจะทำการนำรูปรวมหาเมทริกซ์พื้นฐาน
pts1 = np.int32(pts1) pts2 = np.int32(pts2) F, mask = cv2.findFundamentalMat(pts1,pts2,cv2.FM_LMEDS) # We select only inlier points pts1 = pts1[mask.ravel()==1] pts2 = pts2[mask.ravel()==1]
- และจะพบ Epilines โดนจะสอดคล้องกับจุดในภาพแรกที่มีการวาดลงบนภาพที่สอง ดังนั้นการ Mentioning of correct image เป็นสิ่งที่สำคัญ โดยจะได้ผลลัพธ์เป็น Array of line และจะนำมาวาดเส้นบนรูปภาพ
def drawlines(img1,img2,lines,pts1,pts2): ''' img1 - image on which we draw the epilines for the points in img2 lines - corresponding epilines ''' r,c = img1.shape img1 = cv2.cvtColor(img1,cv2.COLOR_GRAY2BGR) img2 = cv2.cvtColor(img2,cv2.COLOR_GRAY2BGR) for r,pt1,pt2 in zip(lines,pts1,pts2): color = tuple(np.random.randint(0,255,3).tolist()) x0,y0 = map(int, [0, -r[2]/r[1] ]) x1,y1 = map(int, [c, -(r[2]+r[0]*c)/r[1] ]) img1 = cv2.line(img1, (x0,y0), (x1,y1), color,1) img1 = cv2.circle(img1,tuple(pt1),5,color,-1) img2 = cv2.circle(img2,tuple(pt2),5,color,-1) return img1,img2
- ต่อมาจะหา epilines ในรูป และทำการวาดเส้นลง
# Find epilines corresponding to points in right image (second image) and # drawing its lines on left image lines1 = cv2.computeCorrespondEpilines(pts2.reshape(-1,1,2), 2,F) lines1 = lines1.reshape(-1,3) img5,img6 = drawlines(img1,img2,lines1,pts1,pts2) # Find epilines corresponding to points in left image (first image) and # drawing its lines on right image lines2 = cv2.computeCorrespondEpilines(pts1.reshape(-1,1,2), 1,F) lines2 = lines2.reshape(-1,3) img3,img4 = drawlines(img2,img1,lines2,pts2,pts1) plt.subplot(121),plt.imshow(img5) plt.subplot(122),plt.imshow(img3) plt.show()