玩了下opencv的aruco(python版)


簡單的玩了下opencv里頭的aruco,用的手機相機,手機裝了個 ip攝像頭,這樣視頻就可以傳到電腦上了。

首先是標定,我沒打印chessboard,直接在電腦屏幕上顯示,拍了17張,大概如下:

又在手機上裝了個 尺子 之類的app,比划着量了下,每個格子大概是18.1 mm,這個棋盤是10 x 7的棋盤。

要pip install opencv-contrib-python才有擴展模塊,擴展模塊中包含aruco

然后標定了一下:

 1 import cv2
 2 import numpy as np
 3 import glob
 4 import matplotlib.pyplot as plt
 5 import matplotlib.patches as patches
 6 
 7 
 8 # 找棋盤格角點
 9 
10 criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001) # 閾值
11 #棋盤格模板規格
12 w = 9   # 10 - 1
13 h = 6   # 7  - 1
14 # 世界坐標系中的棋盤格點,例如(0,0,0), (1,0,0), (2,0,0) ....,(8,5,0),去掉Z坐標,記為二維矩陣
15 objp = np.zeros((w*h,3), np.float32)
16 objp[:,:2] = np.mgrid[0:w,0:h].T.reshape(-1,2)
17 objp = objp*18.1  # 18.1 mm
18 
19 # 儲存棋盤格角點的世界坐標和圖像坐標對
20 objpoints = [] # 在世界坐標系中的三維點
21 imgpoints = [] # 在圖像平面的二維點
22 
23 images = glob.glob('./chessboard/*.jpg')  #   拍攝的十幾張棋盤圖片所在目錄
24 
25 i = 1
26 for fname in images:
27 
28     img = cv2.imread(fname)
29     gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
30     # 找到棋盤格角點
31     ret, corners = cv2.findChessboardCorners(gray, (w,h),None)
32     # 如果找到足夠點對,將其存儲起來
33     if ret == True:
34         print("i:", i)
35         i = i+1
36     
37         cv2.cornerSubPix(gray,corners,(11,11),(-1,-1),criteria)
38         objpoints.append(objp)
39         imgpoints.append(corners)
40         # 將角點在圖像上顯示
41         cv2.drawChessboardCorners(img, (w,h), corners, ret)
42         cv2.namedWindow('findCorners', cv2.WINDOW_NORMAL)
43         cv2.resizeWindow('findCorners', 810, 405)
44         cv2.imshow('findCorners',img)
45         cv2.waitKey(1)
46 cv2.destroyAllWindows()
47 #%% 標定
48 ret, mtx, dist, rvecs, tvecs = \
49     cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)
50 
51 
52 print("ret:",ret  )
53 print("mtx:\n",mtx)      # 內參數矩陣  
54 print("dist:\n",dist   )   # 畸變系數   distortion cofficients = (k_1,k_2,p_1,p_2,k_3)  
55 print("rvecs:\n",rvecs)   # 旋轉向量  # 外參數  
56 print("tvecs:\n",tvecs  )  # 平移向量  # 外參數
View Code

標定結果里對aruco有用的是 mtx 和 dist。

然后打印包含aruco的marker的紙,運行下面的代碼就可以玩了:

 1 import numpy as np
 2 import time
 3 import cv2  
 4 import cv2.aruco as aruco  
 5 
 6 #with np.load('webcam_calibration_output.npz') as X:  
 7 #    mtx, dist, _, _ = [X[i] for i in ('mtx','dist','rvecs','tvecs')]
 8 
 9 #mtx = 
10 #2946.48    0    1980.53
11 #0    2945.41    1129.25
12 #0    0    1
13 
14 mtx = np.array([
15         [2946.48,       0, 1980.53],
16         [      0, 2945.41, 1129.25],
17         [      0,       0,       1],
18         ])
19 #我的手機拍棋盤的時候圖片大小是 4000 x 2250
20 #ip攝像頭拍視頻的時候設置的是 1920 x 1080,長寬比是一樣的,
21 #ip攝像頭設置分辨率的時候注意一下
22 
23 
24 dist = np.array( [0.226317, -1.21478, 0.00170689, -0.000334551, 1.9892] )
25 
26 video = "http://admin:admin@192.168.1.2:8081/"   # 手機ip攝像頭
27 # 根據ip攝像頭在你手機上生成的ip地址更改,右上角可修改圖像分辨率
28 
29 cap = cv2.VideoCapture(video)
30 
31 
32 font = cv2.FONT_HERSHEY_SIMPLEX #font for displaying text (below)  
33 
34 #num = 0
35 while True:  
36     ret, frame = cap.read()  
37     # operations on the frame come here  
38     
39     gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)  
40     aruco_dict = aruco.Dictionary_get(aruco.DICT_6X6_250)  
41     parameters =  aruco.DetectorParameters_create()  
42   
43     '''
44     detectMarkers(...) 
45         detectMarkers(image, dictionary[, corners[, ids[, parameters[, rejectedI 
46         mgPoints]]]]) -> corners, ids, rejectedImgPoints 
47     '''  
48       
49     #lists of ids and the corners beloning to each id  
50     corners, ids, rejectedImgPoints = aruco.detectMarkers(gray, 
51                                                           aruco_dict, 
52                                                           parameters=parameters)  
53   
54 #    if ids != None: 
55     if ids is not None:
56           
57         rvec, tvec, _ = aruco.estimatePoseSingleMarkers(corners, 0.05, mtx, dist) 
58         # Estimate pose of each marker and return the values rvet and tvec---different 
59         # from camera coeficcients  
60         (rvec-tvec).any() # get rid of that nasty numpy value array error  
61         
62 #        aruco.drawAxis(frame, mtx, dist, rvec, tvec, 0.1) #Draw Axis  
63 #        aruco.drawDetectedMarkers(frame, corners) #Draw A square around the markers
64         
65         for i in range(rvec.shape[0]):
66             aruco.drawAxis(frame, mtx, dist, rvec[i, :, :], tvec[i, :, :], 0.03)
67             aruco.drawDetectedMarkers(frame, corners)
68         ###### DRAW ID #####  
69 #        cv2.putText(frame, "Id: " + str(ids), (0,64), font, 1, (0,255,0),2,cv2.LINE_AA)  
70   
71   
72     else:  
73         ##### DRAW "NO IDS" #####  
74         cv2.putText(frame, "No Ids", (0,64), font, 1, (0,255,0),2,cv2.LINE_AA)  
75   
76     # Display the resulting frame  
77     cv2.imshow("frame",frame)  
78     
79     key = cv2.waitKey(1)
80     
81     if key == 27:         # 按esc鍵退出
82         print('esc break...')  
83         cap.release()
84         cv2.destroyAllWindows()
85         break
86     
87     if key == ord(' '):   # 按空格鍵保存
88 #        num = num + 1
89 #        filename = "frames_%s.jpg" % num  # 保存一張圖像
90         filename = str(time.time())[:10] + ".jpg"  
91         cv2.imwrite(filename, frame)
View Code

最后效果如下:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM