die Buttons erklären sich selbst und es wird sofort ein Video zusammengefügt. Es langt eine USB-Cam oder auch die eingebaute Kamera im Rechner. Mit der "DEFAULT_CAM_ID" muss rumprobiert werden und mit "-1" wird die erste Cam (eingebaute Kamera) gefunden.
Code: Alles auswählen
#! /usr/bin/env python
# -*- coding: utf-8
try:
import tkinter as tk
except ImportError:
import Tkinter as tk
import cv2
from PIL import Image, ImageTk
from functools import partial
WIDTH = 600
HEIGHT = 480
FPS = 30
DEFAULT_CAM_ID = 0
CODEC = "XVID"
DEFAULT_FILE_NAME = "output.avi"
class Cam(object):
PROPID_WIDTH = 3
PROPID_HEIGHT = 4
def __init__(self, cam_id, file_name):
self.cam = cv2.VideoCapture(cam_id)
if not self.cam.isOpened():
raise RuntimeError("can not open camera {0!r}".format(
cam_id))
self.cam_width = self.cam.get(self.PROPID_WIDTH)
self.cam_height = self.cam.get(self.PROPID_HEIGHT)
self.video_writer = cv2.VideoWriter(file_name, cv2.cv.CV_FOURCC(
*CODEC), FPS, (int(self.cam_width), int(self.cam_height)))
def __enter__(self):
return self
def __exit__(self, *args):
self.release()
@property
def size(self):
return (int(self.cam_width), int(self.cam_height))
def get_image(self, size = None):
if size:
size = size
else:
size = self.size
state, self.frame = self.cam.read()
if state:
image = Image.frombytes("RGB", self.size ,self.frame,
"raw", "BGR").resize(size)
return image
else:
return state
def write_frame(self,width, height, fps):
for x in xrange(fps):
self.video_writer.write(self.frame)
def release(self):
self.cam.release()
class CartoonCamUI(tk.LabelFrame):
UPDATE_INTERVAL = 20
def __init__(self, parent, width, height, cam):
tk.LabelFrame.__init__(self, parent, text="CAPTURE",
relief = "solid")
self.parent = parent
self.cam = cam
self.width = width
self.height = height
self.tk_image = None
self.fps = 0
self.canvas = tk.Canvas(self, width=width, height=height, bd=10,
bg="lightgreen")
self.canvas.pack(padx=5, pady=5)
self.write_buttons = list()
self.canvas_confirm_frame = tk.Frame(self, bd=2)
confirm_yes = tk.Button(self.canvas_confirm_frame, text="YES",
command=partial(self.start_stop, write = True))
confirm_yes.pack(side="left")
confirm_no = tk.Button(self.canvas_confirm_frame, text="NO",
command=self.start_stop)
confirm_no.pack(side="right")
write_button_frame = tk.Frame(self, bg="gray")
write_button_frame.pack(padx=5, pady=5)
for column, (text, command, var) in enumerate(
(("ONE FRAME", self.start_stop, 1),
("1/8 SEC", self.start_stop, FPS / 8),
("1/4 SEC", self.start_stop, FPS / 4),
("1/2 SEC", self.start_stop, FPS / 2),
("1 SEC", self.start_stop, FPS ))):
button = tk.Button(write_button_frame, text=text, width=10,
relief="raised", font="Arial 10 bold")
button.grid(column=column, row=0)
self.write_buttons.append(button)
button.config(command=partial(command, var))
def start_stop(self, fps = None, write = False):
if fps != None:
self.fps = fps
if self.after_id is None:
self.canvas.config(bg="lightgreen")
self.canvas.delete("confirm_frame")
self.config(text="CAPTURE")
for button in self.write_buttons:
button.config(state="normal")
if write:
self.cam.write_frame(self.width, self.height, self.fps)
self.run()
else:
self.config(text="WRITE")
self.canvas.config(bg="red")
self.canvas.create_window(self.width / 2, self.height / 2,
window=self.canvas_confirm_frame, tag="confirm_frame")
for button in self.write_buttons:
button.config(state="disabled")
self.after_cancel(self.after_id)
self.after_id = None
def run(self):
self.tk_image = self.cam.get_image((self.width, self.height))
if self.tk_image:
self.canvas.delete("img")
self.tk_image = ImageTk.PhotoImage(self.tk_image)
self.canvas.create_image((10,10), anchor=tk.NW,
image=self.tk_image, tag="img")
self.after_id = self.after(self.UPDATE_INTERVAL, self.run)
else:
self.canvas.create_text((self.width / 2, self.height / 2),
text='NO CAM', font='Arial 40')
self.config(text="NO CAM")
for button in self.write_buttons:
button.config(state="disabled")
def release(self):
self.parent.destroy()
def main():
root = tk.Tk()
root.title('STOP-MOTION-CAM')
try:
with Cam(DEFAULT_CAM_ID, DEFAULT_FILE_NAME) as cam:
cartoon_cam_ui = CartoonCamUI(root, WIDTH, HEIGHT, cam)
cartoon_cam_ui.pack(expand=tk.YES, padx=5, pady=5)
cartoon_cam_ui.run()
root.protocol("WM_DELETE_WINDOW",cartoon_cam_ui.release)
root.mainloop()
except RuntimeError:
tk.Label(root, text = 'can not open camera {0!r}'.format(
DEFAULT_CAM_ID), font = "Arial 20", height = 10).pack()
root.mainloop()
if __name__ == '__main__':
main()