ä»åãã ããããã¥ã¼ããªã¢ã«éãã®å
容ã§ãã
åã
åã¨ååã§ãéãè¦ç¹ããåã対象ãæ®å½±ãã2ã¤ã®ç»åã§ã®ç¹ã®å¯¾å¿ãè¦ã¤ãããã¨ãã§ãã¾ããã
ãã®çµæã使ã£ã¦ãå°å½±å¤æã®è¡åãè¨ç®ããç»åã®è¦ç¹å¤æããããã¨ãã§ãã¾ããããããã£ã¦ã¿ã¾ãã
OpenCV: Feature Matching + Homography to find Objects
特徴点のマッチングとHomographyによる物体検出 — OpenCV-Python Tutorials 1 documentation
24.06.05 追è¨
ãã£ã¦ããã¨ãééã£ã¦ããã®ã§è¨æ£ãã¾ãã
å°å½±å¤æã«ããè¦ç¹å¤æã§ã¯ã対象ã®ç¹ããã¹ã¦1ã¤ã®å¹³é¢ã«ãªãã¨ãã¡ã§ããã
ä¸è¨è¨äºã«è¨è¼ãã¦ãã¾ãã
1ã¤ã®å¹³é¢ã«ãªãã¨ããããªæãã§ãå¤æå¾ã«ãããç¹ãåºã¦ãã¾ãã
以ä¸ãå è¨äºã¯ãã®ã¾ã¾ã«ãã¦ããã¾ãã
使ç¨ç»å
åã åãååã¨åãã·ã£ã«ãã«å¤§èå ã®ç»å3ã¤ã§ãã
ç¹å¾´ç¹ãããã³ã°
åã
åã«ãã£ãã®ã¨åããã¨ãããã¾ãã
SIFTã§ã®ãããã³ã°ãçµæãè¯ãã£ãã®ã§ãSIFTã§ç¹å¾´ç¹æ¤åºãã¾ãã
import cv2 img_both = cv2.imread('Chartres_both.JPG') img_right = cv2.imread('Chartres_right.JPG') img_left = cv2.imread('Chartres_left.JPG') img_both = cv2.resize(img_both, None, fx=0.25, fy=0.25, interpolation=cv2.INTER_AREA) img_right = cv2.resize(img_right, None, fx=0.25, fy=0.25, interpolation=cv2.INTER_AREA) img_left = cv2.resize(img_left, None, fx=0.25, fy=0.25, interpolation=cv2.INTER_AREA) sift = cv2.SIFT_create() kp_both, des_both = sift.detectAndCompute(img_both, None) kp_right, des_right = sift.detectAndCompute(img_right, None) kp_left, des_left = sift.detectAndCompute(img_left, None) bf = cv2.BFMatcher() matches_right = bf.match(des_both, des_right) matches_right = sorted(matches_right, key = lambda x:x.distance) matches_left = bf.match(des_left, des_both) matches_left = sorted(matches_left, key = lambda x:x.distance)
å°å½±å¤æè¡åè¨ç®
cv2.fincHomography()
é¢æ°ã§å°å½±å¤æè¡åãè¨ç®ãããã¨ãã§ãã¾ãã
ãã¥ã¼ããªã¢ã«ãèªãã¨ã以ä¸ã®ãããªãã¨ãæ¸ãã¦ããã¾ãã
- å°å½±å¤æè¡åãæ±ããã«ã¯ãæä½4ç¹ã®ãããã³ã°ç¹ãå¿ è¦
- 誤ã£ããããã³ã°ãã¢ãããã¨çµæã«æªå½±é¿ãä¸ãã
- ããã«å¯¾å¦ããããã
cv2.fincHomography()
é¢æ°ã§ã¯RANSACãLEAST_MEDIANã®ã¢ã«ã´ãªãºã ã使ã£ã¦ãåå ¥åã®ãã¢ã«ã¤ãã¦ãè¯ããããã³ã°ãã©ããå¤å®ãã¾ãããã®çµæããã®é¢æ°ã®è¿ãå¤ã¨ãã¦å¾ããã¾ãã
è¯ããããã³ã°ã®ãã¨ãinlierããã以å¤ãoutlierã¨è¨ãããã§ãã
ãã¥ã¼ããªã¢ã«ã§ã¯ã10ç¹ä»¥ä¸ã®ãããã³ã°ãã¢ã使ç¨ããããã«ãã¦ãã¾ããã
ã·ã£ã«ãã«å¤§èå ã®ç»åã§ããã¨ãåã
åãã£ãæãã§ã¯ããããã³ã°ãã¢ãä¸è´åº¦ã®é«ã(ç¹å¾´éã®è·é¢ã®å°ãã)é ã«ä¸¦ã¹ã¦20ååãã¨ãã»ã¼æ£ãããããã³ã°çµæã¨ãªã£ã¦ãã¾ããã
æ¬æ¥ã¯ratio testã§ãããã³ã°ãã¢ããµããã«ããã¦ããcv2.findHomography()
é¢æ°ã«æããã»ããè¯ãããã§ãããä»åã¯ãã®å¿
è¦ãªãããªã¨ã
ã¨ãããã¨ã§ããã®20åã使ã£ã¦å°å½±å¤æè¡åãæ¢ãããã¨æãã¾ãã
src_pts_for_right = np.float32([kp_both[m.queryIdx].pt for m in matches_right[:20]]).reshape(-1,1,2) dst_pts_right = np.float32([kp_right[m.trainIdx].pt for m in matches_right[:20]]).reshape(-1,1,2) M_right, mask_right = cv2.findHomography(src_pts_for_right, dst_pts_right, cv2.RANSAC, 5.0)
ãããã³ã°çµæã®ãªãã¸ã§ã¯ã(DMatchãªãã¸ã§ã¯ã)ã®queryIdx
ãtrainIdx
ã¯BFMatcher.match()
ã«ä¸ãã2ã¤ã®ç¹å¾´éã»ããã®ãã¡ãããã1ã¤ç®ã2ã¤ç®ã«å¯¾å¿ãã¾ãã
ã¡ãªã¿ã«ãå
¨ãã¤ã³ãinlierã¨ãªã£ãããã§ããã
>>> print(mask_right) [[1] [1] [1] [1] [1] [1] [1] [1] [1] [1] [1] [1] [1] [1] [1] [1] [1] [1] [1] [1]]
ç»åã®è¦ç¹å¤æ
ãã¥ã¼ããªã¢ã«ã§ã¯ãç©ä½ãæ¢ãã¨ããã®ãç®æ¨ã«ãã¦ãã¾ãããããã§ã¯ç»åã®è¦ç¹å¤æããããã¨æã£ã¦ããã®ã§ãåã«ä¸åº¦ä½¿ã£ãcv2.warpPerspective()
ã使ã£ã¦ã¿ããã¨æãã¾ãã
OpenCVやってみる-4. 射影変換 - 勉強しないとな~blog
å ã®å³å´ç»åã¨ã両å´ç»åããå¤æããç»åãæ¯è¼ãã¾ããããããæãã«ãªã£ã¦ãããã¨ã
img_both_converted = cv2.warpPerspective(img_both, M_right, (750, 1000)) img_right_comp = np.hstack((img_right, img_both_converted)) cv2.imshow('Image compare', img_right_comp)
以ä¸ãåèã«ç»åãéç³ãã¦ã¿ã¾ããããä¸è´åº¦ãé«ããã¦ãªãã ãããåãããã
Python OpenCV Overlaying or Blending Two Images
img_right_blended = cv2.addWeighted(img_right, 0.5, img_both_converted, 0.5, 0) cv2.imshow('Image compare(Blended)', img_right_blended)
両å´ç»åãå¤æãã¦å³å´ç»åã®è¦ç¹ã§è¦ã¦ã¿ããã¨ãã¾ããããããã«å³å´ã«æ¡å¼µãããã ãã ã£ãã®ã§ãæ¡å¼µé åã¯çã£é»ã«ã
img_right_extended = cv2.warpPerspective(img_both, M_right, (750*2, 1000)) cv2.imshow('Image right extended', img_right_extended)
ãªãã¨ãã§ããªããã¨èãã¦ã¿ã¾ããããå¤æè¡åãä½ãã¨ãã«å ¥å座æ¨ã«ãªãã»ãããã¤ããã°ã©ãããªãã¨ã
dst_pts_right_offset = dst_pts_right for i in range(20): dst_pts_right_offset[i,0,:] += [750,0] M_right_offset, mask_right_offset = cv2.findHomography(src_pts_for_right, dst_pts_right_offset, cv2.RANSAC, 5.0) img_right_extended = cv2.warpPerspective(img_both, M_right_offset, (750*2, 1000)) cv2.imshow('Image right extended', img_right_extended)
ãããï¼
å·¦å´ã¯ç¹ã«ä½ãããªãã¦ãããããããªã
dst_pts_left = np.float32([kp_left[m.queryIdx].pt for m in matches_left[:20]]).reshape(-1,1,2) M_left, mask_left = cv2.findHomography(src_pts_for_left, dst_pts_left, cv2.RANSAC, 5.0)
img_left_extended = cv2.warpPerspective(img_both, M_left, (750*2, 1000)) cv2.imshow('Image left extended', img_left_extended)
以ä¸
ä»åãããæãã®çµæãå¾ããã¾ããã
ã«ã¡ã©ç»åã®è¦ç¹å¤æã¯èªç±èªå¨ã§ãã
次åã®å 容ã¯æ¤è¨ä¸â¦