python - Camera callibration openCV from image/pixel coordinates to world/mm -
using single camera , chessboard should possible create callibration file used afterward convert image coordinates in pixels world coordinates in mm @ least when object placed on same plane (e.g. when camera fixed above table on image placed several dimensions should inspected)
from previous posts [2] learned both intrinsic , extrinsic camera properties should analyzed. wrote python programms below.
the question is: how use these matriches convert image x , y coordinate world coordinates? hope share of his/her code!
first determine intrinsic parameters:
import numpy np import cv2 import parameters p import os import time import pickle #https://stackoverflow.com/questions/6568007/how-do-i-save-and-restore-multiple-variables-in-python print "switch off auto focus of camera, take multiple pictures of chessboard of properties described in parameters.py , save images in product_pictures before running programm" start_time = time.time() # termination criteria criteria = (cv2.term_criteria_eps + cv2.term_criteria_max_iter, 30, 0.001) # prepare object points, (0,0,0), (1,0,0), (2,0,0) ....,(6,5,0) objp = np.zeros((p.chessboardmin*p.chessboardmax,3), np.float32) objp[:,:2] = np.mgrid[0:p.chessboardmax,0:p.chessboardmin].t.reshape(-1,2) # arrays store object points , image points images. objpoints = [] # 3d point in real world space imgpoints = [] # 2d points in image plane. image_folder_dir = 'product_pictures_intrinsic_camera_callibration\\' # sequentially load multiple images image_listing = os.listdir(image_folder_dir) image_listing = os.listdir(image_folder_dir) print image_listing image_name in image_listing: if image_name.endswith(".jpg"): img = cv2.imread(image_folder_dir+image_name) gray = cv2.cvtcolor(img,cv2.color_bgr2gray) print "analyzing image = " +str(image_name) #cv2.imshow('gray',gray) # find chess board corners ret, corners = cv2.findchessboardcorners(gray, (p.chessboardmax,p.chessboardmin),none) cv2.drawchessboardcorners(img, (p.chessboardmax,p.chessboardmin), corners,ret) img_dir = 'corners_identified/sude1.0_callibration_corners_' + str(time.strftime("%y%m%d%h%m%s")) + ".jpg" # create name image time stamp cv2.imwrite(img_dir, img) show_picture=image_name #cv2.namedwindow('img', cv2.window_normal) #cv2.imshow('img',img) #cv2.waitkey() 6 # if found, add object points, image points (after refining them) if ret == true: print 'chessboard identified' objpoints.append(objp) corners2=cv2.cornersubpix(gray,corners,(11,11),(-1,-1),criteria) imgpoints.append(corners) #should corners 2 use subpix # draw , display corners #cv2.drawchessboardcorners(img, (p.chessboardmax,p.chessboardmin), corners,ret) #cv2.imshow('img',img) #cv2.waitkey() else: print "no chessboard identified ... make sure number of intersecting squares correctly defined in parameters.py" cv2.destroyallwindows() ret, mtx, dist, rvecs, tvecs = cv2.calibratecamera(objpoints, imgpoints, gray.shape[::-1],none,none) #mtx intrinsic camera mtx anti fish eye print "camera callibration performed" #save rectified image img = cv2.imread(image_folder_dir+show_picture) #cv2.imshow('first analyzed img before',img) #cv2.waitkey() h, w = img.shape[:2] newcameramtx, roi=cv2.getoptimalnewcameramatrix(mtx,dist,(w,h),0,(w,h)) #http://ksimek.github.io/2013/08/13/intrinsic/ # if dist has negative values means there distortion, take picture higher distance http://answers.opencv.org/question/28438/undistortion-at-far-edges-of-image/ # undistort dst = cv2.undistort(img, mtx, dist, none, newcameramtx) print "optimal new camera matrix , undistort matrix defined" # save calibration file open('intrinsic_calibration_file.pickle', 'w') f: # python 3: open(..., 'wb') pickle.dump([newcameramtx, roi, rvecs, tvecs, dst,dist], f) # getting objects verify correct save open('intrinsic_calibration_file.pickle') f: # python 3: open(..., 'rb') g, h, i, j, k, l = pickle.load(f) print "new camera matrix = " + str(g) print "roi = " + str(h) + " if = [0,0,0,0] distortion not possible correct --> change zoom settings" print "rvecs calibrate camera = "+ str(i) print "tvecs calibrate camera = "+ str(j) print "dst = " +str(k) print "dist = " +str(l) end_time = time.time() print "duration = " + str(start_time-end_time) + " seconds"`
and extrinsic parameters:
import numpy np import cv2 import parameters p import os import time import pickle print "determine first intrinsic camera settings" print "take 1 picture of chessboard of paramters defined in parameters.py same settings determining instrinsic camera settings , position chessboard product placed" start_time = time.time() # getting intrinsic camera properties open('intrinsic_calibration_file.pickle') f: # python 3: open(..., 'rb') newcameramtx, roi, rvecs, tvecs, dst, dist = pickle.load(f) # termination criteria criteria = (cv2.term_criteria_eps + cv2.term_criteria_max_iter, 30, 0.001) #determine corners of chessboard" imgpoints = [] # 2d points in image plane. image_folder_dir = 'product_pictures_extrinsic_camera_callibration\\' # sequentially load multiple images image_listing = os.listdir(image_folder_dir) image_listing = os.listdir(image_folder_dir) print image_listing image_name in image_listing: if image_name.endswith(".jpg"): img = cv2.imread(image_folder_dir+image_name) gray = cv2.cvtcolor(img,cv2.color_bgr2gray) print "analyzing image = " +str(image_name) #cv2.imshow('gray',gray) # cv2.waitkey(500) # find chess board corners ret, corners = cv2.findchessboardcorners(gray, (p.chessboardmax,p.chessboardmin),none) cv2.drawchessboardcorners(img, (p.chessboardmax,p.chessboardmin), corners,ret) img_dir = 'corners_identified/sude1.0_callibration_corners_' + str(time.strftime("%y%m%d%h%m%s")) + ".jpg" # create name image time stamp cv2.imwrite(img_dir, img) show_picture=image_name #cv2.namedwindow('img', cv2.window_normal) #cv2.imshow('img',img) #cv2.waitkey() 6 # if found, add object points, image points (after refining them) if ret == true: print 'chessboard identified' corners2=cv2.cornersubpix(gray,corners,(11,11),(-1,-1),criteria) imgpoints.append(corners) #should corners 2 use subpix # draw , display corners #cv2.drawchessboardcorners(img, (p.chessboardmax,p.chessboardmin), corners,ret) #cv2.imshow('img',img) #cv2.waitkey() else: print "no chessboard identified ... make sure number of intersecting squares correctly defined in parameters.py" cv2.destroyallwindows() newimgpoint=[] newimgpoint.append([imgpoints[0][36][0][0],imgpoints[0][36][0][1]]) newimgpoint.append([imgpoints[0][0][0][0], imgpoints[0][0][0][1]])#p.chessboardmin-1][0][0],imgpoints[0][p.chessboardmin-1][0][1]]) newimgpoint.append([imgpoints[0][47][0][0],imgpoints[0][47][0][1]])#p.chessboardmin*(p.chessboardmax-1)][0][0],imgpoints[0][p.chessboardmin*(p.chessboardmax-1)][0][1]]) newimgpoint.append([imgpoints[0][10][0][0], imgpoints[0][10][0][1]])#p.chessboardmax*p.chessboardmin-1][0][0],imgpoints[0][p.chessboardmax*p.chessboardmin-1][0][1]]) print "outer corner image coordinates=" +str(newimgpoint) newobjp=[] newobjp.append([0.0,0.0,0.0]) newobjp.append([(p.chessboardmin-1)*p.chessboarddistance*1.0,0.0,0.0]) newobjp.append([0.0,(p.chessboardmax-1)*p.chessboarddistance*1.0,0.0]) newobjp.append([(p.chessboardmax-1)*p.chessboarddistance*1.0,(p.chessboardmin-1)*p.chessboarddistance*1.0,0.0]) print "outer object coordinates=" +str(newobjp) rvec, tvec, inliers = cv2.solvepnp(np.array(newobjp), np.array(newimgpoint), newcameramtx , dist)#check volgorde van return, wellichy]t eerst trou or false rotmat = cv2.rodrigues(rvec) # should rvec # save calibration file open('extrinsic_calibration_file.pickle', 'w') f: # python 3: open(..., 'wb') pickle.dump([rvec,tvec,rotmat], f) # getting objects verify correct save open('extrinsic_calibration_file.pickle') f: # python 3: open(..., 'rb') g, h, = pickle.load(f) print "rvec = "+ str(g) print "tvec = "+ str(h) print "rodrotmat = "+ str(i)`
and parameters.py file
'"""camera callibration""" chessboardmax = 6 chessboardmin = 8 chessboarddistance = 35 # size of chessboard squares in mm'
Comments
Post a Comment