LoginSignup
55

More than 5 years have passed since last update.

OpenCVのundistort(レンズ歪み補正)で端っこが欠けてしまうのをなんとかする

Last updated at Posted at 2014-07-28

OpenCVのcv2.undistortでレンズ歪みを補正しようとすると,端っこが欠けてしまう問題がある.

import matplotlib.pyplot as plt
import cv2


img_und = cv2.undistort(img, camera_mat, dist_coef)
plt.subplot(1,2,1)
plt.imshow(img)
plt.subplot(1,2,2)
plt.imshow(img_und)

download.png

ちなみにカメラは今流行の http://panasonic.jp/wearable/a500/index.html を使った.
この画像では,チェスボード部分のレンズ歪みはとれているものの,周りの情報が失われている.どれくらいの情報が失われているのか.

import numpy as np

w,h=np.meshgrid(range(0, img.shape[1], 10), range(0, img.shape[0], 10))
pts = (np.vstack((w.flatten(), h.flatten())).T).astype('float32')
pts_new = cv2.undistortPoints(np.array([pts]), camera_mat, dist_coef, P=camera_mat)[0]

plt.scatter(pts[:,0], pts[:,1], 20, 'r', alpha=.5)
plt.scatter(pts_new[:,0], pts_new[:,1], 20, 'b', alpha=.5)

download (1).png
赤点が入力画像のグリッド,青点がレンズ歪みを取り除くことによって変形したグリッドを示している.cv2.undistortではこの青グリッドの内,赤グリッドの範囲のみが切り出されたものが出力される.これは,端っこにも重要なものが映っている場合,あまり嬉しくない.

こういう時には,cv2.initUndistortRectifyMapcv2.remapを使うと良い.

new_cammat = cv2.getOptimalNewCameraMatrix(camera_mat, dist_coef, (img.shape[1], img.shape[0]), 1)[0]
map = cv2.initUndistortRectifyMap(camera_mat, dist_coef, np.eye(3), new_cammat, (img.shape[1], img.shape[0]), cv2.cv.CV_32FC1)
img_und = cv2.remap(img, map[0], map[1], cv2.cv.CV_INTER_AREA)

plt.subplot(1,2,1)
plt.imshow(img)
plt.subplot(1,2,2)
plt.imshow(img_und)

download (2).png

うまくいった,あと,チェスボード以外の外側部分では歪みがちゃんと補正しきれてないことも分かった.ちなみに,元画像で計測できていない部分(中央上端,中央下端)は0が埋められる.その部分が必要ない場合,
cv2.getOptimalNewCameraMatrix(camera_mat, dist_coef, (img.shape[1], img.shape[0]), 0)とすれば良い. 詳しくは http://opencv.jp/opencv-2svn/cpp/camera_calibration_and_3d_reconstruction.html#cv-getoptimalnewcameramatrix を参照.

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
55