www.un.org/Depts/DGACM/index_spanish.htm 与其他许多全球倡议一样,我不想在read子里使用植被,首先,我会试图在主食过程中无一线。
In example I moved most of code to class based on tkinter.Frame
to create widget
which I can use many times with different streams. Because I have only one camera (and system can t use the same camera many times) so I found some external stream/file to test it. Because stream sends very big image so I change size to 400, 300
Code works fast when it doesn t have to resize image.
When it has to resize image then sometimes it has problem but still it is OK.
import tkinter
import cv2
import PIL.Image, PIL.ImageTk
import time
# widgets with canvas and camera
class tkCamera(tkinter.Frame):
def __init__(self, window, video_source=0):
super().__init__(window)
self.window = window
#self.window.title(window_title)
self.video_source = video_source
self.vid = MyVideoCapture(self.video_source)
self.canvas = tkinter.Canvas(window, width=self.vid.width, height=self.vid.height)
self.canvas.pack()
# Button that lets the user take a snapshot
self.btn_snapshot = tkinter.Button(window, text="Snapshot", width=50, command=self.snapshot)
self.btn_snapshot.pack(anchor=tkinter.CENTER, expand=True)
# After it is called once, the update method will be automatically called every delay milliseconds
self.delay = 15
self.update_widget()
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 update_widget(self):
# Get a frame from the video source
ret, frame = self.vid.get_frame()
if ret:
self.image = PIL.Image.fromarray(frame)
self.photo = PIL.ImageTk.PhotoImage(image=self.image)
self.canvas.create_image(0, 0, image = self.photo, anchor = tkinter.NW)
self.window.after(self.delay, self.update_widget)
class App:
def __init__(self, window, window_title, video_source1=0, video_source2=0):
self.window = window
self.window.title(window_title)
# open video source (by default this will try to open the computer webcam)
self.vid1 = tkCamera(window, video_source1)
self.vid1.pack()
self.vid2 = tkCamera(window, video_source2)
self.vid2.pack()
# Create a canvas that can fit the above video source size
self.window.mainloop()
class MyVideoCapture:
def __init__(self, video_source=0):
# Open the video source
self.vid = cv2.VideoCapture(video_source)
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)
self.width = 400
self.height = 300
def get_frame(self):
if self.vid.isOpened():
ret, frame = self.vid.read()
if ret:
frame = cv2.resize(frame, (400, 300))
# 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, https://imageserver.webcamera.pl/rec/krupowki-srodek/latest.mp4 )
如果你计划处理框架——例如。 探测动议或面孔——然后从<条码>中删除。 可以在分离后运行。 校对将处理所有时间范围,并分配给<代码>自上. Framework>和<代码>get_pi(<>/代码>只应交回目前的<代码>。
See similar idea on blog pyImageSearch
in
Increasing webcam FPS with Python and OpenCV.
Probably you could even use
from imutils.video import WebcamVideoStream
http://www.un.org。
仍然没有阅读的版本,但附有来源清单,因此可以显示许多照相机。 但对于更多的来源而言,它存在问题——因此,需要使用<条形码><>>。
<>tkinter 已有办法<代码>更新日期(),因此,我改名为<代码>update_frame(。
缩略语 我使用的是<代码>pilow.image.save(),因此,我不必读到新的框架并改成BGR
,而且我可以在停止流时照搬。 Button
仅停留在信封上的图像上,但不得从深层的溪流中停止阅读,因此其他功能仍然可以处理或记录流。
import tkinter
import cv2
import PIL.Image, PIL.ImageTk
import time
class MyVideoCapture:
def __init__(self, video_source=0, width=None, height=None):
# Open the video source
self.vid = cv2.VideoCapture(video_source)
if not self.vid.isOpened():
raise ValueError("Unable to open video source", video_source)
self.width = width
self.height = height
# Get video source width and height
if not self.width:
self.width = int(self.vid.get(cv2.CAP_PROP_FRAME_WIDTH)) # convert float to int
if not self.height:
self.height = int(self.vid.get(cv2.CAP_PROP_FRAME_HEIGHT)) # convert float to int
self.ret = False
self.frame = None
def process(self):
ret = False
frame = None
if self.vid.isOpened():
ret, frame = self.vid.read()
if ret:
frame = cv2.resize(frame, (self.width, self.height))
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
self.ret = ret
self.frame = frame
def get_frame(self):
self.process() # later run in thread
return self.ret, self.frame
# Release the video source when the object is destroyed
def __del__(self):
if self.vid.isOpened():
self.vid.release()
class tkCamera(tkinter.Frame):
def __init__(self, window, video_source=0, width=None, height=None):
super().__init__(window)
self.window = window
#self.window.title(window_title)
self.video_source = video_source
self.vid = MyVideoCapture(self.video_source, width, height)
self.canvas = tkinter.Canvas(window, width=self.vid.width, height=self.vid.height)
self.canvas.pack()
# Button that lets the user take a snapshot
self.btn_snapshot = tkinter.Button(window, text="Snapshot", width=50, command=self.snapshot)
self.btn_snapshot.pack(anchor= center , expand=True)
# After it is called once, the update method will be automatically called every delay milliseconds
self.delay = 15
self.update_widget()
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 update_widget(self):
# Get a frame from the video source
ret, frame = self.vid.get_frame()
if ret:
self.image = PIL.Image.fromarray(frame)
self.photo = PIL.ImageTk.PhotoImage(image=self.image)
self.canvas.create_image(0, 0, image = self.photo, anchor = tkinter.NW)
self.window.after(self.delay, self.update_widget)
class App:
def __init__(self, window, window_title, video_sources):
self.window = window
self.window.title(window_title)
self.vids = []
for source in video_sources:
vid = tkCamera(window, source, 400, 300)
vid.pack()
self.vids.append(vid)
# Create a canvas that can fit the above video source size
self.window.mainloop()
if __name__ == __main__ :
sources = [
0,
# https://imageserver.webcamera.pl/rec/krupowki-srodek/latest.mp4 ,
# https://imageserver.webcamera.pl/rec/skolnity/latest.mp4 ,
https://imageserver.webcamera.pl/rec/krakow4/latest.mp4 ,
]
# Create a window and pass it to the Application object
App(tkinter.Tk(), "Tkinter and OpenCV", sources)
http://www.ohchr.org。
FCCC/SBI/2008/INF.1。 我添加<代码>(时间(1/fps),只在需要时才处理,以便其顺利运作。 延迟<代码>15有时冻结。
我只使用了24秒的消息来源,但只有几秒钟。
import tkinter
import cv2
import PIL.Image, PIL.ImageTk
import time
import threading
class MyVideoCapture:
def __init__(self, video_source=0, width=None, height=None, fps=None):
self.video_source = video_source
self.width = width
self.height = height
self.fps = fps
# Open the video source
self.vid = cv2.VideoCapture(video_source)
if not self.vid.isOpened():
raise ValueError("[MyVideoCapture] Unable to open video source", video_source)
# Get video source width and height
if not self.width:
self.width = int(self.vid.get(cv2.CAP_PROP_FRAME_WIDTH)) # convert float to int
if not self.height:
self.height = int(self.vid.get(cv2.CAP_PROP_FRAME_HEIGHT)) # convert float to int
if not self.fps:
self.fps = int(self.vid.get(cv2.CAP_PROP_FPS)) # convert float to int
# default value at start
self.ret = False
self.frame = None
# start thread
self.running = True
self.thread = threading.Thread(target=self.process)
self.thread.start()
def process(self):
while self.running:
ret, frame = self.vid.read()
if ret:
# process image
frame = cv2.resize(frame, (self.width, self.height))
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
else:
print( [MyVideoCapture] stream end: , self.video_source)
# TODO: reopen stream
self.running = False
break
# assign new frame
self.ret = ret
self.frame = frame
# sleep for next frame
time.sleep(1/self.fps)
def get_frame(self):
return self.ret, self.frame
# Release the video source when the object is destroyed
def __del__(self):
# stop thread
if self.running:
self.running = False
self.thread.join()
# relase stream
if self.vid.isOpened():
self.vid.release()
class tkCamera(tkinter.Frame):
def __init__(self, window, text="", video_source=0, width=None, height=None):
super().__init__(window)
self.window = window
#self.window.title(window_title)
self.video_source = video_source
self.vid = MyVideoCapture(self.video_source, width, height)
self.label = tkinter.Label(self, text=text)
self.label.pack()
self.canvas = tkinter.Canvas(self, width=self.vid.width, height=self.vid.height)
self.canvas.pack()
# Button that lets the user take a snapshot
self.btn_snapshot = tkinter.Button(self, text="Start", command=self.start)
self.btn_snapshot.pack(anchor= center , side= left )
self.btn_snapshot = tkinter.Button(self, text="Stop", command=self.stop)
self.btn_snapshot.pack(anchor= center , side= left )
# Button that lets the user take a snapshot
self.btn_snapshot = tkinter.Button(self, text="Snapshot", command=self.snapshot)
self.btn_snapshot.pack(anchor= center , side= left )
# After it is called once, the update method will be automatically called every delay milliseconds
# calculate delay using `FPS`
self.delay = int(1000/self.vid.fps)
print( [tkCamera] source: , self.video_source)
print( [tkCamera] fps: , self.vid.fps, delay: , self.delay)
self.image = None
self.running = True
self.update_frame()
def start(self):
if not self.running:
self.running = True
self.update_frame()
def stop(self):
if self.running:
self.running = False
def snapshot(self):
# Get a frame from the video source
#ret, frame = self.vid.get_frame()
#if ret:
# cv2.imwrite(time.strftime("frame-%d-%m-%Y-%H-%M-%S.jpg"), cv2.cvtColor(self.frame, cv2.COLOR_RGB2BGR))
# Save current frame in widget - not get new one from camera - so it can save correct image when it stoped
if self.image:
self.image.save(time.strftime("frame-%d-%m-%Y-%H-%M-%S.jpg"))
def update_frame(self):
# widgets in tkinter already have method `update()` so I have to use different name -
# Get a frame from the video source
ret, frame = self.vid.get_frame()
if ret:
self.image = PIL.Image.fromarray(frame)
self.photo = PIL.ImageTk.PhotoImage(image=self.image)
self.canvas.create_image(0, 0, image=self.photo, anchor= nw )
if self.running:
self.window.after(self.delay, self.update_frame)
class App:
def __init__(self, window, window_title, video_sources):
self.window = window
self.window.title(window_title)
self.vids = []
columns = 2
for number, source in enumerate(video_sources):
text, stream = source
vid = tkCamera(self.window, text, stream, 400, 300)
x = number % columns
y = number // columns
vid.grid(row=y, column=x)
self.vids.append(vid)
self.window.protocol("WM_DELETE_WINDOW", self.on_closing)
self.window.mainloop()
def on_closing(self, event=None):
print( [App] stoping threads )
for source in self.vids:
source.vid.running = False
print( [App] exit )
self.window.destroy()
if __name__ == __main__ :
sources = [
( me , 0),
( Zakopane, Poland , https://imageserver.webcamera.pl/rec/krupowki-srodek/latest.mp4 ),
( Kraków, Poland , https://imageserver.webcamera.pl/rec/krakow4/latest.mp4 ),
( Warszawa, Poland , https://imageserver.webcamera.pl/rec/warszawa/latest.mp4 ),
#( Baltic See, Poland , https://imageserver.webcamera.pl/rec/chlopy/latest.mp4 ),
#( Mountains, Poland , https://imageserver.webcamera.pl/rec/skolnity/latest.mp4 ),
]
# Create a window and pass it to the Application object
App(tkinter.Tk(), "Tkinter and OpenCV", sources)
http://www.ohchr.org。
能够记录录像的版本。
cv2
needs framework with BGRgur to Save it disabilities, so, I had to Save it before framework is reflected to RGB.
我将大多数代码移至<代码>MyVideoCapture。 即便没有<代码>tkinter,也可使用。 我也要在<代码>MyVideoCapture中添加以下选择:将图像作为<编码>cv2 阵列或<编码>>>>>,即现在将其转换成<代码>> > > pillow。 那么,主线就不必这样做。
import tkinter
import cv2
import PIL.Image, PIL.ImageTk
import time
import threading
class MyVideoCapture:
def __init__(self, video_source=0, width=None, height=None, fps=None):
self.video_source = video_source
self.width = width
self.height = height
self.fps = fps
# Open the video source
self.vid = cv2.VideoCapture(video_source)
if not self.vid.isOpened():
raise ValueError("[MyVideoCapture] Unable to open video source", video_source)
# Get video source width and height
if not self.width:
self.width = int(self.vid.get(cv2.CAP_PROP_FRAME_WIDTH)) # convert float to int
if not self.height:
self.height = int(self.vid.get(cv2.CAP_PROP_FRAME_HEIGHT)) # convert float to int
if not self.fps:
self.fps = int(self.vid.get(cv2.CAP_PROP_FPS)) # convert float to int
# default value at start
self.ret = False
self.frame = None
self.convert_color = cv2.COLOR_BGR2RGB
#self.convert_color = cv2.COLOR_BGR2GRAY
self.convert_pillow = True
# default values for recording
self.recording = False
self.recording_filename = output.mp4
self.recording_writer = None
# start thread
self.running = True
self.thread = threading.Thread(target=self.process)
self.thread.start()
def start_recording(self, filename=None):
if self.recording:
print( [MyVideoCapture] already recording: , self.recording_filename)
else:
# VideoWriter constructors
#.mp4 = codec id 2
if filename:
self.recording_filename = filename
else:
self.recording_filename = time.strftime("%Y.%m.%d %H.%M.%S", time.localtime()) + ".avi"
#fourcc = cv2.VideoWriter_fourcc(* I420 ) # .avi
#fourcc = cv2.VideoWriter_fourcc(* MP4V ) # .avi
fourcc = cv2.VideoWriter_fourcc(* MP42 ) # .avi
#fourcc = cv2.VideoWriter_fourcc(* AVC1 ) # error libx264
#fourcc = cv2.VideoWriter_fourcc(* H264 ) # error libx264
#fourcc = cv2.VideoWriter_fourcc(* WRAW ) # error --- no information ---
#fourcc = cv2.VideoWriter_fourcc(* MPEG ) # .avi 30fps
#fourcc = cv2.VideoWriter_fourcc(* MJPG ) # .avi
#fourcc = cv2.VideoWriter_fourcc(* XVID ) # .avi
#fourcc = cv2.VideoWriter_fourcc(* H265 ) # error
self.recording_writer = cv2.VideoWriter(self.recording_filename, fourcc, self.fps, (self.width, self.height))
self.recording = True
print( [MyVideoCapture] started recording: , self.recording_filename)
def stop_recording(self):
if not self.recording:
print( [MyVideoCapture] not recording )
else:
self.recording = False
self.recording_writer.release()
print( [MyVideoCapture] stop recording: , self.recording_filename)
def record(self, frame):
# write frame to file
if self.recording_writer and self.recording_writer.isOpened():
self.recording_writer.write(frame)
def process(self):
while self.running:
ret, frame = self.vid.read()
if ret:
# process image
frame = cv2.resize(frame, (self.width, self.height))
# it has to record before converting colors
if self.recording:
self.record(frame)
if self.convert_pillow:
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
frame = PIL.Image.fromarray(frame)
else:
print( [MyVideoCapture] stream end: , self.video_source)
# TODO: reopen stream
self.running = False
if self.recording:
self.stop_recording()
break
# assign new frame
self.ret = ret
self.frame = frame
# sleep for next frame
time.sleep(1/self.fps)
def get_frame(self):
return self.ret, self.frame
# Release the video source when the object is destroyed
def __del__(self):
# stop thread
if self.running:
self.running = False
self.thread.join()
# relase stream
if self.vid.isOpened():
self.vid.release()
class tkCamera(tkinter.Frame):
def __init__(self, window, text="", video_source=0, width=None, height=None):
super().__init__(window)
self.window = window
#self.window.title(window_title)
self.video_source = video_source
self.vid = MyVideoCapture(self.video_source, width, height)
self.label = tkinter.Label(self, text=text)
self.label.pack()
self.canvas = tkinter.Canvas(self, width=self.vid.width, height=self.vid.height)
self.canvas.pack()
# Button that lets the user take a snapshot
self.btn_snapshot = tkinter.Button(self, text="Start", command=self.start)
self.btn_snapshot.pack(anchor= center , side= left )
self.btn_snapshot = tkinter.Button(self, text="Stop", command=self.stop)
self.btn_snapshot.pack(anchor= center , side= left )
# Button that lets the user take a snapshot
self.btn_snapshot = tkinter.Button(self, text="Snapshot", command=self.snapshot)
self.btn_snapshot.pack(anchor= center , side= left )
# After it is called once, the update method will be automatically called every delay milliseconds
# calculate delay using `FPS`
self.delay = int(1000/self.vid.fps)
print( [tkCamera] source: , self.video_source)
print( [tkCamera] fps: , self.vid.fps, delay: , self.delay)
self.image = None
self.running = True
self.update_frame()
def start(self):
#if not self.running:
# self.running = True
# self.update_frame()
self.vid.start_recording()
def stop(self):
#if self.running:
# self.running = False
self.vid.stop_recording()
def snapshot(self):
# Get a frame from the video source
#ret, frame = self.vid.get_frame()
#if ret:
# cv2.imwrite(time.strftime("frame-%d-%m-%Y-%H-%M-%S.jpg"), cv2.cvtColor(self.frame, cv2.COLOR_RGB2BGR))
# Save current frame in widget - not get new one from camera - so it can save correct image when it stoped
if self.image:
self.image.save(time.strftime("frame-%d-%m-%Y-%H-%M-%S.jpg"))
def update_frame(self):
# widgets in tkinter already have method `update()` so I have to use different name -
# Get a frame from the video source
ret, frame = self.vid.get_frame()
if ret:
#self.image = PIL.Image.fromarray(frame)
self.image = frame
self.photo = PIL.ImageTk.PhotoImage(image=self.image)
self.canvas.create_image(0, 0, image=self.photo, anchor= nw )
if self.running:
self.window.after(self.delay, self.update_frame)
class App:
def __init__(self, window, window_title, video_sources):
self.window = window
self.window.title(window_title)
self.vids = []
columns = 2
for number, source in enumerate(video_sources):
text, stream = source
vid = tkCamera(self.window, text, stream, 400, 300)
x = number % columns
y = number // columns
vid.grid(row=y, column=x)
self.vids.append(vid)
self.window.protocol("WM_DELETE_WINDOW", self.on_closing)
self.window.mainloop()
def on_closing(self, event=None):
print( [App] stoping threads )
for source in self.vids:
source.vid.running = False
print( [App] exit )
self.window.destroy()
if __name__ == __main__ :
sources = [
( me , 0),
( Zakopane, Poland , https://imageserver.webcamera.pl/rec/krupowki-srodek/latest.mp4 ),
( Kraków, Poland , https://imageserver.webcamera.pl/rec/krakow4/latest.mp4 ),
( Warszawa, Poland , https://imageserver.webcamera.pl/rec/warszawa/latest.mp4 ),
#( Baltic See, Poland , https://imageserver.webcamera.pl/rec/chlopy/latest.mp4 ),
#( Mountains, Poland , https://imageserver.webcamera.pl/rec/skolnity/latest.mp4 ),
]
# Create a window and pass it to the Application object
App(tkinter.Tk(), "Tkinter and OpenCV", sources)
http://www.un.org。
我制作了可以选择来源的版本,从而可以展示录像。
该法典混乱。 糖尿病窗户可以分成几个班子。
我可以这样说,因为答案限于30 000个特性。
I put it on GitHub: python-cv2-streams-viewer