我正在尝试从左上角的一帧速率的视频中获取时间戳。 我只能得到日期,不能得到整个时间戳。帮我获取整个时间戳 我正在共享一个在预处理视频后得到的窗口。
我本来希望获得整个时间戳,但我无法做到。 我想要一个 json 文件中的整个时间戳,例如“2024-03-29 16:36:20”,并且每个帧都会发生变化 像例如。 帧 1 - “2024-03-29 16:36:20” 帧 54 - “2024-03-29 16:36:21” 帧 140 - “2024-03-29 16:36:22” 等等 我的代码 -
import cv2
import pytesseract
import json
import re
pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'
def extract_timestamp(frame):
roi = frame[0:50, 0:550]
gray = cv2.cvtColor(roi, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (5, 5), 0)
gray = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
custom_config = r'--oem 3 --psm 7'
text = pytesseract.image_to_string(gray, config=custom_config)
# cv2.imshow('ROI', gray)
# cv2.waitKey(1)
match = re.search(r'\d{4}-\d{2}-\d{2}', text)
if match:
return match.group(0)
else:
return " "
def process_video(video_path, output_video_path, json_output_path):
cap = cv2.VideoCapture(video_path)
fps = cap.get(cv2.CAP_PROP_FPS)
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter(output_video_path, fourcc, fps, (width, height))
if not cap.isOpened():
print("Error: Could not open video.")
return
frame_count = 0
timestamps = []
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
if frame_count % int(fps) == 0: # One frame per second
timestamp = extract_timestamp(frame)
if timestamp:
print(f"Frame {frame_count}: {timestamp}")
cv2.putText(frame, timestamp, (10, height - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 1,
cv2.LINE_AA)
timestamps.append({'frame': frame_count, 'timestamp': timestamp})
else:
print(f"Frame {frame_count}: No timestamp detected")
out.write(frame)
frame_count += 1
cap.release()
out.release()
with open(json_output_path, 'w') as json_file:
json.dump(timestamps, json_file, indent=4)
video_path = r"C:\Users\Ayush Thakur\Desktop\projects\timestamp\vid.mov"
output_video_path = 'output_annotated_video.mp4'
json_output_path = 'timestamps.json'
process_video(video_path, output_video_path, json_output_path)
你几乎做到了!你面临的挑战是如何在你只有起始日期和帧速率的情况下推断每个帧的确切时间。
由于你能够每秒获取一帧时间戳,下面是如何生成所需 JSON 时间戳的方法:
import cv2
import pytesseract
import json
import re
from datetime import datetime, timedelta
pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'
def extract_timestamp(frame):
roi = frame[0:50, 0:550]
gray = cv2.cvtColor(roi, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (5, 5), 0)
gray = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
custom_config = r'--oem 3 --psm 7'
text = pytesseract.image_to_string(gray, config=custom_config)
match = re.search(r'\d{4}-\d{2}-\d{2}', text)
if match:
return match.group(0)
else:
return " "
def process_video(video_path, output_video_path, json_output_path):
cap = cv2.VideoCapture(video_path)
fps = cap.get(cv2.CAP_PROP_FPS)
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter(output_video_path, fourcc, fps, (width, height))
if not cap.isOpened():
print("错误:无法打开视频。")
return
frame_count = 0
timestamps = []
base_timestamp = None # 存储初始时间戳
while cap.isOpened():
ret, frame = cap.read()
if not ret:
break
if frame_count % int(fps) == 0: # 每秒一帧
timestamp_str = extract_timestamp(frame)
if timestamp_str:
if base_timestamp is None: # 初始化基本时间戳
base_timestamp = datetime.strptime(timestamp_str, "%Y-%m-%d")
base_timestamp = base_timestamp.replace(hour=0, minute=0, second=0) #确保从 00:00:00 开始
timestamp = base_timestamp + timedelta(seconds=frame_count // fps)
timestamp_formatted = timestamp.strftime("%Y-%m-%d %H:%M:%S") # 格式化时间戳
print(f"帧 {frame_count}: {timestamp_formatted}")
cv2.putText(frame, timestamp_formatted, (10, height - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 1, cv2.LINE_AA)
timestamps.append({'frame': frame_count, 'timestamp': timestamp_formatted})
else:
print(f"帧 {frame_count}: 未检测到时间戳")
out.write(frame)
frame_count += 1
cap.release()
out.release()
with open(json_output_path, 'w') as json_file:
json.dump(timestamps, json_file, indent=4)
video_path = r"C:\Users\Ayush Thakur\Desktop\projects\timestamp\vid.mov"
output_video_path = 'output_annotated_video.mp4'
json_output_path = 'timestamps.json'
process_video(video_path, output_video_path, json_output_path)
说明:
-
导入
datetime
和timedelta
: 这些模块用于处理日期和时间计算。 -
base_timestamp
: 此变量存储从提取的日期创建的初始时间戳,初始化为 00:00:00。 - 增量时间戳:
-
对于每个帧,我们通过将总秒数(
frame_count // fps
)添加到base_timestamp
来计算时间戳。 -
timedelta(seconds=frame_count // fps)
创建一个表示当前帧的持续时间的timedelta
对象。 -
然后我们添加这个
timedelta
到base_timestamp
以获得该特定帧的精确时间戳。 -
格式化:
使用
strftime("%Y-%m-%d %H:%M:%S")
将计算出的时间戳格式化为所需的字符串格式。
现在,你的代码应该为每个帧生成准确的时间戳,并将其存储在所需的 JSON 文件中。
如果你的视频跨越多天,此代码假定它是在 24 小时内录制的。 如果不是,则需要添加逻辑来检测日期变化,并在必要时更新
base_timestamp
。