diff --git a/lib/librknn_api.so b/lib/librknn_api.so new file mode 100644 index 0000000..5c886a0 Binary files /dev/null and b/lib/librknn_api.so differ diff --git a/lib/librknnrt.so b/lib/librknnrt.so new file mode 100644 index 0000000..1a9dc54 Binary files /dev/null and b/lib/librknnrt.so differ diff --git a/lib/rknn_toolkit_lite2-2.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl b/lib/rknn_toolkit_lite2-2.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl new file mode 100644 index 0000000..d49aaac Binary files /dev/null and b/lib/rknn_toolkit_lite2-2.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl differ diff --git a/model/anchors_yolov5.txt b/model/anchors_yolov5.txt new file mode 100644 index 0000000..680a13e --- /dev/null +++ b/model/anchors_yolov5.txt @@ -0,0 +1,18 @@ +10.0 +13.0 +16.0 +30.0 +33.0 +23.0 +30.0 +61.0 +62.0 +45.0 +59.0 +119.0 +116.0 +90.0 +156.0 +198.0 +373.0 +326.0 diff --git a/model/bus.jpg b/model/bus.jpg new file mode 100644 index 0000000..d8ef30b Binary files /dev/null and b/model/bus.jpg differ diff --git a/model/coco_80_labels_list.txt b/model/coco_80_labels_list.txt new file mode 100644 index 0000000..941cb4e --- /dev/null +++ b/model/coco_80_labels_list.txt @@ -0,0 +1,80 @@ +person +bicycle +car +motorcycle +airplane +bus +train +truck +boat +traffic light +fire hydrant +stop sign +parking meter +bench +bird +cat +dog +horse +sheep +cow +elephant +bear +zebra +giraffe +backpack +umbrella +handbag +tie +suitcase +frisbee +skis +snowboard +sports ball +kite +baseball bat +baseball glove +skateboard +surfboard +tennis racket +bottle +wine glass +cup +fork +knife +spoon +bowl +banana +apple +sandwich +orange +broccoli +carrot +hot dog +pizza +donut +cake +chair +couch +potted plant +bed +dining table +toilet +tv +laptop +mouse +remote +keyboard +cell phone +microwave +oven +toaster +sink +refrigerator +book +clock +vase +scissors +teddy bear +hair drier +toothbrush diff --git a/model/download_model.sh b/model/download_model.sh new file mode 100644 index 0000000..15c3ed4 --- /dev/null +++ b/model/download_model.sh @@ -0,0 +1 @@ +wget -O ./yolov5s_relu.onnx https://ftrg.zbox.filez.com/v2/delivery/data/95f00b0fc900458ba134f8b180b3f7a1/examples/yolov5/yolov5s_relu.onnx diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..11547a9 --- /dev/null +++ b/templates/index.html @@ -0,0 +1,18 @@ + + + +Surround View System + +

🚗 四路摄像头 + 环视鸟瞰图

+
+

四路分屏

+ +
+
+

鸟瞰图 (Bird's Eye View)

+ +
+

按 Ctrl+C 停止服务 | 账号: admin / 密码: password123

+ + + \ No newline at end of file diff --git a/video.py b/video.py index f4addec..53be331 100644 --- a/video.py +++ b/video.py @@ -7,7 +7,6 @@ import numpy as np from surround_view import FisheyeCameraModel, BirdView import surround_view.param_settings as settings - class MultiCameraBirdView: def __init__(self): self.running = True @@ -138,7 +137,7 @@ def main(): birdview = BirdView() Gmat, Mmat = birdview.get_weights_and_masks(projected) # 初始化权重矩阵 birdview.update_frames(projected) - birdview.stitch_all_parts() + birdview.get_weights_and_masks.stitch_all_parts() birdview.make_white_balance() birdview.copy_car_image() img_small = cv2.resize(birdview.image, (300, 600)) diff --git a/web.py b/web.py new file mode 100644 index 0000000..3991678 --- /dev/null +++ b/web.py @@ -0,0 +1,156 @@ +# from turtle import right +import cv2 +import threading +import sys +import os +import argparse +import numpy as np +from surround_view import FisheyeCameraModel, BirdView +import surround_view.param_settings as settings + +right_frame = None + +class MultiCameraBirdView: + def __init__(self): + self.running = True + self.names = settings.camera_names # e.g., ['front', 'back', 'left', 'right'] + self.yamls = [os.path.join(os.getcwd(), "yaml", name + ".yaml") for name in self.names] + self.camera_models = [ + FisheyeCameraModel(camera_file, camera_name) + for camera_file, camera_name in zip(self.yamls, self.names) + ] + + # 摄像头设备映射 + self.which_cameras = {"front": 0, "back": 2, "left": 1, "right": 3} + self.caps = [] + + print("[INFO] 初始化摄像头...") + for name in self.names: + cap = cv2.VideoCapture(self.which_cameras[name], cv2.CAP_ANY) + cap.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc(*"YUYV")) + cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1920) + cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 1080) + cap.set(cv2.CAP_PROP_BUFFERSIZE, 1) # 最小缓冲,降低延迟 + if not cap.isOpened(): + print(f"[ERROR] 无法打开 {name} 摄像头 (设备 {self.which_cameras[name]})", file=sys.stderr) + self.running = False + return + self.caps.append(cap) + + self.birdview = BirdView() + self._initialize_weights() + + def _initialize_weights(self): + try: + images = [os.path.join(os.getcwd(), "images", name + ".png") for name in self.names] + static_frames = [] + for img_path, cam_model in zip(images, self.camera_models): + img = cv2.imread(img_path) + if img is None: + print(f"[WARN] 静态图缺失: {img_path},用黑图代替") + img = np.zeros((1080, 1920, 3), dtype=np.uint8) + img = cam_model.undistort(img) + img = cam_model.project(img) + img = cam_model.flip(img) + static_frames.append(img) + if len(static_frames) == 4: + self.birdview.get_weights_and_masks(static_frames) + print("[INFO] 权重矩阵初始化成功") + except Exception as e: + print(f"[ERROR] 权重初始化失败: {e}", file=sys.stderr) + + def process_frame_once(self, frame, model): + """只处理一次:去畸变 + 投影 + 翻转""" + frame = model.undistort(frame) + frame = model.project(frame) + frame = model.flip(frame) + return frame + + def process_frame_undistort(self, frame, model): + """只处理一次:去畸变 + 投影 + 翻转""" + frame = model.undistort(frame) + # frame = model.project(frame) + # frame = model.flip(frame) + return frame + + def run(self): + current_view = "front" # 默认显示前视图 + + while self.running: + raw_frames = {} + processed_frames = [] + valid = True + + # 读取并处理所有摄像头帧 + for i, (cap, model, name) in enumerate(zip(self.caps, self.camera_models, self.names)): + ret, frame = cap.read() + if not ret or frame is None: + print(f"[WARN] 跳过 {name} 帧") + valid = False + break + # 保存原始帧(用于右侧显示) + raw_frames[name] = frame.copy() + # 处理用于鸟瞰图的帧 + p_frame = self.process_frame_once(frame, model) + processed_frames.append(p_frame) + + if not valid or len(processed_frames) != 4: + continue + + # 更新鸟瞰图 + self.birdview.update_frames(processed_frames) + self.birdview.stitch_all_parts() + self.birdview.make_white_balance() + self.birdview.copy_car_image() + + # 获取当前选中的单路图像(已校正) + single_img = self.process_frame_undistort(raw_frames[current_view], self.camera_models[self.names.index(current_view)]) + birdview_img = self.birdview.image + + # 拼接显示:左侧鸟瞰图(1/3),右侧单路(2/3) + h_display, w_display = 720, 1280 + w_bird = w_display // 3 + w_single = w_display - w_bird + + bird_resized = cv2.resize(birdview_img, (w_bird, h_display)) + single_resized = cv2.resize(single_img, (w_single, h_display)) + display = np.hstack((bird_resized, single_resized)) + + + + cv2.namedWindow('Video', cv2.WND_PROP_FULLSCREEN) + cv2.setWindowProperty('Video', cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN) + cv2.imshow("Video", display) + + key = cv2.waitKey(1) & 0xFF + if key == ord('q'): + self.running = False + break + elif key == ord('1'): + current_view = "front" + elif key == ord('2'): + current_view = "back" + elif key == ord('3'): + current_view = "left" + elif key == ord('4'): + current_view = "right" + + # 释放资源 + for cap in self.caps: + cap.release() + cv2.destroyAllWindows() + + +def main(): + print("🚀 启动实时四路环视系统...") + print("操作说明:") + print(" 1 - 前视图 | 2 - 后视图 | 3 - 左视图 | 4 - 右视图") + print(" q - 退出程序") + multi_cam = MultiCameraBirdView() + if multi_cam.running: + multi_cam.run() + else: + print("[ERROR] 摄像头初始化失败") + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/yolov5s-640-640.rknn b/yolov5s-640-640.rknn new file mode 100644 index 0000000..3e233fc Binary files /dev/null and b/yolov5s-640-640.rknn differ