首页 > 解决方案 > 存储灰度视频的像素值,对它们进行平均,然后显示生成的视频

问题描述

`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 像素的所有像素值,然后对它们进行平均。我需要对每个像素和每一帧都这样做,并用平均像素替换主像素。但是,我尝试这样做的方式使其非常缓慢且不准确。

标签: pythonopencv

解决方案


这听起来像一个卷积。

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 张连续剧照开始:

来自矩阵的 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:

原#3

和平均图像#1:

在此处输入图像描述

图像不仅是灰度的(如预期的那样),而且看起来很暗。也许一些增亮会使事情看起来更好/更明显。


推荐阅读