opencv_webcam/opencv_webcam.py

182 lines
7.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# OpenCV Webcam Script v0.2
# 创建人:曾逸夫
# 创建时间2022-01-02
import cv2
from pathlib import Path
import argparse
import time
import glob
import os
from utils.ows_path import increment_path
def parse_args(known=False):
parser = argparse.ArgumentParser(description='OpenCV Webcam Script')
parser.add_argument('--device', '-dev', default=0,
type=int, help='device index for webcam')
parser.add_argument('--quit', '-q', default="q",
type=str, help='quit key for webcam')
parser.add_argument('--is_autoSaveFrame', '-isasf',
action='store_true', help='is auto save frame')
parser.add_argument('--is_handSaveFrame', '-ishsf',
action='store_true', help='is hand save frame')
parser.add_argument('--is_resizeFrame', '-isrf',
action='store_true', help='is resize frame')
parser.add_argument('--frame_saveDir', '-fsd',
default="./WebcamFrame", type=str, help='save frame dir')
parser.add_argument('--frame_nSave', '-fns', default=1,
type=int, help='n frames save a frame (auto save frame)')
parser.add_argument('--frame_capKey', '-fck', default="a",
type=str, help='frame capture key (hand save frame)')
parser.add_argument('--resize_frame', '-rf',
default=[640, 480], type=int, nargs='+', help='resize frame save')
parser.add_argument('--resizeRatio_frame', '-rrf',
default=1.0, type=float, help='resize ratio frame save')
parser.add_argument('--frame_namePrefix', '-fnp',
default="frame", type=str, help='frame name prefix')
parser.add_argument('--frame_saveStyle', '-fss',
default="jpg", type=str, help='frame save style')
parser.add_argument('--jpg_quality', '-jq',
default=95, type=int, help='frame save jpg quality (0-100) default 95')
parser.add_argument('--png_quality', '-pq',
default=3, type=int, help='frame save jpg quality (0-9) default 3')
parser.add_argument('--pause', '-p',
default="p", type=str, help='webcam pause')
args = parser.parse_known_args()[0] if known else parser.parse_args()
return args
# 帧保存
def frame_opt(frame, frame_savePath, frame_num, is_resizeFrame, resize_frame, resizeRatio_frame,
frame_namePrefix, frame_saveStyle, jpg_quality, png_quality):
# 判断图片质量范围
if (jpg_quality < 0 or jpg_quality > 100):
print(f'JPG质量系数超出范围无法保存')
return
if (png_quality < 0 or png_quality > 9):
print(f'PNG质量系数超出范围无法保存')
return
if (is_resizeFrame): # resize frame
w_resize = int(
resize_frame[0] * resizeRatio_frame) # 重塑宽度
h_resize = int(
resize_frame[1] * resizeRatio_frame) # 重塑高度
frame_new = cv2.resize(
frame, (w_resize, h_resize), interpolation=cv2.INTER_AREA) # 重塑
if (frame_saveStyle == 'jpg'):
cv2.imwrite(
f'./{frame_savePath}/{frame_namePrefix}-{frame_num}.{frame_saveStyle}', frame_new,
[int(cv2.IMWRITE_JPEG_QUALITY), jpg_quality])
elif (frame_saveStyle == 'png'):
cv2.imwrite(
f'./{frame_savePath}/{frame_namePrefix}-{frame_num}.{frame_saveStyle}', frame_new,
[int(cv2.IMWRITE_PNG_COMPRESSION), png_quality])
else:
print(f'帧格式有问题!无法保存!')
return
else:
if (frame_saveStyle == 'jpg'):
cv2.imwrite(
f'./{frame_savePath}/{frame_namePrefix}-{frame_num}.{frame_saveStyle}', frame,
[int(cv2.IMWRITE_JPEG_QUALITY), jpg_quality])
elif (frame_saveStyle == 'png'):
cv2.imwrite(
f'./{frame_savePath}/{frame_namePrefix}-{frame_num}.{frame_saveStyle}', frame,
[int(cv2.IMWRITE_PNG_COMPRESSION), png_quality])
else:
print(f'帧格式有问题!无法保存!')
return
# Webcam OpenCV
def webcam_opencv(device_index, quit_key, pause_key, is_autoSaveFrame, frame_saveDir, frame_nSave, is_handSaveFrame,
frame_capKey, is_resizeFrame, resize_frame, resizeRatio_frame, frame_namePrefix, frame_saveStyle,
jpg_quality, png_quality):
if (quit_key == frame_capKey): # 判断快捷键冲突
print(f'快捷键冲突! 程序结束!')
return
s_time = time.time() # 起始时间
cap = cv2.VideoCapture(device_index) # 连接设备
frame_width = cap.get(3) # 宽度
frame_height = cap.get(4) # 高度
fps = cap.get(5) # 帧率
print(f'宽度:{frame_width}, 高度:{frame_height} FPS{fps}')
success, _ = cap.read() # 读取设备
if success: # 连接设备成功
print(f'摄像头连接成功!')
if is_autoSaveFrame or is_handSaveFrame:
# 帧保存路径管理
frame_savePath = increment_path(
Path(f"{frame_saveDir}") / "frames", exist_ok=False) # 增量运行
frame_savePath.mkdir(parents=True, exist_ok=True) # 创建目录
frame_num = 0 # 帧数
ows_version = 'OpenCV Webcam Script v0.2' # 版本号
while(1):
wait_key = cv2.waitKey(20) & 0xFF # 键盘监听
ret, frame = cap.read() # 捕获画面
frame_num += 1 # 帧计数
print(f'当前帧:第{frame_num}') # 输出信息
cv2.imshow(ows_version, frame) # 显示画面
if (is_autoSaveFrame): # 自动保存
if (frame_num % frame_nSave == 0): # 每隔n帧保存一次
frame_opt(frame, frame_savePath, frame_num, is_resizeFrame, resize_frame, resizeRatio_frame,
frame_namePrefix, frame_saveStyle, jpg_quality, png_quality)
if (is_handSaveFrame): # 手动保存
if wait_key == ord(frame_capKey): # 保存键
frame_opt(frame, frame_savePath, frame_num, is_resizeFrame, resize_frame, resizeRatio_frame,
frame_namePrefix, frame_saveStyle, jpg_quality, png_quality)
if wait_key == ord(quit_key): # 退出 ord字符转ASCII码
break
if wait_key == ord(pause_key):
print(f'已暂停!按任意键继续。。。')
cv2.waitKey(0) # 暂停,按任意键继续
print(f'一共处理了{frame_num}')
# 释放缓存
cap.release()
cv2.destroyAllWindows()
else: # 连接设备失败
print(f'摄像头连接异常!')
print(f'程序结束!')
e_time = time.time() # 终止时间
print(f'用时:{round((e_time - s_time), 3)}秒, {round((e_time - s_time)/60, 3)}分, {round((e_time - s_time)/3600, 3)}小时')
def main(args):
device_index = args.device
quit_key = args.quit
is_autoSaveFrame = args.is_autoSaveFrame
is_handSaveFrame = args.is_handSaveFrame
frame_saveDir = args.frame_saveDir
frame_nSave = args.frame_nSave
frame_capKey = args.frame_capKey
resize_frame = args.resize_frame
is_resizeFrame = args.is_resizeFrame
resizeRatio_frame = args.resizeRatio_frame
frame_namePrefix = args.frame_namePrefix
frame_saveStyle = args.frame_saveStyle
jpg_quality = args.jpg_quality
png_quality = args.png_quality
pause_key = args.pause
# 调用webcam opencv
webcam_opencv(device_index, quit_key, pause_key, is_autoSaveFrame, frame_saveDir, frame_nSave,
is_handSaveFrame, frame_capKey, is_resizeFrame, resize_frame, resizeRatio_frame,
frame_namePrefix, frame_saveStyle, jpg_quality, png_quality)
if __name__ == '__main__':
args = parse_args()
main(args)