[PYTHON] Display the image of the camera connected to the personal computer on the GUI.

1. What you want to do

The image taken from the camera is displayed on the GUI screen. It also adds the ability to take a snapshot when you press the shutter on the camera.

2. Program contents

  1. Create an instance of the camera with VideoCapture () of OpenCV.
  2. Use Tkinter's Canvas as the screen to display the video (image).
  3. Use OpenCV read () to get the still image (Frame) of the camera.
  4. Display the still image (Frame) of the camera acquired in 3. on Tkinter's Canvas.
  5. Use Python's update () and after () to loop 3-4. (= ** Display the image on Canvas. This is done dozens of times per second, so it looks like a video. **)

3. Design

3.1. Camera instance

Use VideoCapture () to set up a camera instance vcap. video source = 0 Built-in camera video_source = 1 USB camera

At that time, the width and height of the Video image are also acquired.

self.vcap = cv2.VideoCapture( video_source )
self.width = self.vcap.get( cv2.CAP_PROP_FRAME_WIDTH )
self.height = self.vcap.get( cv2.CAP_PROP_FRAME_HEIGHT )

3.2. Tkinter Canvas

Use Tkinter to set up a Canvas instance.

self.canvas1 = tk.Canvas(self.frame_cam)
self.canvas1.configure( width= self.width, height=self.height)
self.canvas1.grid(column= 0, row=0,padx = 10, pady=10)

3.3. Get the still image of the camera with read ()

Use OpenCV read () to get the vcap image. Store the acquired one in frame. Convert what you got with BGR to RGB and store it in frame again.

_, frame = self.vcap.read()
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

3.4. Display the still image of the camera on Tkinter's Canvas.

Once you get the frame, use Pillow to convert it to photo. The reason is that Canvas can only display images processed by Pillow. (Perhaps) Then, the photo is displayed on Canvas.

#OpenCV frame -> Pillow Photo
self.photo = PIL.ImageTk.PhotoImage(image = PIL.Image.fromarray(frame))

#self.photo -> Canvas
self.canvas1.create_image(0,0, image= self.photo, anchor = tk.NW)

3.5. Use Python's update () and after () to loop 3-4.

Set the update cycle with delay. The unit is milliseconds. This time, set it to 15 milliseconds. ** See how the FPS of the video changes when you change the value of this delay. ** ** Insert update () into the main part and after () into the part that displays the image on the Canvas.


self.delay = 15 #[mili seconds]
self.update()

#...............
def update(self):
    #Get a frame from the video source
     _, frame = self.vcap.read()

    frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    self.photo = PIL.ImageTk.PhotoImage(image = PIL.Image.fromarray(frame))

    #self.photo -> Canvas
    self.canvas1.create_image(0,0, image= self.photo, anchor = tk.NW)

    self.master.after(self.delay, self.update)

3.6. Snapshot

The snapshot is processed by converting the frame learned by read () of OpenCV to RGB and then saving it as a file with cv2.imwrite.

    def press_snapshot_button(self):
        # Get a frame from the video source
        _, frame = self.vcap.read()
        frame1 = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

        cv2.imwrite( "frame-" + time.strftime( "%Y-%d-%m-%H-%M-%S" ) + ".jpg ",
                     cv2.cvtColor( frame1, cv2.COLOR_BGR2RGB ) )

4. Execution result

bandicam-2020-08-03-15-00-20-115.gif

5. Summary

  1. The image taken from the camera could be displayed on the GUI screen.
  2. Use OpenCV and Tkinter.
  3. It is important to use Python's update () and after ().

6. Reference materials

1.Python OpenCV - show a video in a Tkinter window 2. [Raspberry Pi] How to display the image of the camera module on Tkinter 3. Load video with Python, OpenCV (file / camera image) 4. Modified version: I made a breakout with tkinter in Python.

7. Program code


import tkinter as tk
from tkinter import ttk
import cv2
import PIL.Image, PIL.ImageTk
from tkinter import font
import time


class Application(tk.Frame):
    def __init__(self,master, video_source=0):
        super().__init__(master)

        self.master.geometry("700x700")
        self.master.title("Tkinter with Video Streaming and Capture")

        # ---------------------------------------------------------
        # Font
        # ---------------------------------------------------------
        self.font_frame = font.Font( family="Meiryo UI", size=15, weight="normal" )
        self.font_btn_big = font.Font( family="Meiryo UI", size=20, weight="bold" )
        self.font_btn_small = font.Font( family="Meiryo UI", size=15, weight="bold" )

        self.font_lbl_bigger = font.Font( family="Meiryo UI", size=45, weight="bold" )
        self.font_lbl_big = font.Font( family="Meiryo UI", size=30, weight="bold" )
        self.font_lbl_middle = font.Font( family="Meiryo UI", size=15, weight="bold" )
        self.font_lbl_small = font.Font( family="Meiryo UI", size=12, weight="normal" )

        # ---------------------------------------------------------
        # Open the video source
        # ---------------------------------------------------------

        self.vcap = cv2.VideoCapture( video_source )
        self.width = self.vcap.get( cv2.CAP_PROP_FRAME_WIDTH )
        self.height = self.vcap.get( cv2.CAP_PROP_FRAME_HEIGHT )

        # ---------------------------------------------------------
        # Widget
        # ---------------------------------------------------------

        self.create_widgets()

        # ---------------------------------------------------------
        # Canvas Update
        # ---------------------------------------------------------

        self.delay = 15 #[mili seconds]
        self.update()


    def create_widgets(self):

        #Frame_Camera
        self.frame_cam = tk.LabelFrame(self.master, text = 'Camera', font=self.font_frame)
        self.frame_cam.place(x = 10, y = 10)
        self.frame_cam.configure(width = self.width+30, height = self.height+50)
        self.frame_cam.grid_propagate(0)

        #Canvas
        self.canvas1 = tk.Canvas(self.frame_cam)
        self.canvas1.configure( width= self.width, height=self.height)
        self.canvas1.grid(column= 0, row=0,padx = 10, pady=10)

        # Frame_Button
        self.frame_btn = tk.LabelFrame( self.master, text='Control', font=self.font_frame )
        self.frame_btn.place( x=10, y=550 )
        self.frame_btn.configure( width=self.width + 30, height=120 )
        self.frame_btn.grid_propagate( 0 )

        #Snapshot Button
        self.btn_snapshot = tk.Button( self.frame_btn, text='Snapshot', font=self.font_btn_big)
        self.btn_snapshot.configure(width = 15, height = 1, command=self.press_snapshot_button)
        self.btn_snapshot.grid(column=0, row=0, padx=30, pady= 10)

        # Close
        self.btn_close = tk.Button( self.frame_btn, text='Close', font=self.font_btn_big )
        self.btn_close.configure( width=15, height=1, command=self.press_close_button )
        self.btn_close.grid( column=1, row=0, padx=20, pady=10 )




    def update(self):
        #Get a frame from the video source
        _, frame = self.vcap.read()

        frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        self.photo = PIL.ImageTk.PhotoImage(image = PIL.Image.fromarray(frame))

        #self.photo -> Canvas
        self.canvas1.create_image(0,0, image= self.photo, anchor = tk.NW)

        self.master.after(self.delay, self.update)

    def press_snapshot_button(self):
        # Get a frame from the video source
        _, frame = self.vcap.read()

        frame1 = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

        cv2.imwrite( "frame-" + time.strftime( "%Y-%d-%m-%H-%M-%S" ) + ".jpg ",
                     cv2.cvtColor( frame1, cv2.COLOR_BGR2RGB ) )

    def press_close_button(self):
        self.master.destroy()
        self.vcap.release()





def main():
    root = tk.Tk()
    app = Application(master=root)#Inherit
    app.mainloop()

if __name__ == "__main__":
    main()


Recommended Posts

Display the image of the camera connected to the personal computer on the GUI.
Display the graph of tensorBoard on jupyter
Mouse over Matplotlib to display the corresponding image
I tried to correct the keystone of the image
ROS Lecture 119 Correct the color of the camera image
I tried to display the infection condition of coronavirus on the heat map of seaborn
Try to measure the position of the object on the desk (real coordinate system) from the camera image with Python + OpenCV
I tried to detect the iris from the camera image
Try to estimate the number of likes on Twitter
Python OpenCV tried to display the image in text.
[Python] Save the result of web scraping the Mercari product page on Google Colab to Google Sheets and display the product image as well.
How to get the current weather data and display it on the GUI while updating it automatically
I tried to find the entropy of the image with python
Make the display of Python module exceptions easier to understand
[Ev3dev] How to display bmp image on LCD with python
The image display function of iTerm is convenient for image processing.
Dot according to the image
Display GUI messages on Ubuntu
Connected components of the graph
[PyQt x pySerial] Display a list of COM ports connected to the PC in the combo box
[Cloudian # 9] Try to display the metadata of the object in Python (boto3)
[Python] Try to graph from the image of Ring Fit [OCR]
I tried to build the SD boot image of LicheePi Nano
Consider the speed of processing to shift the image buffer with numpy.ndarray
[Go] Create a CLI command to change the extension of the image
I tried to display GUI on Mac with X Window System
How to use Jupyter on the front end of supercomputer ITO
A command to easily check the speed of the network on the console
I checked the image of Science University on Twitter with Word2Vec.
How to update the python version of Cloud Shell on GCP
The story of failing to update "calendar.day_abbr" on the admin screen of django
Display the absolute path on the Finder
Supplement to the explanation of vscode
I tried to transform the face image using sparse_image_warp of TensorFlow Addons
[Python] How to specify the window display position and size of matplotlib
I tried to get the batting results of Hachinai using image processing
[EV3 x Python] Stream the camera image to your PC using mjpg-streamer.
Understand how to display images on Jupyter (utilization of imshow / matplotlib of OpenCV)
Try to image the elevation data of the Geographical Survey Institute with Python
I want to display an image on Jupyter Notebook using OpenCV (mac)
Semi-automatically generate a description of the package to be registered on PyPI
[Image recognition] How to read the result of automatic annotation with VoTT
[Android] Display images on the web in the info Window of Google Map
Download all the images attached to the body of the pull request on Github
Hook to Shared Library on Linux to interrupt the behavior of existing binaries
Prepare a URL to display the image uploaded by Active Storage by yourself
Trial to judge the timing of the progress display of the for loop using 0b1111 ~
About the main tasks of image processing (computer vision) and the architecture used
I tried to display the altitude value of DTM in a graph
The story of trying to push SSH_AUTH_SOCK obsolete on screen with LD_PRELOAD
Folding @ Home on Linux Mint to contribute to the analysis of the new coronavirus
GAE --With Python, rotate the image based on the rotation information of EXIF and upload it to Cloud Storage.