我有视频文件,我可以转换成RGB空间与cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)为每帧。然后,我想计算红色和蓝色值的平均值和标准差,在100秒内取平均值和标准差。我的视频是> 100秒长,所以会想重复这每100秒,并分配值的向量。因此,对于每第n个100秒剪辑,我有值R(ave),R(sd),B(ave),B(sd)。我是相当新的简历和视频处理,所以会感谢帮助,在任何部分。
cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
qyzbxkaa1#
我终于写出来了。这整个程序将运行足够长的视频超过1分钟长。如果你有一个弱的电脑,那么我不羡慕你。但总的来说它工作得很好。这是:
import cv2 def calc_sd(arr: list, mean_val: float): prev_dis = 0 for k in arr: prev_dis += (k - mean_val) ** 2 dis = prev_dis / len(arr) return dis ** (1 / 2) def calc_mean(arr: list): return sum(arr) / len(arr) # list of your videos here lst_of_videos = ['vid_test.mkv', 'signs.mkv', 'signs_ml.mkv'] lst_of_all_videos_data = [] for i in lst_of_videos: cap = cv2.VideoCapture(i) # list for data every 100 sec # data there will be like: # [['mean_red', 'mean_green', 'mean_blue', 'sd_red', 'sd_green', 'sd_blue'], 'and every 100 sec like this'] lst_of_data = [] lst_of_red = [] lst_of_green = [] lst_of_blue = [] # getting video fps fps = cap.get(cv2.CAP_PROP_FPS) abstract_seconds = 0 # for counting frames print('video: ', i) while True: ret, frame = cap.read() if abstract_seconds >= 100 or not ret: print(' video: ', i, ', 100 secs, ret: ', ret) mean_red = calc_mean(lst_of_red) mean_green = calc_mean(lst_of_green) mean_blue = calc_mean(lst_of_blue) print(' mean counted') sd_red = calc_sd(lst_of_red, mean_red) sd_green = calc_sd(lst_of_green, mean_green) sd_blue = calc_sd(lst_of_blue, mean_blue) print(' sd counted') lst_of_data.append([mean_red, mean_green, mean_blue, sd_red, sd_green, sd_blue]) lst_of_red.clear() lst_of_green.clear() lst_of_blue.clear() print(' arrays cleared') if not ret: break b, g, r = cv2.split(frame) lst_of_red.append(r.sum(axis=0).sum(axis=0) / r.size) lst_of_green.append(g.sum(axis=0).sum(axis=0) / g.size) lst_of_blue.append(b.sum(axis=0).sum(axis=0) / b.size) abstract_seconds += 1 / fps print(lst_of_data) lst_of_all_videos_data.append(lst_of_data) lst_of_data.clear()
字符串
eivgtgni2#
我将使用类似下面的代码来计算1小时视频的全局统计数据。我直接在stackoverflow框中修改了它,以满足您的“时间窗口”要求,所以它可能会有一些小错误。我放弃了最后一段,因为你说你想要100秒的窗口,但你可以很容易地适应它,如果你真的需要它。我保留了BGR格式,因为它和其他格式一样好。我喜欢这个选项比另一个答案,因为你不是保持了很多列表和平均值和标准计算是为3个通道一次完成。另一个要点是开放视频的发布。
from docopt import docopt from contextlib import contextmanager import cv2 import numpy as np import sys @contextmanager def VideoCapture(input_video): # findFileOrKeep allows more searching paths capture = cv2.VideoCapture(cv2.samples.findFileOrKeep(input_video)) if not capture.isOpened(): print('Unable to open: ' + input_video, file=sys.stderr) exit(0) try: yield capture finally: # Release the video capture object at the end capture.release() DOCTEXT = f""" Usage: name_of_the_script.py <video_path>... [--windows=<w>] Options: --windows=<w> Windows seconds [default: 100] """ if __name__ == '__main__': args = docopt(DOCTEXT, argv=sys.argv[1:], help=True, version=None, options_first=False) video_pathes = args['<video_path>'] windows = float(args['--windows']) output = [] for i_video, video_path in enumerate(video_pathes): with VideoCapture(video_path) as cap: fps = cap.get(cv2.CAP_PROP_FPS) i = 0 psum = np.array([0.0, 0.0, 0.0]) # BGR psum_sq = np.array([0.0, 0.0, 0.0]) # BGR num_px = windows * fps * int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) * cap.get(cv2.CAP_PROP_FRAME_HEIGHT) while True: ret, frame = cap.read() if not ret: # frame is None break fr += 1 if fr % int(windows * fps) == 0: print(f'Processed {fr / fps}s\tVideo {i_video} / len(video_pathes)\t{video_path}') total_mean = psum / num_px total_var = (psum_sq / num_px) - (total_mean ** 2) total_std = np.sqrt(total_var) output.append([total_mean, total_std]) psum = np.array([0.0, 0.0, 0.0]) # BGR psum_sq = np.array([0.0, 0.0, 0.0]) # BGR psum = frame.sum(axis=(0, 1)) psum_sq = (frame ** 2).sum(axis=(0, 1)) print(f'[mean (BGR), std (BGR)]:\n{output}') # NOTE: or use it as you want. You should make it as a function if you need it to do another thing.
2条答案
按热度按时间qyzbxkaa1#
我终于写出来了。这整个程序将运行足够长的视频超过1分钟长。如果你有一个弱的电脑,那么我不羡慕你。但总的来说它工作得很好。这是:
字符串
eivgtgni2#
我将使用类似下面的代码来计算1小时视频的全局统计数据。
我直接在stackoverflow框中修改了它,以满足您的“时间窗口”要求,所以它可能会有一些小错误。我放弃了最后一段,因为你说你想要100秒的窗口,但你可以很容易地适应它,如果你真的需要它。
我保留了BGR格式,因为它和其他格式一样好。
我喜欢这个选项比另一个答案,因为你不是保持了很多列表和平均值和标准计算是为3个通道一次完成。
另一个要点是开放视频的发布。
字符串