前提・実現したいこと
Python版のopencvを使った、リアルタイムでのキャリブレーションおよび、ひずみ補正。
プログラミング初心者です。
Python版のopencvを使って、魚眼ウェブカメラ(画角150°)のキャリブレーションおよび、ひずみ補正をしたのですが、画像のように変にひずみ補正が行われ解決策を探しています。
本来は画像の真ん中の茶色い部分を主に補正したいと考えています。
右が補正前左が補正後です。
発生している問題・エラーメッセージ
なし
該当のソースコード
python
1コード
import cv2
import numpy as np
import os
import glob
import sys
assert float(cv2.version.rsplit('.', 1)[0]) >= 3, 'OpenCV version 3 or newer required.'
CHECKERBOARD = (7,10)
subpix_criteria = (cv2.TERM_CRITERIA_EPS+cv2.TERM_CRITERIA_MAX_ITER, 30, 0.1)
calibration_flags=cv2.fisheye.CALIB_RECOMPUTE_EXTRINSIC+cv2.fisheye.CALIB_CHECK_COND+cv2.fisheye.CALIB_FIX_SKEW
objp = np.zeros((1, CHECKERBOARD[0]CHECKERBOARD[1], 3), np.float32)
objp[0,:,:2] = np.mgrid[0:CHECKERBOARD[0], 0:CHECKERBOARD[1]].T.reshape(-1, 2)
_img_shape = None
objpoints = [] # 3d point in real world space
imgpoints = [] # 2d points in image plane.
images = glob.glob(r'C:\Users\Gen\Pictures\Camera Rolljpg')#ここにキャリブレーションしたいフォルダ名を入力
for fname in images:
[ ]img = cv2.imread(fname)
[ ]if _img_shape == None:
[ ]_img_shape = img.shape[:2]
[ ]else:
[ ]assert _img_shape == img.shape[:2], "All images must share the same size."
[ ]gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
[ ]ret, corners = cv2.findChessboardCorners(gray, CHECKERBOARD, cv2.CALIB_CB_ADAPTIVE_THRESH+cv2.CALIB_CB_FAST_CHECK+cv2.CALIB_CB_NORMALIZE_IMAGE) [ ]if ret == True: [ ]objpoints.append(objp) [ ]cv2.cornerSubPix(gray,corners,(3,3),(-1,-1),subpix_criteria) [ ]imgpoints.append(corners)
N_OK = len(objpoints)
K = np.zeros((3, 3))
D = np.zeros((4, 1))
rvecs = [np.zeros((1, 1, 3), dtype=np.float64) for i in range(N_OK)]
tvecs = [np.zeros((1, 1, 3), dtype=np.float64) for i in range(N_OK)]
rms, _, _, _, _ =
cv2.fisheye.calibrate(
objpoints,
imgpoints,
gray.shape[::-1],
K,
D,
rvecs,
tvecs,
calibration_flags,
(cv2.TERM_CRITERIA_EPS+cv2.TERM_CRITERIA_MAX_ITER, 30, 1e-6)
)
print("Found " + str(N_OK) + " valid images for calibration")
print("DIM=" + str(_img_shape[::-1]))
print("K=np.array(" + str(K.tolist()) + ")")
print("D=np.array(" + str(D.tolist()) + ")")
以下3つにprintされたパラメーターを代入
DIM=(_img_shape[::-1])
K=np.array(K.tolist())
D=np.array(D.tolist())
balance=0.95
dim2=None
dim3=None
cap = cv2.VideoCapture(0)
fourcc = cv2.VideoWriter_fourcc(*'DIVX')
out = cv2.VideoWriter('output.avi',fourcc, 20.0, (1280,720))
out1 = cv2.VideoWriter('undistortedop.avi',fourcc, 20.0, (1280,720))
while True:
[ ]ret, frame = cap.read()
[ ]gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
[ ]dim1=(1280,720)
[ ]assert dim1[0]/dim1[1] == DIM[0]/DIM[1],
[ ]if not dim2:
[ ]dim2 = dim1
[ ]if not dim3:
[ ]dim3 = dim1
[ ]dim3=(1280,720)
[ ]scaled_K = K * dim1[0] / DIM[0] # The values of K is to scale with image dimension.
[ ]scaled_K[2][2] = 1.0 # Except that K[2][2] is always 1.0
[ ]new_K = cv2.fisheye.estimateNewCameraMatrixForUndistortRectify(scaled_K, D, dim2, np.eye(3), balance=balance)
[ ]map1, map2 = cv2.fisheye.initUndistortRectifyMap(scaled_K,D,np.eye(3),new_K,dim3, cv2.CV_16SC2)
[ ]undistorted_img = cv2.remap(frame, map1, map2, interpolation=cv2.INTER_LINEAR, borderMode=cv2.BORDER_CONSTANT)
[ ]out1.write(undistorted_img)
[ ]cv2.imshow("undistorted", undistorted_img)
[ ]out.write(frame)
[ ]cv2.imshow('frame',frame)
[ ]if cv2.waitKey(1) & 0xFF == ord('q'):
[ ]break
cap.release()
out.release()
out1.release()
cv2.destroyAllWindows()
試したこと
キャリブレーション用画像の取り直し。
異なった照明状況での撮影。
補足情報(FW/ツールのバージョンなど)
ここにより詳細な情報を記載してください。