Python函数式编程,范围和变量。我哪里错了?

问题描述 投票:-2回答:1

我正在从图形项目选择中组装一个类函数列表,在链的末尾,我将函数列表传递给循环进行处理。一切都很好。除了循环似乎没有累积,但只适用于应用的最后一个类函数。我认为这是由于范围,但是想知道一些经验丰富的大师能否指出我正确的方向。

这是一个没有循环的代码片段,按预期工作。为清晰起见,只有两个功能:

frame=cv2.GaussianBlur(frame,(15,15),0) and frame=cv2.flip(frame, 1)

该功能使用self.capture()frame = cv2.cvtColor()设置来自视频卡或摄像机的输入视频流,以提供可单独处理的单个帧对象,在这种情况下,帧使用openCV(cv2)类函数进行模糊和翻转。如预期的那样,很好。

def display_video_stream(self):
    self.capture = cv2.VideoCapture(0)
    frame = self.capture.read()
    frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

    #want to replace these class functions with function list
    frame = cv2.GaussianBlur(frame,(15,15),0)
    frame = cv2.flip(frame, 1)

    image = QImage(frame, frame.shape[1], frame.shape[0], 
                       frame.strides[0], QImage.Format_RGB888)
    self.image_label.setPixmap(QPixmap.fromImage(image))

所以,现在我用一个在for循环中处理的列表替换这两个函数,如下所示。但是,当我这样做时,我得不到相同的结果。它只是应用的函数列表中的最后一个操作。因此,根据列表的顺序,我会被模糊或翻转,而不是模糊然后翻转。我检查循环是否使用print语句循环,这很好,索引号在控制台中循环,因为视频源流,所以它正在处理函数OK但是第一个例子通过传递结果累积帧输出第一个操作作为第二个操作的新源值,循环版本没有。

我认为这是循环中的范围。所以我在哪里指定帧值为:

frame = self.capture.read()

在进入循环之前,似乎循环内部总是保持帧的初始值而不是沿着函数列表累积它,同时处理,或者只是在循环内每次写入帧值。我不明白!在我看来,这两个片段在操作上应该是相同的。那么我如何处理这里的范围,如果它确实是一个范围问题。我很难过。

def display_video_stream(self):
    self.capture = cv2.VideoCapture(0)
    frame = self.capture.read()
    frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

    #this loop works but seems to only return last frame function, not  accumulate. As if loop overwrites frame each time.
    #with original value or perhaps is out of scope and reverts to self.setup_frame() value eachtime?
    #whichever is last function in list, that is the result returned in output but not both.

    functions = [cv2.GaussianBlur(frame,(15,15),0), cv2.flip(frame, 1)]
    indexval = 0
    for i in range(len(functions)):
        frame = functions[indexval]
        indexval += 1

    image = QImage(frame, frame.shape[1], frame.shape[0], 
                       frame.strides[0], QImage.Format_RGB888)
    self.image_label.setPixmap(QPixmap.fromImage(image))
python list loops opencv scope
1个回答
1
投票
  1. 你对read的使用是错误的。
ret, frame = cap.read()

文件:

read(...) method of cv2.VideoCapture instance
    read([, image]) -> retval, image
    .   @brief Grabs, decodes and returns the next video frame.
    .
    .   @param [out] image the video frame is returned here. If no frames has b$
    .   @return `false` if no frames has been grabbed
    .   ....
  1. 你的functions变量不是函数,而是处理过的图像列表。
functions = [
    lambda frame:cv2.GaussianBlur(frame,(15,15),0),
    lambda frame: cv2.flip(frame, 1)
]


for func in functions:
    frame = func(frame)
  1. 也许你改变框架到QImage的方式是不对的,我不太确定。

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.