python - 存储灰度视频的像素值,对它们进行平均,然后显示生成的视频
问题描述
`n = 3 数组 = np.ones((n,n)) / (n*n) n = array.shape[0] * array.shape 1
while(True): ret, frame = cap.read()
if ret is True:
print("newframe")
gframe = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
dst = cv2.copyMakeBorder(gframe, 1, 1, 1, 1, borderType, None, None)
blur = cv2.blur(dst,(3,3))
if k == 1 :
lastframe = gframe
curframe = gframe
nextframe = gframe
newFrame = gframe
k = 0
else :
lf = ndimage.convolve(lastframe, array, mode='constant', cval= 0.0)
cf = ndimage.convolve(curframe, array, mode='constant', cval= 0.0)
nf = ndimage.convolve(nextframe, array, mode='constant', cval= 0.0)
lastframe = curframe
curframe = nextframe
nextframe = gframe
b = np.zeros((3, 528, 720))
b[0] = lf
b[1] = cf
b[2] = nf
result = np.mean(b, axis=0)
cv2.imshow('frame',result)
cv2.imshow('frame2',gframe)
我正在尝试添加 3x3 像素的所有像素值,然后对它们进行平均。我需要对每个像素和每一帧都这样做,并用平均像素替换主像素。但是,我尝试这样做的方式使其非常缓慢且不准确。
解决方案
这听起来像一个卷积。
import numpy as np
from scipy import ndimage
a = np.random.random((5, 5))
一个
[[0.14742615 0.83548453 0.67433445 0.59162829 0.21160044]
[0.1700598 0.89074466 0.84155171 0.65092969 0.3842437 ]
[0.22662423 0.2266929 0.47757456 0.34480112 0.06261333]
[0.89402116 0.00101947 0.90503461 0.93112109 0.44817247]
[0.21788789 0.3338606 0.07323461 0.28944439 0.91217591]]
窗口大小为 3x3 的卷积操作
n = 3
k = np.ones((n, n)) / (n * n)
n = k.shape[0] * k.shape[1]
b = ndimage.convolve(a, k, mode='constant', cval=0.0)
b
[[0.22707946 0.39551126 0.49829704 0.3726987 0.2042669 ]
[0.27744803 0.49894366 0.61486021 0.47103081 0.24953517]
[0.26768469 0.51481368 0.58549664 0.56067136 0.31354238]
[0.21112292 0.37288334 0.39808704 0.4937969 0.33203648]
[0.16075435 0.26945093 0.28152386 0.39546479 0.28676821]]
现在您只需为当前帧和前两个帧执行此操作。
-------- 编辑:三帧------------
对于 3D,您可以像本文中那样编写卷积函数,但它使用 FFT 非常复杂
如果您只想在三帧之间进行平均,您可以这样做:
f1 = np.random.random((5, 5)) # Frame1
f2 = np.random.random((5, 5)) # Frame2
f3 = np.random.random((5, 5)) # Frame3
n = 3
k = np.ones((n, n)) / (n * n)
n = k.shape[0] * k.shape[1]
b0 = ndimage.convolve(f1, k, mode='constant', cval=0.0)
b1 = ndimage.convolve(f2, k, mode='constant', cval=0.0)
b2 = ndimage.convolve(f3, k, mode='constant', cval=0.0)
# Create a 3D Matrix, with each fame placed along the first dimension
b = np.zeros((3, 5, 5))
b[0] = b0
b[1] = b1
b[2] = b2
# Take the average across the first dimension (across frames)
result = np.mean(b, axis=0)
可能有比这更优雅的解决方案,但它可以完成工作。
-------- 编辑:电影 ------------
基于评论中的所有问题,我决定尝试添加更多代码来帮助实现。
首先,我从一部电影中的这 7 张连续剧照开始:
我尚未验证以下代码是否可以证明错误或实际上返回了正确的结果。
import cv2
import numpy as np
from scipy import ndimage
# this is a function to do previous code
def mean_frames(frames, kernel):
b = np.zeros(frames.shape)
for i in range(frames.shape[0]):
b[i] = ndimage.convolve(frames[i], k, mode='constant', cval=0.0)
b = np.mean(b, axis=0) / frames.shape[0]
return b
mean_N = 3 # frames to average
# read in 1 file to get dimenions
im = cv2.imread(f'{root}1.png', cv2.IMREAD_GRAYSCALE)
# setup numpy matrix that will hold mean_N frames at a time
frames = np.zeros((mean_N, im.shape[0], im.shape[1]))
avg_frames = [] # list to store our 3 averaged frames
count = 0 # counter to position frames in 1st dim of 3D matrix for avg
k = np.ones((3, 3)) / (3 * 3) # kernel for 2D convolution
for j in range(1, 7): # 7 images
file_name = root + str(j) + '.png'
im = cv2.imread(file_name, cv2.IMREAD_GRAYSCALE)
frames[count, ::] = im # store in 3D matrix
# if loaded more than min req. for avg, we average
if j >= mean_N:
# average and store to list
avg_frames.append(mean_frames(frames, k))
# if the count is mean_N - 1, that means we need to replace
# the 0th matrix in frames so that we are doing a 'moving avg'
if count == (mean_N - 1):
count = 0
else:
count += 1 #increase position in 0th dim for 3D matrix storage
# ouput averaged frames
for i, f in enumerate(avg_frames):
cv2.imwrite(f'{path}output{i}.jpg', f)
然后查看文件夹,有 5 个文件(如果我们对 7 个静止图像进行 3 帧的移动平均,则符合预期:
看之前和之后:
图 3:
和平均图像#1:
图像不仅是灰度的(如预期的那样),而且看起来很暗。也许一些增亮会使事情看起来更好/更明显。
推荐阅读
- excel - 初始化表单时选择 ComboBox 的默认值
- python - 如何使用 Python 读取 Metastock 数据
- python - discord.ext.commands.errors.MissingRequiredArgument:扩展是缺少的必需参数
- debugging - 传递额外的编译标志来调试 bitbake 配方中的构建
- javascript - 将 Puppeteer 与 Electron 一起使用会引发“找不到浏览器修订版”错误。使用节点运行良好
- emeditor - EmEditor 在空行上的缩进行为
- azure - 如何在 Azure 数据工厂中使用二进制列加入?
- javascript - 从控制台搜索值 (Firefox)
- docker - Docker 卷未安装在容器中
- laravel - 在 Laravel 中验证日期