2014-04-12 7 views
11

나는 스테레오 캠 장치를 함께 사용하여 좋은 불일치 맵을 생성하는 데 문제가 있습니다. 여기에 두 개의 정류 이미지의 예 내가 그들과 함께 생산 된 상이지도는 다음과 같습니다 당신이 볼 수 있듯이OpenCV에서 StereoBM을 사용하는 불일치 맵

Rectified images with disparity map

는, 결과는 아주 나쁜 있습니다. StereoBM의 설정을 변경해도 그다지 변하지 않습니다.

셋업

  • 카메라는 둘다 동일 모델이며, USB로 컴퓨터에 연결합니다.
  • 그들은 움직이지 않도록 단단한 나무 보드에 고정됩니다. 내가 할 수있는 최선의 방법으로 그들을 정렬했지만, 물론 완벽하지는 않습니다. 그들은 움직일 수 없기 때문에 교정 중 및 교정 후 위치가 동일합니다.
  • OpenCV를 사용하여 스테레오 쌍을 보정하고 OpenCV의 StereoBM 클래스를 사용하여 디스 패리티 맵을 생성합니다.
  • 아마도 그다지 관련이 없지만 파이썬으로 코딩하고 있습니다. 내가 지금까지 전문가가되는,하지만 난 문제를 추측하고있어 교정이나에 내가 처음이 일을하고있어

    상상, 그렇게 할 수

문제 스테레오 정류, 디스 패리티 맵의 계산보다. 나는 StereoBM에 대한 설정의 모든 순열을 시험해 보았습니다. 그리고 다른 결과를 얻었지만, 모두 위의 불일치 맵과 같습니다 : 흑백 패치.

이 개념은 내가 이해할 수있는 것처럼 스테레오 수정이 각 그림의 모든 점을 정렬하여 직선 (내 경우 수평선)으로 연결되도록해야한다는 사실에 의해 뒷받침됩니다. 두 교정 된 사진을 서로 옆에서 조사해 본다면 이것이 사실이 아니라는 것이 즉시 분명합니다. 대응점은 왼쪽보다 오른쪽 그림에서 훨씬 높습니다. 하지만 교정이나 정류가 문제인지는 잘 모르겠습니다.

코드

실제 코드가 객체에 싸여있다 - 당신은 그것의 전체를보고 관심이 경우, 그것은 on GitHub 사용할 수 있습니다.

import cv2 
import numpy as np 

## Load test images 
# TEST_IMAGES is a list of paths to test images 
input_l, input_r = [cv2.imread(image, cv2.CV_LOAD_IMAGE_GRAYSCALE) 
        for image in TEST_IMAGES] 
image_size = input_l.shape[:2] 

## Retrieve chessboard corners 
# CHESSBOARD_ROWS and CHESSBOARD_COLUMNS are the number of inside rows and 
# columns in the chessboard used for calibration 
pattern_size = CHESSBOARD_ROWS, CHESSBOARD_COLUMNS 
object_points = np.zeros((np.prod(pattern_size), 3), np.float32) 
object_points[:, :2] = np.indices(pattern_size).T.reshape(-1, 2) 
# SQUARE_SIZE is the size of the chessboard squares in cm 
object_points *= SQUARE_SIZE 
image_points = {} 
ret, corners_l = cv2.findChessboardCorners(input_l, pattern_size, True) 
cv2.cornerSubPix(input_l, corners_l, 
       (11, 11), (-1, -1), 
       (cv2.TERM_CRITERIA_MAX_ITER + cv2.TERM_CRITERIA_EPS, 
        30, 0.01)) 
image_points["left"] = corners_l.reshape(-1, 2) 
ret, corners_r = cv2.findChessboardCorners(input_r, pattern_size, True) 
cv2.cornerSubPix(input_r, corners_r, 
       (11, 11), (-1, -1), 
       (cv2.TERM_CRITERIA_MAX_ITER + cv2.TERM_CRITERIA_EPS, 
        30, 0.01)) 
image_points["right"] = corners_r.reshape(-1, 2) 

## Calibrate cameras 
(cam_mats, dist_coefs, rect_trans, proj_mats, valid_boxes, 
undistortion_maps, rectification_maps) = {}, {}, {}, {}, {}, {}, {} 
criteria = (cv2.TERM_CRITERIA_MAX_ITER + cv2.TERM_CRITERIA_EPS, 
      100, 1e-5) 
flags = (cv2.CALIB_FIX_ASPECT_RATIO + cv2.CALIB_ZERO_TANGENT_DIST + 
     cv2.CALIB_SAME_FOCAL_LENGTH) 
(ret, cam_mats["left"], dist_coefs["left"], cam_mats["right"], 
dist_coefs["right"], rot_mat, trans_vec, e_mat, 
f_mat) = cv2.stereoCalibrate(object_points, 
           image_points["left"], image_points["right"], 
           image_size, criteria=criteria, flags=flags) 
(rect_trans["left"], rect_trans["right"], 
proj_mats["left"], proj_mats["right"], 
disp_to_depth_mat, valid_boxes["left"], 
valid_boxes["right"]) = cv2.stereoRectify(cam_mats["left"], 
              dist_coefs["left"], 
              cam_mats["right"], 
              dist_coefs["right"], 
              image_size, 
              rot_mat, trans_vec, flags=0) 
for side in ("left", "right"): 
    (undistortion_maps[side], 
    rectification_maps[side]) = cv2.initUndistortRectifyMap(cam_mats[side], 
                  dist_coefs[side], 
                  rect_trans[side], 
                  proj_mats[side], 
                  image_size, 
                  cv2.CV_32FC1) 

## Produce disparity map 
rectified_l = cv2.remap(input_l, undistortion_maps["left"], 
         rectification_maps["left"], 
         cv2.INTER_NEAREST) 
rectified_r = cv2.remap(input_r, undistortion_maps["right"], 
         rectification_maps["right"], 
         cv2.INTER_NEAREST) 
cv2.imshow("left", rectified_l) 
cv2.imshow("right", rectified_r) 
block_matcher = cv2.StereoBM(cv2.STEREO_BM_BASIC_PRESET, 0, 5) 
disp = block_matcher.compute(rectified_l, rectified_r, disptype=cv2.CV_32F) 
cv2.imshow("disparity", disp) 

잘못 여기서 뭐하는거야 : 여기에 실제로 (난 그냥이 사진보다 더를 사용하여 보정, 실제 코드에 물론)을 실행 무슨의 단순화 된 예는?

답변

13

문제는 데이터 자체가 아니라 시각적 인 것으로 나타났습니다. 어쨌든 cv2.reprojectImageTo3D은 부동 소수점 값으로 불일치 맵을 요구했기 때문에 cv2.CV_32Fblock_matcher.compute에서 요청했습니다.

OpenCV 설명서를 더 자세히 읽으면 내가 실수로 이것을 생각하고 있다고 생각하게되었고 실제로는 속도를 위해 부동 소수점으로 정수를 사용하려고했지만 cv2.imshow에 대한 설명서는 명확하지 않았습니다. 16 비트 부호있는 정수 (16 비트 부호없는 것과 비교)를 사용하여 수행하는 작업에 대해 시각화를 위해 값을 수레로 남겨 두었습니다.

documentation of cv2.imshow은 32 비트 부동 소수점 값이 0과 1 사이에 있다고 가정하므로 255로 곱합니다. 255는 픽셀이 흰색으로 표시되는 채도 점입니다. 필자의 경우이 가정은 바이너리 맵을 생성했습니다. 나는 OpenCV가 똑같이한다는 사실을 취소하기 위해 그것을 수동으로 0-255의 범위로 확장 한 다음 255로 나누었다. 나도 알아, 끔찍한 수술이지만, 나는 단지 StereoBM을 오프라인으로 조정하여 성능이 중요하지 않다는 것을 알고있다. 해결책은 다음과 같습니다.

# Other code as above 
disp = block_matcher.compute(rectified_l, rectified_r, disptype=cv2.CV_32F) 
norm_coeff = 255/disp.max() 
cv2.imshow("disparity", disp * norm_coeff/255) 

그러면 불일치 맵은 괜찮아 보입니다.

관련 문제