视频供稿中的Pi Camera黑条

时间:2019-03-09 06:38:01

标签: python python-3.x tkinter raspberry-pi3 cv2

我目前正在Raspberry Pi 3上使用Thonny运行此代码。此应用程序将Pi Camera帧的实时提要放到Tkinter Canvas上。然后,用户可以单击“捕获”按钮以捕获并存储框架。 “触摸充电”和“触摸检索”按钮只是在使cancas可见/不可见之间切换。它的功能远不止于此,但就目前而言,我想知道的是为什么这些黑条会显示在供稿上。 谢谢!

GUI layout without video feed canvas visible

GUI layout with video feed canvas and black bars

another picture of the black bars

到目前为止,这是我的代码

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")

0 个答案:

没有答案