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 同步传输时每一帧数据包 中负载信息 确定每一路帧规律 确定软同步方案