平均后图像全部为灰色

时间:2017-11-09 16:16:50

标签: python opencv image-processing

import cv2

redArry = []
greenArry = []
blueArry = []


def chunk(n, lst):
    n = min(n, len(lst) - 1)
    return [lst[i:i + n] for i in range(len(lst) - n + 1)]


def average(group):
chunkCtrl = 0

for im in group:
    B = im[:, :, 0]
    G = im[:, :, 1]
    R = im[:, :, 2]

    redArry.append(R)
    greenArry.append(G)
    blueArry.append(B)
    chunkCtrl +=1

    if chunkCtrl == 2 :
        for x in range(im.shape[0]):
            for y in range(im.shape[1]):
                chunkCtrl = 0
                sumRed = 0
                sumGreen = 0
                sumBlue = 0

                for i in range(2):
                    redImage = redArry[i]
                    sumRed += redImage[x, y]
                    print redImage

                    greenImage = greenArry[i]
                    sumGreen += greenImage[x, y]
                    print greenImage

                    blueImage = blueArry[i]
                    sumBlue += blueImage[x, y]
                    print blueImage

                    sumRed = sumRed / 2.0
                    sumGreen = sumGreen / 2.0
                    sumBlue = sumBlue / 2.0

                image = cv2.merge((sumRed , sumGreen , sumBlue))
                return image






arrayOfFrames = []

cap = cv2.VideoCapture('myVideo.mp4')
while (cap.isOpened()):
    ret, frame = cap.read()
    if ret == True:
        arrayOfFrames.append(frame)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
        elif cv2.waitKey(1) & 0xFF == ord('p'):
            cv2.waitKey(0)
    else:
        break

cap.release()
cv2.destroyAllWindows()


groupedFrames = chunk(2 , arrayOfFrames)

for group in groupedFrames:    
    averagedImage = average(group)    
    cv2.imshow("Result" , averagedImage)
    cv2.waitKey(0)

我正在尝试使用开放的CV和python来平均视频。 我的想法是我将第1帧和第2帧平均并返回新图像。

算法解释 将电影分割成帧数组。 将该数组划分为重叠的块。 对于块中的每个图像 将图像分成3个通道 得到每个频道的总和 使用平均总和制作新图像 显示图像

2 个答案:

答案 0 :(得分:3)

这是您的平均(组)功能,重写:

def average(group):
    chunkCtrl = 0
    new_image = np.zeros(np.shape(group[0]))

    for im in group:
        chunkCtrl += 1
        B = im[:, :, 0]
        G = im[:, :, 1]
        R = im[:, :, 2]

        for x in range(im.shape[0]):
            for y in range(im.shape[1]):
                new_image[x,y,0] += B[x,y]
                new_image[x,y,1] += G[x,y]
                new_image[x,y,2] += R[x,y]

                if chunkCtrl == 2:
                    new_image[x,y,0] = new_image[x,y,0]/2.0
                    new_image[x,y,1] = new_image[x,y,1]/2.0
                    new_image[x,y,2] = new_image[x,y,2]/2.0

        # this is not necessary if your chunks are always 2 images, which they seem to be
        if chunkCtrl == 2:
            return new_image

    return new_image

我无法解释您的代码出了什么问题,因为我不确定问题中的缩进是否反映了您的实际代码,但有些事情要指出:

  • redArry,blueArry和greenArry在他们不需要的时候被宣布为全球性的。在每次调用开始时将它们初始化为空(平均(组)以避免错误。
  • 从问题中的缩进开始,您似乎在实际遍历整个图像数组之前返回合并的图像。
  • 注意sumRed,sumBlue和sumGreen如何在每个像素处初始化为0(在x ...的两个循环内,以及y ...)。由于您在转到下一个图像之前循环遍历图像的各个像素,因此您永远不会实际总结每个图像的像素。

我建议您使用函数范围作为一种方法来了解变量应该初始化的位置,可以更新的位置以及不应该使用的位置。这可以为您节省大量的调试时间!

编辑:OpenCV非常棒,有许多有用的图像处理工具。一个好的就是:Image Blending

答案 1 :(得分:2)

通过手动迭代Python中的所有元素来执行每个元素的添加或分割numpy数组是一个可怕的悲观

利用numpy提供的vectorized arithmetic operations,我们可以通过@ ma22从以下方式重写函数:

def average_fast(group):
    if len(group) == 1:
        return np.float64(group[0])

    new_image = np.zeros(np.shape(group[0]))

    for im in group[:2]:
        new_image += im

    return new_image / 2.0

相同的结果,约60%的代码(维护更少,恕我直言更容易理解它的作用)。不仅如此 - 在一组1024x1024 RGB图像上测量两种方法,我们可以看到这种方法快了近200倍(25毫秒,而差不多5秒)。