Python 은 OpenCV 를 사용 하여 표시 합 니 다.

본 고 는 OpenCV 공식 사례 와 결합 하여 공식 사례 중의 코드 를 수정 하여 정상적으로 운행 할 수 있 도록 하고 자신 이 수집 한 데 이 터 를 실험 하고 설명 한다.
준비 하 다
OpenCV 는 다음 그림 과 같이 바둑판 격 판 을 사용 하여 표시 한다.카 메 라 를 표시 하기 위해 서 우 리 는 일련의 3 차원 점 과 그들 에 대응 하 는 2 차원 이미지 점 을 입력 해 야 한다.흑백 이 섞 인 바둑판 칸 에서 2 차원 이미지 포 인 트 는 각 점 검 사 를 통 해 쉽게 찾 을 수 있다.실제 세계 의 3 차원 점 에 대해 서 는?우리 가 채집 하 는 것 은 카 메 라 를 한 곳 에 두 고 바둑판 의 표지 판 을 이동 시 켜 서로 다른 위 치 를 바 꾸 어 촬영 하 는 것 이기 때문이다.그래서 우 리 는(X,Y,Z)의 값 을 알 아야 한다.그러나 쉽게 말 하면 우 리 는 바둑판 칸 이 있 는 평면 을 XY 평면,즉 Z=0 으로 정의 한다.표지 판 에 있어 서 우 리 는 바둑판 칸 의 사각형 사 이 즈 를 알 수 있다.예 를 들 어 30mm 이다.그러면 우 리 는 바둑판 칸 의 각 점 좌 표를(0,0,0),(30,0,0),(60,0,0)로 정의 할 수 있다.
3D 점 을 object points 라 고 하고 2D 이미지 점 을 image points 라 고 합 니 다.

2.바둑판 격 각 점 검 측
바둑판 격자 템 플 릿 을 찾기 위해 openCV 의 함수 cv2.find Chessboard Corners()를 사용 합 니 다.우리 도 프로그램 에 우리 가 사용 하 는 템 플 릿 이 어떤 규격 인지 알려 야 한다.예 를 들 어 8*8 의 바둑판 칸 이나 5*5 바둑판 칸 등 은 x 방향 과 y 방향 개수 가 같 지 않 은 바둑판 칸 템 플 릿 을 사용 하 는 것 을 권장 한다.아래 실험 에서 우리 가 사용 한 것 은 10*7 의 바둑판 칸 으로 각 칸 의 길 이 는 20mm 이 며,즉 9*6 의 내부 각 점 을 함유 하고 있다.이 함수 가 템 플 릿 을 감지 하면 해당 하 는 각 점 을 되 돌려 주 고 트 루 로 돌아 갑 니 다.물론 모든 그림 이 필요 한 템 플 릿 을 찾 을 수 있 는 것 은 아니 므 로 여러 폭 의 그림 으로 표 시 를 할 수 있 습 니 다.바둑판 칸 을 사용 하 는 것 외 에 우 리 는 원점 진 을 사용 할 수 있 으 며,대응 하 는 함 수 는 cv2.find Circlesgrid()이다.
각 점 을 찾 으 면 cv2.corner SubPix()를 사용 하면 더욱 정확 한 각 점 픽 셀 좌 표를 얻 을 수 있 습 니 다.cv2.drawChessboard Corners()를 사용 하여 각 점 을 그림 에 그 릴 수 있 습 니 다.다음 그림 에서 보 듯 이:

3.표지
위의 절 차 를 통 해 우 리 는 표 시 된 3 차원 점 과 이에 대응 하 는 이미지 의 2 차원 점 을 얻 었 다.우 리 는 cv2.calibleeCamera()를 사용 하여 표 시 를 합 니 다.이 함 수 는 표 시 된 결과,카메라 의 내 매개 변수 행렬,기형 적 변화 계수,회전 행렬 과 평 이 벡터 를 되 돌려 줍 니 다.
4.기형 적 변화 제거
세 번 째 단 계 는 카메라 내 삼 과 기변 계 수 를 얻 었 습 니 다.이미 지 를 기변 하기 전에 cv.getOptimal NewCameraMatrix()를 사용 하여 내 파라미터 와 기변 계 수 를 최적화 하고 자유 자유 비례 인자 alpha 를 설정 할 수 있 습 니 다.알파 가 0 으로 설정 되 었 을 때 편집 한 기형 적 변 화 를 제거 한 후 원 하지 않 는 픽 셀 에서 제거 한 내 매개 변수 와 기형 적 변 수 를 되 돌려 줍 니 다.알파 가 1 로 설정 되 었 을 때,검은색 픽 셀 점 을 추가 로 포함 하 는 내부 파라미터 와 기변 계 수 를 되 돌려 주 고,이 를 편집 하 는 데 사용 할 ROI 를 되 돌려 줍 니 다.
그 다음 에 우 리 는 새로 얻 은 내부 매개 변수 행렬 과 기형 적 변화 계 수 를 사용 하여 이미지 에 대해 기형 적 변 화 를 제거 할 수 있다.기형 적 인 변 화 를 없 애 는 두 가지 방법 이 있다.
(1)cv2.undistort 사용()
이것 은 함 수 를 직접 호출 하면 기형 적 인 이미 지 를 얻 을 수 있 고 위의 ROI 를 사용 하여 편집 할 수 있 는 가장 직접적인 방법 이다.코드 는 다음 과 같 습 니 다:

# undistort
dst = cv2.undistort(img, mtx, dist, None, newcameramtx)

# crop the image
x,y,w,h = roi
dst = dst[y:y+h, x:x+w]
cv2.imwrite('calibresult.png',dst)
다음 그림 은 그림 한 장 을 기형 적 으로 변화 시 킨 후에 검은색 픽 셀 을 유지 하 는 결 과 를 보 여 줍 니 다.

(2)remmaping 사용
이것 은 두 단계 로 나 누 는 방법 이다.먼저 기형 적 인 이미지 에서 비 기형 적 인 이미지 로 의 매 핑 을 계산 한 다음 에 이 매 핑 관 계 를 이용 하여 이미지 에 대해 기형 적 인 변 화 를 제거 하 는 것 이다.
코드 는 다음 과 같 습 니 다:

# undistort
mapx,mapy = cv2.initUndistortRectifyMap(mtx,dist,None,newcameramtx,(w,h),5)
dst = cv2.remap(img,mapx,mapy,cv2.INTER_LINEAR)

# crop the image
x,y,w,h = roi
dst = dst[y:y+h, x:x+w]
cv2.imwrite('calibresult.png',dst)
5.반 투영 오차
반 투영 오 차 를 통 해 우 리 는 결과 의 좋 고 나 쁨 을 평가 할 수 있다.0 에 가 까 울 수록 결과 가 이상 적 이라는 뜻 이다.이전에 계 산 된 내 매개 변수 매트릭스,기변 계수,회전 매트릭스 와 평이 벡터 를 통 해 cv2.procject Points()를 사용 하여 3 차원 점 에서 2 차원 이미지 의 투영 을 계산 한 다음 에 반 투영 으로 얻 은 점 과 이미지 에서 검출 된 점 의 오 차 를 계산 하고 마지막 으로 표 시 된 이미지 에 대한 평균 오 차 를 계산한다.이 값 은 반 투영 오차 이다.
코드
모든 절차 의 코드 는 다음 과 같다.

#coding:utf-8
import cv2
import numpy as np
import glob

#       
#   
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
#       
w = 9
h = 6
#            ,  (0,0,0), (1,0,0), (2,0,0) ....,(8,5,0),  Z  ,      
objp = np.zeros((w*h,3), np.float32)
objp[:,:2] = np.mgrid[0:w,0:h].T.reshape(-1,2)
#                   
objpoints = [] #            
imgpoints = [] #          

images = glob.glob('calib/*.png')
for fname in images:
 img = cv2.imread(fname)
 gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
 #        
 ret, corners = cv2.findChessboardCorners(gray, (w,h),None)
 #         ,      
 if ret == True:
  cv2.cornerSubPix(gray,corners,(11,11),(-1,-1),criteria)
  objpoints.append(objp)
  imgpoints.append(corners)
  #          
  cv2.drawChessboardCorners(img, (w,h), corners, ret)
  cv2.imshow('findCorners',img)
  cv2.waitKey(1)
cv2.destroyAllWindows()

#   
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)

#    
img2 = cv2.imread('calib/00169.png')
h, w = img2.shape[:2]
newcameramtx, roi=cv2.getOptimalNewCameraMatrix(mtx,dist,(w,h),0,(w,h)) #       
dst = cv2.undistort(img2, mtx, dist, None, newcameramtx)
#     ROI      
#x,y,w,h = roi
#dst = dst[y:y+h, x:x+w]
cv2.imwrite('calibresult.png',dst)

#      
total_error = 0
for i in xrange(len(objpoints)):
 imgpoints2, _ = cv2.projectPoints(objpoints[i], rvecs[i], tvecs[i], mtx, dist)
 error = cv2.norm(imgpoints[i],imgpoints2, cv2.NORM_L2)/len(imgpoints2)
 total_error += error
print "total error: ", total_error/len(objpoints)
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기