Zhangのカメラキャリブレーションで、きちんとチェスボードの交点を検出できているか確かめるコード
でパクったキャリブレーションのコードですが、
「OpenCV を利用した非接触 3 次元座標測定技術に関する研究」
この報告によれば、チェスボードの角度がカメラの視線方向に対して斜め15度を超えると、
"検出した交点座標が画像上の交点位置と異なる"
"全ての交点座標が検出できない" などの問題が発生するそう。
そこで、
- 目視により検出したポイントを表示
- ボタンにより画像を使用するか否かを人の目で判別する という機能をつけます。
上記コードにつけたし
# -*- coding: utf-8 -*- import numpy import cv2 from glob import glob import Tkinter import tkMessageBox square_size = 23.0 # 正方形のサイズ pattern_size = (10, 7) # 模様のサイズ pattern_points = numpy.zeros( (numpy.prod(pattern_size), 3), numpy.float32 ) #チェスボード(X,Y,Z)座標の指定 (Z=0) pattern_points[:,:2] = numpy.indices(pattern_size).T.reshape(-1, 2) pattern_points *= square_size obj_points = [] img_points = [] for fn in glob("*.jpg"): # 画像の取得 im = cv2.imread(fn, 0) print "loading..." + fn # チェスボードのコーナーを検出 found, corner = cv2.findChessboardCorners(im, pattern_size) # コーナーがあれば if found: term = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_COUNT, 30, 0.1) cv2.cornerSubPix(im, corner, (5,5), (-1,-1), term) #よくわからないがサブピクセル処理(小数点以下のピクセル単位まで精度を求める) cv2.drawChessboardCorners(im, pattern_size, corner,found) cv2.imshow('found corners in' + fn,im) # コーナーがない場合のエラー処理 if not found: print 'chessboard not found' continue # 選択ボタンを表示 root = Tkinter.Tk() root.withdraw() if tkMessageBox.askyesno('askyesno','この画像の値を採用しますか?'): img_points.append(corner.reshape(-1, 2)) #appendメソッド:リストの最後に因数のオブジェクトを追加 #corner.reshape(-1, 2) : 検出したコーナーの画像内座標値(x, y) obj_points.append(pattern_points) print 'found corners in ' + fn + ' is adopted' else: print 'found corners in ' + fn + ' is not adopted' cv2.destroyAllWindows() # 内部パラメータを計算 rms, K, d, r, t = cv2.calibrateCamera(obj_points,img_points,(im.shape[1],im.shape[0])) # 計算結果を表示 print "RMS = ", rms print "K = \n", K print "d = ", d.ravel() # 計算結果を保存 numpy.savetxt("K.csv", K, delimiter =',',fmt="%0.14f") #カメラ行列の保存 numpy.savetxt("d.csv", d, delimiter =',',fmt="%0.14f") #歪み係数の保存
めんどくさいので、main関数にする表記も外しました*2
結果はこんな。