レンズ歪みの補正
2015/8/14
Python2.7.6, OpenCV3.0.0
OpenCVにはチェスボードからカメラのレンズ歪みを補正するキャリブレーションという機能がある。
Webカメラから画像を取得して、キャリブレーション
import numpy as np
import cv2
import glob
# termination criteria
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
# prepare object points, like (0,0,0), (1,0,0), (2,0,0) ....,(6,5,0)
objp = np.zeros((6*7,3), np.float32)
objp[:,:2] = np.mgrid[0:7,0:6].T.reshape(-1,2)
# Arrays to store object points and image points from all the images.
objpoints = [] # 3d point in real world space
imgpoints = [] # 2d points in image plane.
capture = cv2.VideoCapture(0)
if capture.isOpened() is False:
raise("IO Error")
cv2.namedWindow('Before', cv2.WINDOW_AUTOSIZE)
cv2.namedWindow('After', cv2.WINDOW_AUTOSIZE)
for i in range(10): #安定するまで何回か取得
ret, src_img = capture.read()
if ret == False:
continue
copy_img = src_img.copy()
cv2.imshow('Before', src_img)
gray = cv2.cvtColor(copy_img,cv2.COLOR_BGR2GRAY)
# Find the chess board corners
ret, corners = cv2.findChessboardCorners(gray,(7,6),None)
if ret == False:
cv2.destroyAllWindows()
print('Error')
exit()
# If found, add object points, image points (after refining them)
objpoints.append(objp)
corners2 = cv2.cornerSubPix(gray,corners,(11,11),(-1,-1),criteria)
imgpoints.append(corners2)
# Draw and display the corners
# img = cv2.drawChessboardCorners(copy_img, (7,6), corners2, ret)
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1],None,None)
h, w = img.shape[:2]
newcameramtx, roi = cv2.getOptimalNewCameraMatrix(mtx,dist,(w,h),1,(w,h))
# undistort
mapx,mapy = cv2.initUndistortRectifyMap(mtx,dist,None,newcameramtx,(w,h),5)
dst = cv2.remap(src_img,mapx,mapy,cv2.INTER_LINEAR)
cv2.imshow('After',dst)
while True: #キーを押すまで待機
if cv2.waitKey(33) >= 0:
break
cv2.destroyAllWindows()
取りあえず、ここの情報を頼りに意味も分からず、コピペしてみたら、一応できたっぽい。
Docs » OpenCV-Python Tutorials » Camera Calibration and 3D Reconstruction » Camera Calibration
http://opencv-python-tutroals.readthedocs.org/en/latest/py_tutorials/py_calib3d/py_calibration/py_calibration.html
チェスボードのほかにもcv2.findCirclesGrid()
という関数もある。
各種関数
findChessboardCorners
retval, corners = cv2.findChessboardCorners(image, patternSize, flags)
チェスボードの交点を探す
image
・・・ カラー画像かグレースケール画像patternSize
・・・ チェスボードの交点数(行, 列)flags
・・・ 操作フラグ(?)corners
・・・ 検出されたコーナーの出力配列retval
・・・ 処理結果
OpenCV API Reference » calib3d. Camera Calibration and 3D Reconstruction
docs.opencv.org/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html#findchessboardcorners
OpenCV3.0.0 : Camera Calibration and 3D Reconstruction
http://docs.opencv.org/3.0.0/d9/d0c/group__calib3d.html#ga93efa9b0aa890de240ca32b11253dd4a
OpenCVでチェスボードの交点を検出する
http://venuschjp.blogspot.jp/2015/02/opencv.html
cornerSubPix
corners2 = cornerSubPix(image, corners, winSize, zeroZone, criteria)
コーナー位置を高精度化
image
・・・ グレースケール画像corners
・・・ 入力コーナーの初期座標.winSize
・・・ 探索窓のサイズの半分.(5,5) の場合,52+1×52+1 = 11×11 サイズの探索窓が利用される.要は判定範囲?zeroZone
・・・ 探索領域の中心に存在する対象外領域の半分のサイズ. (-1,-1) は,対象外領域はないということcriteria
・・・ コーナー位置高精度化のための繰り返し処理の停止基準.最大反復数と要求精度のどちらか,あるいは両方を指定corners2
・・・ 高精度化されたコーナー座標
opencv v2.1 documentation » cv. 画像処理とコンピュータビジョン » 特徴検出
http://opencv.jp/opencv-2.1/cpp/feature_detection.html#cv-cornersubpix
OpenCV 3.0.0 : Feature Detection
http://docs.opencv.org/3.0.0/dd/d1a/group__imgproc__feature.html#ga354e0d7c86d0d9da75de9b9701a9a87e
OpenCVでチェスボードの交点を検出する
http://venuschjp.blogspot.jp/2015/02/opencv.html
calibrateCamera
retval, cameraMatrix, distCoeffs, rvecs, tvecs = cv2.calibrateCamera(objectPoints, imagePoints, imageSize, flags=0)
各種補正用のパラメータを取得
objectPoints
・・・ 交点の点群座標.imagePoints
・・・ objectPointsに対応する特徴点の画像上での座標値.imageSize
・・・ 画像サイズ.cameraMatrix
・・・ 歪み係数の出力ベクトル入出力用のカメラの内部パラメータ行列.distCoeffs
・・・ 歪み係数の出力ベクトルrvecs
・・・ 推定された回転ベクトルtvecs
・・・ 推定された並進ベクトルflags
・・・ 様々なフラグ.retval
・・・ 処理結果
OpenCV 3.0.0 Documentation : Camera Calibration and 3D Reconstruction
http://docs.opencv.org/3.0.0/d9/d0c/group__calib3d.html#ga687a1ab946686f0d85ae0363b5af1d7b
opencv 2.2 documentation » カメラキャリブレーションと3次元再構成
http://opencv.jp/opencv-2svn/cpp/camera_calibration_and_3d_reconstruction.html#cv-getoptimalnewcameramatrix
OpenCV2系のAPIを使って歪み補正を行う
http://qiita.com/tunepolo/items/76058121238be386bb21
getOptimalNewCameraMatrix
newCameraMatrix, roi = cv2.getOptimalNewCameraMatrix(cameraMatrix, distCoeffs, imageSize, alpha, newImageSize)
画像に適応する行列パラメータを生成する
- cameraMatrix – 入力されるカメラ行列.
- distCoeffs – 入力される歪み係数ベクトル
- imageSize – 最適画像サイズ.
- alpha – 0~1の値.1だと元画像で計測できていない部分(中央上端,中央下端)は0が埋められる
- newCameraMatrix – 出力される新たなカメラ行列.
- newImageSize – 平行化された後の画像サイズ.デフォルトでは imageSize と同じになる.
- validPixROI – 歪み補正された画像中のすべての有効なピクセル領域を囲む矩形
OpenCVのundistort(レンズ歪み補正)で端っこが欠けてしまうのをなんとかする
http://qiita.com/jellied_unagi/items/36796d48d7d8a5fb3e42
opencv 2.2 documentation » カメラキャリブレーションと3次元再構成
http://opencv.jp/opencv-2svn/cpp/camera_calibration_and_3d_reconstruction.html#cv-getoptimalnewcameramatrix
OpenCV 3.0.0 Documentation : Camera Calibration and 3D Reconstruction
http://docs.opencv.org/3.0-beta/modules/calib3d/doc/camera_calibration_and_3d_reconstruction.html#getoptimalnewcameramatrix
initUndistortRectifyMap
レンズ歪みを補正する。cv2.undistort()
という関数もあって、こちらも補正するけど、補正が効く部分を切り取ってしまう。
もとの画像サイズのままにしたいときは、この関数とremap()
を使う。
map1, map2 = cv2.initUndistortRectifyMap(cameraMatrix, distCoeffs, R, newCameraMatrix, size , m1type)
補正マップ作成
cameraMatrix
・・・ 入力されるカメラ行列distCoeffs
・・・ 入力される歪み係数ベクトルR
・・・ 物体空間における平行化変換(3x3 の行列).Noneの場合,恒等変換が仮定されるnewCameraMatrix
・・・ 新しいカメラ行列size
・・・ 歪み補整された画像サイズ.m1type
・・・ 1番目の出力マップの型.map1
・・・ 1番目の出力マップ.map2
・・・ 2番目の出力マップ.
OpenCVのundistort(レンズ歪み補正)で端っこが欠けてしまうのをなんとかする
http://qiita.com/jellied_unagi/items/36796d48d7d8a5fb3e42
opencv 2.2 documentation » カメラキャリブレーションと3次元再構成
http://opencv.jp/opencv-2svn/cpp/camera_calibration_and_3d_reconstruction.html#cv-initundistortrectifymap
OpenCV 3.0.0 Documentation : Geometric Image Transformations
http://docs.opencv.org/3.0.0/da/d54/group__imgproc__transform.html#ga7dfb72c9cf9780a347fbe3d1c47e5d5a
remap
dst = cv2.remap(src, map1,map2, interpolation, borderMode, borderValue)
画像に対して,汎用的な幾何学変換を適用
src
・・・ 入力画像dst
・・・ 出力画像. map1 と同じサイズ, src と同じタイプmap1
・・・ 型 CV_16SC2 , CV_32FC1 あるいは CV_32FC2 である座標点 (x,y) ,または単なる値 x の1番目のマップmap2
・・・ 型 CV_16UC1 , CV_32FC1 あるいは none(map1 が (x,y) である場合は空のマップ) である値 y の2番目のマップinterpolation
・・・ 補間手法. cv2.INTER_LINEARはバイリニア補間borderMode
・・・ ピクセル外挿手法. デフォルトではBORDER_TRANSPARENT。borderValue
・・・ 定数境界モードで利用されるピクセル値.デフォルトでは 0
opencv 2.2 documentation » 画像の幾何学変換
http://opencv.jp/opencv-2svn/cpp/imgproc_geometric_image_transformations.html?highlight=remap#remap
OpenCV 3.0.0 Documentation : Geometric Image Transformations http://docs.opencv.org/3.0.0/da/d54/group__imgproc__transform.html#gab75ef31ce5cdfb5c44b6da5f3b908ea4
ただのコピペだけど、頑張った!