2012-04-05 15 views
5

मैं कैमरे को कैलिब्रेट करने के लिए OpenCV 2.3 पायथन बाइंडिंग का उपयोग करने की कोशिश कर रहा हूं। मैंने मैटलैब में नीचे दिए गए डेटा का उपयोग किया है और अंशांकन काम करता है, लेकिन मुझे ओपनसीवी में काम करने के लिए प्रतीत नहीं होता है। प्रारंभिक अनुमान के रूप में सेटअप कैमरा मैट्रिक्स मैटलैब टूलबॉक्स से गणना किए गए उत्तर के बहुत करीब है।ओपनसीवी 2.3 कैमरा कैलिब्रेशन

import cv2 
import numpy as np 

obj_points = [[-9.7,3.0,4.5],[-11.1,0.5,3.1],[-8.5,0.9,2.4],[-5.8,4.4,2.7],[-4.8,1.5,0.2],[-6.7,-1.6,-0.4],[-8.7,-3.3,-0.6],[-4.3,-1.2,-2.4],[-12.4,-2.3,0.9], [-14.1,-3.8,-0.6],[-18.9,2.9,2.9],[-14.6,2.3,4.6],[-16.0,0.8,3.0],[-18.9,-0.1,0.3], [-16.3,-1.7,0.5],[-18.6,-2.7,-2.2]] 
img_points = [[993.0,623.0],[942.0,705.0],[1023.0,720.0],[1116.0,645.0],[1136.0,764.0],[1071.0,847.0],[1003.0,885.0],[1142.0,887.0],[886.0,816.0],[827.0,883.0],[710.0,636.0],[837.0,621.0],[789.0,688.0],[699.0,759.0],[768.0,800.0],[697.0,873.0]] 

obj_points = np.array(obj_points) 
img_points = np.array(img_points) 

w = 1680 
h = 1050 
size = (w,h) 

camera_matrix = np.zeros((3, 3)) 
camera_matrix[0,0]= 2200.0 
camera_matrix[1,1]= 2200.0 
camera_matrix[2,2]=1.0 
camera_matrix[2,0]=750.0 
camera_matrix[2,1]=750.0 

dist_coefs = np.zeros(4) 
results = cv2.calibrateCamera(obj_points, img_points,size, 
    camera_matrix, dist_coefs) 
+1

"इसका काम करने के लिए प्रतीत नहीं होता" द्वारा आपका क्या मतलब है - क्या यह किसी प्रकार की त्रुटि देता है? (किस मामले में, क्या त्रुटि?) या यह चलता है और आपको उम्मीदवारों को उम्मीद नहीं करता है? –

उत्तर

20

सबसे पहले, आपका कैमरा मैट्रिक्स गलत है।

fx 0 cx 
0 fy cy 
0 0 1 

तुम अपने को देखें, तो आप इसे गलत तरीके से गोल मिल गया है: आप पढ़ा है, यह की तरह दिखना चाहिए

fx 0 0 
0 fy 0 
cx cy 1 

तो सबसे पहले, camera_matrix.T करने के लिए camera_matrix सेट (या बदलें कि आप camera_matrix कैसे बनाते हैं। याद रखें कि camera_matrix[i,j]पंक्तिi, कॉलमj)।

camera_matrix = camera_matrix.T 

इसके बाद, मैं अपने कोड भाग गया और मुझे लगता है कि "यह काम करने के लिए प्राप्त करने के लिए नहीं कर पा रहे" निम्न त्रुटि (वैसे का मतलब है - हमेशा कहते हैं तुम्हारा मतलब क्या द्वारा "पाने के लिए नहीं कर पा रहे यह "काम करने के लिए अपने प्रश्नों में - अगर यह एक त्रुटि है, त्रुटि पोस्ट यह चलता है, लेकिन आप संख्या पागल, इसलिए कहते हैं) देता है:

OpenCV Error: Assertion failed (ni >= 0) in collectCalibrationData, file /home/cha66i/Downloads/OpenCV-2.3.1/modules/calib3d/src/calibration.cpp, line 3161 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
cv2.error: /home/cha66i/Downloads/OpenCV-2.3.1/modules/calib3d/src/calibration.cpp:3161: error: (-215) ni >= 0 in function collectCalibrationData 

मैं तो (बहुत माध्यम से उपयोगी पढ़ें) और। ध्यान दिया कि obj_points और img_pointsवैक्टर के वेक्टर होना चाहिए, क्योंकि वस्तु/छवि बिंदु के सेट में फ़ीड करना संभव है एक ही शतरंज (/ अंशांकन बिंदु) की कई छवियों के लिए है।

इसलिए:

cv2.calibrateCamera([obj_points], [img_points],size, camera_matrix, dist_coefs) 

क्या? मुझे अब भी वही त्रुटि मिलती है?!

फिर, मैं OpenCV को Python2 नमूने (फ़ोल्डर OpenCV-2.x.x/samples/python2 में) पर एक नज़र था, और एक calibration.py मुझे दिखा कैसे अंशांकन कार्यों का उपयोग करने के लिए देखा (नमूने कभी नहीं बहुत मूल्यवान समझना, वे अक्सर प्रलेखन की तुलना में बेहतर कर रहे हैं!) ।

मैं calibration.py भागने की कोशिश की लेकिन यह नहीं चलता है क्योंकि यह camera_matrix और distCoeffs तर्क है, जो जरूरी हैं की आपूर्ति नहीं करता है। तो मैंने इसे एक डमी camera_matrix और distCoeffs में फ़ीड करने के लिए संशोधित किया, और हे, यह काम करता है!

एकमात्र अंतर मैं अपने obj_points/img_points और उनके बीच के बीच देख सकता हूं, यह है कि उनके पास dtype=float32 है, जबकि मेरा नहीं है।

तो, मैं बदल मेरी obj_points और img_points भी dtype float32 के लिए (OpenCV करने को Python2 इंटरफ़ेस ऐसे ही हास्यास्पद है, जब मैट्रिक्स एक dtype नहीं है अक्सर कार्यों काम नहीं करते):

obj_points = obj_points.astype('float32') 
img_points = img_points.astype('float32') 

फिर मैं फिर कोशिश करता हूं:

>>> cv2.calibrateCamera([obj_points], [img_points],size, camera_matrix, dist_coefs) 
OpenCV Error: Bad argument 
(For non-planar calibration rigs the initial intrinsic matrix must be specified) 
in cvCalibrateCamera2, file .... 

क्या ?! कम से कम एक अलग त्रुटि।लेकिन मैं प्रारंभिक आंतरिक मैट्रिक्स की आपूर्ति करता हूं!

तो मैं वापस दस्तावेज़ पर जाएं, और flags पैरामीटर नोटिस:

झंडे - विभिन्न झंडे शून्य या निम्न मान का एक संयोजन हो सकता है कि:

CV_CALIB_USE_INTRINSIC_GUESS cameraMatrix वैध प्रारंभिक शामिल कि आगे

अनुकूलित कर रहे हैं fx, FY, cx, cy की मूल्यों ...

अहा, तो मैं प्रारंभिक अनुमान मैं प्रदान की उपयोग करने के लिए समारोह स्पष्ट बताने के लिए है:

cv2.calibrateCamera([obj_points], [img_points],size, camera_matrix.T, dist_coefs, 
        flags=cv2.CALIB_USE_INTRINSIC_GUESS) 

हुर्रे! यह काम करता हैं!

(नैतिक कहानी का - (ध्यान से OpenCV प्रलेखन पढ़ा है, और नवीनतम संस्करण का उपयोग यानी opencv.itseez.com पर) आप अजगर cv2 इंटरफ़ेस का उपयोग कर रहे हैं इसके अलावा, के लिए samples/python2 निर्देशिका में उदाहरण से परामर्श करें। प्रलेखन को पूरक करें। इन दो चीजों के साथ आपको अधिकतर समस्याओं को हल करने में सक्षम होना चाहिए।)

+0

धन्यवाद श्रीमान श्रीमान। मुझे दस्तावेज में "वैक्टरों के वैक्टर" मिल गए थे, लेकिन इसका अर्थ समझने में कोई अच्छा नहीं मिला। – hokiebird

+0

@ गणितीय.coffee: क्या आप मुझे गैर-coplanar रिग के लिए ओपनसीवी अंशांकन में इस्तेमाल एल्गोरिदम (कागज) के लिए इंगित कर सकते हैं? मेरा मानना ​​है कि यह Bouguet [लिंक] (http://www.vision.caltech.edu/bouguetj/calib_doc/htmls/ref.html) द्वारा मैटलैब कैमरा कैलिब्रेशन टूलबॉक्स से लिया गया है। लेकिन, मुझे यकीन नहीं है कि यह त्सई के एल्गोरिदम या हेइककिला के एल्गोरिदम है? –

+0

@ सतीश कुमार, मेरे पास कोई सुराग नहीं होगा जो वे उपयोग करते हैं। [प्रलेखन] (http://docs.opencv.org/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html?highlight=calibratecamera#bouguetmct) Bouget Matlab सामान का एक लिंक है। शायद आप देखने के लिए स्रोत कोड के माध्यम से पढ़ सकते हैं। –

1

गणितीय.coffee की सहायता के बाद मुझे यह 3 डी अंशांकन चलाने के लिए मिला है।

import cv2 
from cv2 import cv 
import numpy as np 

obj_points = [[-9.7,3.0,4.5],[-11.1,0.5,3.1],[-8.5,0.9,2.4],[-5.8,4.4,2.7],[-4.8,1.5,0.2],[-6.7,-1.6,-0.4],[-8.7,-3.3,-0.6],[-4.3,-1.2,-2.4],[-12.4,-2.3,0.9],[-14.1,-3.8,-0.6],[-18.9,2.9,2.9],[-14.6,2.3,4.6],[-16.0,0.8,3.0],[-18.9,-0.1,0.3],[-16.3,-1.7,0.5],[-18.6,-2.7,-2.2]] 
img_points = [[993.0,623.0],[942.0,705.0],[1023.0,720.0],[1116.0,645.0],[1136.0,764.0],[1071.0,847.0],[1003.0,885.0],[1142.0,887.0],[886.0,816.0],[827.0,883.0],[710.0,636.0],[837.0,621.0],[789.0,688.0],[699.0,759.0],[768.0,800.0],[697.0,873.0]] 

obj_points = np.array(obj_points,'float32') 
img_points = np.array(img_points,'float32') 

w = 1680 
h = 1050 
size = (w,h) 

camera_matrix = np.zeros((3, 3),'float32') 
camera_matrix[0,0]= 2200.0 
camera_matrix[1,1]= 2200.0 
camera_matrix[2,2]=1.0 
camera_matrix[0,2]=750.0 
camera_matrix[1,2]=750.0 

dist_coefs = np.zeros(4,'float32') 

retval,camera_matrix,dist_coefs,rvecs,tvecs = cv2.calibrateCamera([obj_points],[img_points],size,camera_matrix,dist_coefs,flags=cv.CV_CALIB_USE_INTRINSIC_GUESS) 

समस्या सिर्फ मैं अब क्यों है dist_coefs वेक्टर 5 तत्वों लंबा है जब अंशांकन समारोह से लौट आए है। दस्तावेज कहता है "यदि वेक्टर में चार तत्व होते हैं, तो इसका मतलब है कि के 3 = 0"। लेकिन वास्तव में के 3 का उपयोग किया जाता है, भले ही dist_coefs (4 या 5) की लंबाई हो। इसके अलावा मुझे काम करने के लिए ध्वज CV_CALIB_FIX_K3 नहीं मिल रहा है, जो कि ध्वज को K3 को शून्य करने के लिए मजबूर करने के लिए उस ध्वज का उपयोग करने के लिए बंधे हैं। एक पूर्णांक कहने वाले कैश की आवश्यकता है। ऐसा इसलिए हो सकता है क्योंकि मुझे नहीं पता कि एक साथ कई झंडे कैसे करें, मैं बस यह कर रहा हूं, झंडे = (सीवी.सीवी ..., सीवी.सीवी ...)।

Just to compare, from the matlab camera cal routine the results are... 
    Focal length: 2210. 2207. 
    principal point: 781. 738. 
    Distortions: 4.65e-2 -9.74e+0 3.9e-3 6.74e-3 0.0e+0 
    Rotation vector: 2.36 0.178 -0.131 
    Translation vector: 16.016 2.527 69.549 

From this code, 
    Focal length: 1647. 1629. 
    principal point: 761. 711. 
    Distortions: -2.3e-1 2.0e+1 1.4e-2 -9.5e-2 -172e+2 
    Rotation vector: 2.357 0.199 -0.193 
    Translation vector: 16.511 3.307 48.946 

मुझे लगता है कि अगर मैं यह समझ सकता हूं कि k3 = 0 को कैसे बल देना है, तो शेष मान सही तरीके से संरेखित होंगे।

1

dist_coeffs वेक्टर को 5 आयामी शून्य वेक्टर के रूप में बनाएं और फिर CV_CALIB_FIX_K3 ध्वज का उपयोग करें। आप देख सकते हैं कि वेक्टर (के 3) में अंतिम तत्व शून्य होगा।

जब कई झंडे का उपयोग करने की बात आती है, तो आप या उन्हें कर सकते हैं।

उदाहरण: cv.CV_CALIB_USE_INTRINSIC_GUESS | cv.CV_CALIB_FIX_K3

2

क्या इसके लायक है के लिए, निम्नलिखित कोड का टुकड़ा वर्तमान 2.4.6.1 के तहत काम करता है:

pattern_size = (16, 12) 
    pattern_points = np.zeros((np.prod(pattern_size), 3), np.float32) 
    pattern_points[:, :2] = np.indices(pattern_size).T.reshape(-1, 2).astype(np.float32) 
    img_points = pattern_points[:, :2] * 2 + np.array([40, 30], np.float32) 
    print(cv2.calibrateCamera([pattern_points], [img_points], (400, 400), flags=cv2.CALIB_USE_INTRINSIC_GUESS)) 

ध्यान दें कि camera_matrix और dist_coefs आवश्यक नहीं हैं।

0

उपयोग Point3f और Point3d और Point2d के बजाय Point2fobject_points और image_points परिभाषित करने के लिए और यह काम करेंगे।

+0

कृपया, ओपनसीवी समुदाय को एक पक्ष करें और ** पुराने प्रश्न का उत्तर न दें ** – berak