同频同帧测试记录

该代码示例展示了如何使用OpenCV和线程池来处理多个摄像头的视频流,实现图像抓取和保存。通过调整摄像头参数和使用并发执行来优化读取和保存帧的时间,同时探讨了软同步的可能性,即基于时间戳的帧同步策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

from concurrent.futures import ThreadPoolExecutor
import threading
import cv2
import time

take_from_video_flag = False
quit_flag = False
take_count_once = 20
take_current_count = 0


def get_photo():
    cap = cv2.VideoCapture(0)
    f, frame = cap.read()
    cv2.imwrite('image.jpg', frame)
    cap.release()

# tof


def take_pic_from_tof(camera_id):
    print("take_pic_from_top:")


def take_pic_from_video(camera_id):
    global take_from_video_flag
    take_from_video_flag = True


def save_frame(frame, camera_id,index):
    format = "%Y_%m_%d_%H_%M_%S"
    file_name = str(camera_id) + "_" + \
        time.strftime(format, time.localtime()) + "_" + str(index) + ".jpg"
    print("file_name:", file_name)
    cv2.imwrite("./save/"+file_name, frame)
    # cv2.imwrite(file_name, frame)
    print("imwrite end:", file_name)


def open_camera(camera_id):
    print("opencamera id:", camera_id)
    cap = cv2.VideoCapture(camera_id, cv2.CAP_DSHOW)
    cap.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc('M', 'J', 'P', 'G'))
    if not cap.isOpened():
        print("Cannot open camera")
        exit()
    cap.set(cv2.CAP_PROP_FRAME_WIDTH, 1280)
    cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 1024)
    cap.set(cv2.CAP_PROP_FPS, 30)
    # cap.set(cv2.CAP_PROP_BRIGHTNESS, 1)
    # cap.set(cv2.CAP_PROP_CONTRAST,40)
    # cv2无法设置fps,但我可以用以下方式更改fps
    fps = cap.get(cv2.CAP_PROP_FPS)

    print("fps:", fps)
    width = cap.get(cv2.CAP_PROP_FRAME_WIDTH)
    print("width", width)
    height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
    print("height", height)
    timestamp_from_start = cap.get(cv2.CAP_PROP_POS_MSEC)
    print("timestamp_from_start", timestamp_from_start)
    return cap


def save_pic_with_thread(frame, camera_id,index):
    t = threading.Thread(target=save_frame(frame, camera_id,index))
    t.start()


def main():
    global take_from_video_flag
    global take_count_once
    global take_current_count
    pool = ThreadPoolExecutor(max_workers=1)
    cap0 = open_camera(0)
    time.sleep(3)
    cap1 = open_camera(1)
    
    cv2.namedWindow("camera0", cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO)
    cv2.namedWindow("camera1", cv2.WINDOW_NORMAL | cv2.WINDOW_KEEPRATIO)
    cv2.resizeWindow("camera0",320,256)
    cv2.resizeWindow("camera1",320,256)
        
    while True:
        start_time = time.time()
        cap0.grab()
        cap1.grab()
        
        # read_code, frame = cap0.read()
        # read_code2, frame1 = cap1.read()
        read_code, frame = cap0.retrieve()
        read_code2, frame1 = cap1.retrieve()
        if not read_code or not read_code2:
            break
      
        read_time = (time.time() - start_time)*1000
        print("read time :",read_time)
        cv2.imshow("camera0", frame)
        cv2.imshow("camera1", frame1)

        if take_from_video_flag:
            pool.submit(save_pic_with_thread,frame,0,take_current_count)
            pool.submit(save_pic_with_thread,frame1,1,take_current_count)
            # save_pic_with_thread(frame=frame, camera_id=0,index=take_current_count)
            # save_pic_with_thread(frame=frame1, camera_id=1,index=take_current_count)
            # if(take_current_count <= take_count_once):
            #     take_from_video_flag = True
            #     take_current_count = take_current_count+1
            # else:
            #     take_current_count = 0
            #     take_from_video_flag = False

        if cv2.waitKey(1) == ord('s'):
            print("save_pic: main")
            take_from_video_flag = True
            # save_frame(frame, 0)
            # save_frame(frame1, 1)
        elif cv2.waitKey(1) == ord('q'):
            print("quit: main")
          
            break

    print("quit: destroy")
    cap0.release()
    cap1.release()
    pool.shutdown()
    cv2.destroyAllWindows()
    cv2.destroyAllWindows()


if __name__ == "__main__":
    main()

UVC 负载数据头 Payload Header Information-摄像头数据包格式分析 - USB中文网

由于 opencv 上层api封装 无法真正获取uvc协议层 一些原始信息  

理论上 软同步基于 时间戳 可控制 偏差在固定帧差内 (待进一步研究)) 

可通过 usb抓包工具分析 多路摄像头 传入 iso 同步传输时每一帧数据包 中负载信息 确定每一路帧规律 确定软同步方案 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值