Files
2022-12-12 17:35:24 +08:00

136 lines
4.8 KiB
Python

# Copyright(C) 2022. Huawei Technologies Co.,Ltd. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import glob
import math
import collections
import cv2
import numpy as np
import camera_configs
from yolov3_infer import yolo_infer
LEFTIMG = "left_*.jpg"
RIGHTIMG = "right_*.jpg"
YOLO_RESIZELEN = 416
def get_rectify(height, width):
left_matrix = camera_configs.left_camera_matrix
right_matrix = camera_configs.right_camera_matrix
left_distortion = camera_configs.left_distortion
right_distortion = camera_configs.right_distortion
R = camera_configs.R
T = camera_configs.T
# Image size
size = (width, height)
# Calculate correction transformation
R1, R2, P1, P2, Q, validPixROI1, validPixROI2 = cv2.stereoRectify(left_matrix, left_distortion,
right_matrix, right_distortion, size, R, T)
# Calculate correction map
left_map1, left_map2 = cv2.initUndistortRectifyMap(left_matrix, left_distortion, R1, P1, size, cv2.CV_16SC2)
right_map1, right_map2 = cv2.initUndistortRectifyMap(right_matrix, right_distortion, R2, P2, size, cv2.CV_16SC2)
Camera = collections.namedtuple('Camera', ['left_map1', 'left_map2', 'right_map1', 'right_map2', 'Q'])
camera = Camera(left_map1, left_map2, right_map1, right_map2, Q)
return camera
def stereo_match(imgleft, imgright):
stereo = cv2.StereoSGBM_create(minDisparity=0,
numDisparities=16 * 6,
blockSize=5,
P1=216,
P2=864,
disp12MaxDiff=1,
uniquenessRatio=10,
speckleWindowSize=0,
speckleRange=1,
preFilterCap=60,
mode=cv2.STEREO_SGBM_MODE_SGBM_3WAY)
disparity = stereo.compute(imgleft, imgright)
return disparity
if __name__ == '__main__':
left_paths = []
left_paths.extend(glob.glob(os.path.join("image", LEFTIMG)))
left_paths.sort()
right_paths = []
right_paths.extend(glob.glob(os.path.join("image", RIGHTIMG)))
right_paths.sort()
if len(left_paths) == 0 or len(right_paths) == 0:
print("The dataset is empty!.Please check the dataset and files.")
exit()
if len(left_paths) != len(right_paths):
print("Picture missing!.Please check the dataset and files.")
exit()
paths = zip(left_paths, right_paths)
NUM = 0
for left, right in paths:
img1 = cv2.imread(left)
img2 = cv2.imread(right)
img_height, img_width = img1.shape[0:2]
configs = get_rectify(img_height, img_width)
# Distortion correction
img1_rectified = cv2.remap(img1, configs.left_map1, configs.left_map2, cv2.INTER_LINEAR)
img2_rectified = cv2.remap(img2, configs.right_map1, configs.right_map2, cv2.INTER_LINEAR)
cv2.imwrite("SGBM_left.jpg", img1_rectified)
# Set the picture as a grayscale image to prepare for SGBM
imgL = cv2.cvtColor(img1_rectified, cv2.COLOR_BGR2GRAY)
imgR = cv2.cvtColor(img2_rectified, cv2.COLOR_BGR2GRAY)
# Generate parallax map according to SGBM/Semi-Global Block Matching
parallax = stereo_match(imgL, imgR)
# Expand the picture to 3d space, and the value in z direction is the current distance
threeD = cv2.reprojectImageTo3D(parallax.astype(np.float32) / 16., configs.Q)
coordinate = yolo_infer("SGBM_left.jpg", YOLO_RESIZELEN)
NUM += 1
print("The result of case %d :" % NUM)
for coor in coordinate:
x = coor.x1
y = coor.y1
name = coor.className
x = int(x)
y = int(y)
print('\nPixel coordinates x = {}, y = {}'.format(x, y))
x = x - 1
y = y - 1
print("3D coordinates ({:f}, {:f}, {:f}) mm ".format(threeD[y][x][0], threeD[y][x][1], threeD[y][x][2]))
distance = math.sqrt(threeD[y][x][0] ** 2 + threeD[y][x][1] ** 2 + threeD[y][x][2] ** 2)
distance = distance / 1000.0 # mm -> m
print("{}'s actual distance: {:f} m\n".format(name, distance))
os.remove("SGBM_left.jpg")