728x90
모든 카메라에는
이미지 센서와 렌즈사이는 정확하게 나란하지 않아 약간의 이미지 왜곡이 발생한다.
이 왜곡에 대한 행렬을 camera matrix라 한다.
camera matrix는 카매라 내부 (왜곡 정도에 대한) 행렬과
카메라 이미지 평면 ~ 외부 물체에 대한 회전, 평행이동에 대한 백터로 이루어진다.
카메라 캘리브레이션 카메라 왜곡 행렬 camera matrix를 찾아주는 작업이다.
스테레오 비전 같은 3차원 복원을 한다면 이 카메라 왜곡을 잡아주어야 한다.
자세한 설명은 다음 링크에서
ref : https://darkpgmr.tistory.com/32
카매라 캘리브레이션은 체스판이 있으면 할수 있는데,
테블릿에다 채스보드를 띄워서 검출했다.
카메라 매트릭스와 왜곡 계수를 구하였으면
이 값으로 왜곡된 카메라 영상을 보정시킬수가 있다.
import numpy as np
import cv2
import glob
import pickle
import time
#https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_calib3d/py_calibration/py_calibration.html
#https://stackoverflow.com/questions/6568007/how-do-i-save-and-restore-multiple-variables-in-python
#This should be as close to zero as possible
def reprojection_error(imgpoints, objpoints, mtx, dist, rvecs, tvecs):
mean_error = 0
for i in range(len(objpoints)):
imgpoints2, _ = cv2.projectPoints(objpoints[i], rvecs[i], tvecs[i], mtx, dist)
error = cv2.norm(imgpoints[i],imgpoints2, cv2.NORM_L2)/len(imgpoints2)
mean_error = mean_error + error
print("total error: " + str(mean_error/len(objpoints)))
return mean_error
# 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((4*6,3), np.float32)
objp[:,:2] = np.mgrid[0:6,0:4].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.
cap = cv2.VideoCapture(0)
while(len(objpoints) < 20):
ret, frame = cap.read()
frame = cv2.flip(frame, -1)
rsz = cv2.resize(frame, dsize=(320,240))
gray = cv2.cvtColor(rsz, cv2.COLOR_BGR2GRAY)
# Find the chess board corners
ret, corners = cv2.findChessboardCorners(gray, (6,4),None)
# If found, add object points, image points (after refining them)
if ret == True:
objpoints.append(objp)
corners2 = cv2.cornerSubPix(gray,corners,(11,11),(-1,-1),criteria)
imgpoints.append(corners2)
# Draw and display the corners
gray = cv2.drawChessboardCorners(gray, (6,4), corners2,ret)
print("chessobard corner detected. curr num objpoints : " + str(len(objpoints)) + ", curr num imgpoints : " + str(len(imgpoints)))
time.sleep(0.2)
cv2.imshow('res',gray)
if cv2.waitKey(20) & 0xFF == ord('q'):
break
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1],None,None)
reprojection_error(imgpoints, objpoints, mtx, dist, rvecs, tvecs)
cap.release()
cv2.destroyAllWindows()
print("camera matrix")
print(mtx)
print("distortion coeff")
print(dist)
# Saving the objects:
with open('cam_calib.pkl', 'wb') as f:
pickle.dump([mtx, dist, rvecs, tvecs], f)
지금 사용하는 파이 카메라는 내부 왜곡이 크지 않아서인지 보정 전과 후에도 큰 차이가 없다.
실제 이미지 왜곡은 다음 링크를 참조하는게 좋을것같다.
ref : https://medium.com/analytics-vidhya/camera-calibration-with-opencv-f324679c6eb7
import numpy as np
import cv2
import glob
import pickle
def get_cameramat_dist(filename):
f = open(filename, 'rb')
mat, dist, rvecs, tvecs = pickle.load(f)
f.close()
print("camera matrix")
print(mat)
print("distortion coeff")
print(dist)
return mat,dist
def main():
mat, dist = get_cameramat_dist("cam_calib.pkl")
cap = cv2.VideoCapture(0)
ret, frame = cap.read()
frame = cv2.flip(frame, -1)
rsz = cv2.resize(frame, dsize=(320,240))
gray = cv2.cvtColor(rsz, cv2.COLOR_BGR2GRAY)
h, w = gray.shape[:2]
newcameramtx, roi=cv2.getOptimalNewCameraMatrix(mat,dist,(w,h),1,(w,h))
while(True):
ret, frame = cap.read()
frame = cv2.flip(frame,-1)
rsz = cv2.resize(frame, dsize=(320,240))
gray = cv2.cvtColor(rsz, cv2.COLOR_BGR2GRAY)
# undistort
mapx,mapy = cv2.initUndistortRectifyMap(mat,dist,None,newcameramtx,(w,h),5)
res = cv2.remap(gray,mapx,mapy,cv2.INTER_LINEAR)
# crop the image
x,y,w,h = roi
res = res[y:y+h, x:x+w]
cv2.imshow('res',res)
if cv2.waitKey(20) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
if __name__ == "__main__":
main()
300x250
'로봇 > 로봇' 카테고리의 다른 글
zumi - 30. monoVo-python 분석, 수정하기 fail (0) | 2020.08.28 |
---|---|
zumi - 28. 피처매칭과 호모그래피 (0) | 2020.08.28 |
zumi - 27. ORB 특징, 브루트포스 매처를 이용한 피처 매칭 (0) | 2020.08.28 |
zumi - 26. pi에서 빌드없이 opencv 설치하기 (0) | 2020.08.28 |
zumi - 25. mpu6050 가속도계로 속도, 위치 구하기 fail (0) | 2020.08.28 |