我目前正在Raspberry Pi 3上使用Thonny运行此代码。此应用程序将Pi Camera帧的实时提要放到Tkinter Canvas上。然后,用户可以单击“捕获”按钮以捕获并存储框架。 “触摸充电”和“触摸检索”按钮只是在使cancas可见/不可见之间切换。它的功能远不止于此,但就目前而言,我想知道的是为什么这些黑条会显示在供稿上。 谢谢!
到目前为止,这是我的代码
import tkinter
import cv2
import PIL.Image, PIL.ImageTk
import time
state = 0 # state of canvas
inUse = 0 # make inUse = 1 at the end
class App:
global state
global inUse
def __init__(self, window, window_title, video_source=0):
self.window = window
self.window.title(window_title)
self.video_source = video_source
# open video source (by default this will try to open the computer webcam)
self.vid = MyVideoCapture(self.video_source)
# Create a canvas that can fit the above video source size
# self.canvas = tkinter.Canvas(window, width = self.vid.width, height = self.vid.height)
self.canvas = tkinter.Canvas(window, width=2000, height=2000)
# Button that lets the user take a snapshot
self.btn_snapshot=tkinter.Button(window, text="Snapshot", width=35, command=self.snapshot)
self.btn_state=tkinter.Button(window, text="Enable/Disable", width=35, command=self.closeWindow)
# use lambda with command if you need to use anything
self.chargeBT=tkinter.Button(window, text="Touch to Charge", width=25, height=3, command=self.chargeAction)
self.retrieveBT=tkinter.Button(window, text="Touch to Retrieve", width=25, height=3, command=self.chargeAction)
self.btn_snapshot.pack(anchor=tkinter.W)
self.btn_state.pack(anchor=tkinter.W)
self.chargeBT.place(relx=0.4, rely=0.8)
self.retrieveBT.place(relx=0.7, rely=0.8)
self.canvas.pack(anchor=tkinter.CENTER)
self.canvas.pack_forget()
# After it is called once, the update method will be automatically called every delay milliseconds
self.delay = 15
self.update()
self.window.geometry("800x480")
self.window.mainloop()
def snapshot(self):
# Get a frame from the video source
ret, frame = self.vid.get_frame()
if ret:
cv2.imwrite("frame-" + time.strftime("%d-%m-%Y-%H-%M-%S") + ".jpg", cv2.cvtColor(frame, cv2.COLOR_RGB2BGR))
def closeWindow(self):
global state
if state == 0:
self.canvas.pack()
state = 1
else:
self.canvas.pack_forget()
state = 0
#self.window.destroy()
def update(self):
# Get a frame from the video source
ret, frame = self.vid.get_frame()
if ret:
frame = cv2.flip(frame,1)
self.photo = PIL.ImageTk.PhotoImage(image = PIL.Image.fromarray(frame))
self.canvas.create_image(0, 0, image = self.photo, anchor = tkinter.NW)
self.window.after(self.delay, self.update)
def chargeAction(self):
global inUse
if inUse == 0:
print("Im in!!!")
self.btn_state.configure(text="YOYOYO")
self.canvas.pack(anchor=tkinter.CENTER)
inUse = 1
else:
print("Sorry this locker is in use")
self.canvas.pack_forget()
inUse = 0
class MyVideoCapture:
def __init__(self, video_source=0):
# Open the video source
self.vid = cv2.VideoCapture(video_source)
rval, frame = self.vid.read()
self.vid.set(3, 200)
self.vid.set(4, 200)
""" change resolution
cap.set(3,1280)
cap.set(4,1024)
"""
if not self.vid.isOpened():
raise ValueError("Unable to open video source", video_source)
# Get video source width and height
self.width = self.vid.get(cv2.CAP_PROP_FRAME_WIDTH)
self.height = self.vid.get(cv2.CAP_PROP_FRAME_HEIGHT)
def get_frame(self):
if self.vid.isOpened():
ret, frame = self.vid.read()
if ret:
# Return a boolean success flag and the current frame converted to BGR
return (ret, cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
else:
return (ret, None)
else:
return (ret, None)
# Release the video source when the object is destroyed
def __del__(self):
if self.vid.isOpened():
self.vid.release()
# Create a window and pass it to the Application object
App(tkinter.Tk(), "Tkinter and OpenCV")