<p>你能试试这个代码看看你能得到多少FPS吗?我包括了一个FPS的计算,所以我们可以比较笔记。(编辑:还有什么错误。我没有得到你在原始代码中得到的错误,下面的代码也没有错误)</p>
<p>我从头开始只是想看看我是否想出了不同的东西。有几个不同点:</p>
<ol>
<li>有一个(未成年人?)缺陷:opencv的默认颜色通道是BGR而不是
RGB公司。因此,将grascale转换从<code>cv2.COLOR_RGB2GRAY</code>
-->;<code>cv2.COLOR_BGR2GRAY</code>。你可以在<a href="http://docs.opencv.org/modules/highgui/doc/reading_and_writing_images_and_video.html#videocapture" rel="nofollow">VideoCapture example</a>中看到他们做了类似的事情。</li>
<li>我用一个简单的标签来显示图像,而不是画布。我以前没用过帆布,所以我不知道你需要用它做什么。使用一个简单的标签,您必须<a href="http://effbot.org/pyfaq/why-do-my-tkinter-images-not-appear.htm" rel="nofollow">keep a reference to the image you are displaying</a>这样它就不会被垃圾收集。您可以在update_image()中看到。</li>
<li>对于回调,我使用带参数的lambdas(正如您在评论中提到的)。否则,当使用参数进行函数调用时,将立即运行回调,而不是注册回调。结果看起来很管用,但并不像你想的那样。或者,如果希望打包参数并将其作为未调用的函数发送,则可以使用<a href="http://docs.python.org/2/library/functools.html#partial-objects" rel="nofollow">functools.partial</a>。</li>
<li>同样对于回调,我添加了一个try:except块,用于在根目录被破坏后开始运行回调。我不知道这是不是正确的方法,但据我所知是可行的。</li>
</ol>
<p>使用此代码,我可以获得15 FPS,并且在windows 7上没有错误:</p>
<pre><code>from collections import deque
import cv2
import Image, ImageTk
import time
import Tkinter as tk
def quit_(root):
root.destroy()
def update_image(image_label, cam):
(readsuccessful, f) = cam.read()
gray_im = cv2.cvtColor(f, cv2.COLOR_BGR2GRAY)
a = Image.fromarray(gray_im)
b = ImageTk.PhotoImage(image=a)
image_label.configure(image=b)
image_label._image_cache = b # avoid garbage collection
root.update()
def update_fps(fps_label):
frame_times = fps_label._frame_times
frame_times.rotate()
frame_times[0] = time.time()
sum_of_deltas = frame_times[0] - frame_times[-1]
count_of_deltas = len(frame_times) - 1
try:
fps = int(float(count_of_deltas) / sum_of_deltas)
except ZeroDivisionError:
fps = 0
fps_label.configure(text='FPS: {}'.format(fps))
def update_all(root, image_label, cam, fps_label):
update_image(image_label, cam)
update_fps(fps_label)
root.after(20, func=lambda: update_all(root, image_label, cam, fps_label))
if __name__ == '__main__':
root = tk.Tk()
# label for the video frame
image_label = tk.Label(master=root)
image_label.pack()
# camera
cam = cv2.VideoCapture(0)
# label for fps
fps_label = tk.Label(master=root)
fps_label._frame_times = deque([0]*5) # arbitrary 5 frame average FPS
fps_label.pack()
# quit button
quit_button = tk.Button(master=root, text='Quit',
command=lambda: quit_(root))
quit_button.pack()
# setup the update callback
root.after(0, func=lambda: update_all(root, image_label, cam, fps_label))
root.mainloop()
</code></pre>