Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit b69f818

Browse files
committed
Displaying a video feed with OpenCV and Tkinter
1 parent a3d761d commit b69f818

File tree

2 files changed

+141
-0
lines changed

2 files changed

+141
-0
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# -*- coding: utf-8 -*-
2+
# @Time : 2018年2月8日 16:09
3+
# @Author : play4fun
4+
# @File : Displaying a video feed with OpenCV and Tkinter.py
5+
# @Software: PyCharm
6+
7+
"""
8+
Displaying a video feed with OpenCV and Tkinter.py:
9+
https://www.pyimagesearch.com/2016/05/30/displaying-a-video-feed-with-opencv-and-tkinter/
10+
11+
"""
12+
13+
# import the necessary packages
14+
from __future__ import print_function
15+
from photoboothapp import PhotoBoothApp
16+
from imutils.video import VideoStream
17+
import argparse
18+
import time
19+
20+
# construct the argument parse and parse the arguments
21+
ap = argparse.ArgumentParser()
22+
ap.add_argument("-o", "--output", required=True,
23+
help="path to output directory to store snapshots")
24+
ap.add_argument("-p", "--picamera", type=int, default=-1,
25+
help="whether or not the Raspberry Pi camera should be used")
26+
args = vars(ap.parse_args())
27+
28+
# initialize the video stream and allow the camera sensor to warmup
29+
print("[INFO] warming up camera...")
30+
vs = VideoStream(usePiCamera=args["picamera"] > 0).start()
31+
time.sleep(2.0)
32+
33+
# start the app
34+
pba = PhotoBoothApp(vs, args["output"])
35+
pba.root.mainloop()

‎cv-Tkinter-GUI/photoboothapp.py‎

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
# -*- coding: utf-8 -*-
2+
# @Time : 2018年2月8日 16:10
3+
# @Author : play4fun
4+
# @File : photoboothapp.py
5+
# @Software: PyCharm
6+
7+
"""
8+
photoboothapp.py:
9+
"""
10+
11+
# import the necessary packages
12+
from __future__ import print_function
13+
from PIL import Image
14+
from PIL import ImageTk
15+
import tkinter as tki
16+
import threading
17+
import datetime
18+
import imutils
19+
import cv2
20+
import os
21+
22+
23+
class PhotoBoothApp:
24+
def __init__(self, vs, outputPath):
25+
# store the video stream object and output path, then initialize
26+
# the most recently read frame, thread for reading frames, and
27+
# the thread stop event
28+
self.vs = vs
29+
self.outputPath = outputPath
30+
self.frame = None
31+
self.thread = None
32+
self.stopEvent = None
33+
34+
# initialize the root window and image panel
35+
self.root = tki.Tk()
36+
self.panel = None
37+
38+
# create a button, that when pressed, will take the current
39+
# frame and save it to file
40+
btn = tki.Button(self.root, text="Snapshot!",
41+
command=self.takeSnapshot)
42+
btn.pack(side="bottom", fill="both", expand="yes", padx=10,
43+
pady=10)
44+
45+
# start a thread that constantly pools the video sensor for
46+
# the most recently read frame
47+
self.stopEvent = threading.Event()
48+
self.thread = threading.Thread(target=self.videoLoop, args=())
49+
self.thread.start()
50+
51+
# set a callback to handle when the window is closed
52+
self.root.wm_title("PyImageSearch PhotoBooth")
53+
self.root.wm_protocol("WM_DELETE_WINDOW", self.onClose)
54+
55+
def videoLoop(self):
56+
# DISCLAIMER:
57+
# I'm not a GUI developer, nor do I even pretend to be. This
58+
# try/except statement is a pretty ugly hack to get around
59+
# a RunTime error that throws due to threading
60+
try:
61+
# keep looping over frames until we are instructed to stop
62+
while not self.stopEvent.is_set():
63+
# grab the frame from the video stream and resize it to
64+
# have a maximum width of 300 pixels
65+
self.frame = self.vs.read()
66+
self.frame = imutils.resize(self.frame, width=300)
67+
68+
# represents images in BGR order; however PIL
69+
# represents images in RGB order, so we need to swap
70+
# the channels, then convert to PIL and ImageTk format
71+
image = cv2.cvtColor(self.frame, cv2.COLOR_BGR2RGB)
72+
image = Image.fromarray(image)
73+
image = ImageTk.PhotoImage(image)
74+
75+
# if the panel is not None, we need to initialize it
76+
if self.panel is None:
77+
self.panel = tki.Label(image=image)
78+
self.panel.image = image
79+
self.panel.pack(side="left", padx=10, pady=10)
80+
81+
# otherwise, simply update the panel
82+
else:
83+
self.panel.configure(image=image)
84+
self.panel.image = image
85+
86+
except RuntimeError as e:
87+
print("[INFO] caught a RuntimeError")
88+
89+
def takeSnapshot(self):
90+
# grab the current timestamp and use it to construct the
91+
# output path
92+
ts = datetime.datetime.now()
93+
filename = "{}.jpg".format(ts.strftime("%Y-%m-%d_%H-%M-%S"))
94+
p = os.path.sep.join((self.outputPath, filename))
95+
96+
# save the file
97+
cv2.imwrite(p, self.frame.copy())
98+
print("[INFO] saved {}".format(filename))
99+
100+
def onClose(self):
101+
# set the stop event, cleanup the camera, and allow the rest of
102+
# the quit process to continue
103+
print("[INFO] closing...")
104+
self.stopEvent.set()
105+
self.vs.stop()
106+
self.root.quit()

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /