【发布时间】:2015-11-21 14:13:39
【问题描述】:
我是相当缺乏经验的 Python 用户 (v2.7.8),我正在尝试编写一个 GUI,它以 640x480 的低分辨率显示来自 USB 相机的图像,但单击按钮时仍会以最高分辨率记录2592x1944。 GUI 是用 Tkinter 编写的。我的 Tkinter 程序使用 Multiprocessing 和 Queue 从相机中获取一帧,将其存储在队列中并在对象窗口中显示该帧。作为原理证明,我已经让程序在带有 PiCamera 的 Raspberry Pi 上运行,但现在我需要将系统移动到带有这个 USB 设备 (https://www.leopardimaging.com/uploads/LI-OV5640-USB-72_datasheet.pdf) 的 PC 上。我曾尝试使用 OpenCV2 移植代码来控制摄像头,但一旦我尝试更改摄像头的分辨率,程序就会挂起,没有出现任何错误消息。
我可以在 Python shell 中编写类似的代码并让它工作,尽管我显示较小实时提要的方法很笨拙:
import numpy as np
from multiprocessing import Process, Queue
from Queue import Empty
import cv2
from PIL import Image, ImageTk
import time
feed_queue = Queue(maxsize=2**4)
live_feed = cv2.VideoCapture(1)
live_feed.set(3,2592)
live_feed.set(4,1944)
live_feed.set(5,15)
while True:
ret, img = live_feed.read()
preview_size = (640,480)
preview_frame = cv2.resize(img, preview_size, interpolation=cv2.INTER_AREA)
cv2.imshow("input", preview_frame)
key = cv2.waitKey(10)
if key == 27:
cv2.imwrite("output.jpg",img)
break
但是,一旦我为在 Tkinter 中工作而写了类似的东西,一切都崩溃了:
def image_capture(feed_queue):
live_feed = cv2.VideoCapture(1)
live_feed.set(3,2592)
live_feed.set(4,1944)
live_feed.set(5,15)
while True:
try:
flag, frame = live_feed.read()
if flag == 0:
break
feed_queue.put(frame)
cv2.waitKey(10)
except:
live_feed.release()
continue
def update_image(image_label, feed_queue):
frame = feed_queue.get()
preview_size = (640,480)
preview_frame = cv2.resize(frame, preview_size, interpolation = cv2.INTER_AREA)
# Convert the colour space information from CV2's BGR to the more standard RGB for use with the Tkinter widgets using Python Image Library built in functions
im = cv2.cvtColor(preview_frame, cv2.COLOR_BGR2RGB)
# Create a reference copy of the original image so that it isn't designated as garbage by Python's memory allocator
a = Image.fromarray(im)
# Now convert this duplicate image to the format required by Tkinter and assign it to the Tkinter label widget, named image_label
b = ImageTk.PhotoImage(image=a)
image_label.configure(image=b)
image_label._image_cache = b
# Update the main window with this new image
root.update()
def update_all(root, image_label, feed_queue):
update_image(image_label, feed_queue)
root.after(0, func=lambda: update_all(root, image_label, feed_queue))
if __name__ == '__main__':
feed_queue = Queue(maxsize=2**4)
p = Process(target=image_capture, args=(feed_queue,))
p.start()
# setup the update callback
root.after(0, func=lambda: update_all(root, image_label, feed_queue))
print 'root.after was called...'
root.mainloop()
print 'mainloop exit'
p.join()
这可能不是最有效的方法,因此我将不胜感激任何关于更好方法或使该程序运行的方法的建议。
谢谢大家!
注意: 我可能已经隔离了将图像放入队列的问题。我在 shell 代码中写了一些命令,然后它就崩溃了
import numpy as np
from multiprocessing import Process, Queue
from Queue import Empty
import cv2
global live_feed
live_feed = cv2.VideoCapture(1)
live_feed.set(3,2592
live_feed.set(4,1944)
live_feed.set(5,15)
def takeapicture():
global live_feed
flag, frame = live_feed.read()
return flag, frame
def makeaq(feed_q):
global live_feed
flag, frame = live_feed.read()
feed_q.put(frame)
feed_q = Queue(maxsize = 2**4)
issue, img = takeapicture()
issue, img.shape
>(True, (1944L, 2592L, 3L))
pin = feed_q.get()
然后崩溃!
【问题讨论】:
-
为什么要用opencv来控制摄像头?
-
主要是因为它是我熟悉的。如果它可以满足我的主要标准,我非常乐意尝试其他方法 - 以一种尺寸显示实时图像,在出现提示时记录静止图像。
-
请在此处查看我的新请求:stackoverflow.com/questions/32271964/…
标签: python windows opencv video camera