Folgen Sie diesem umfassenden Projekt, um mehr über Python und Bildverarbeitung zu erfahren.

Ganz gleich, ob Sie an einem spannenden Python-Projekt arbeiten oder verschiedene Facetten der Python-Programmierung erkunden möchten, die Erstellung einer Kameraanwendung dient diesem Zweck. Dabei werden verschiedene Aspekte der Python-Programmierung kombiniert, wie z. B. die Entwicklung grafischer Benutzeroberflächen (GUI), Bild- und Videoverarbeitung und Multithreading.

Darüber hinaus trägt die Lösung praktischer Herausforderungen wie dieser dazu bei, Ihre Fähigkeiten zur Problemlösung zu schärfen. Diese Fähigkeiten sind bei jedem Programmiervorhaben wertvoll.

Einrichten Ihrer Umgebung

Beginnen Sie mit Erstellen einer neuen virtuellen Umgebung. Dadurch wird Ihr Projekt isoliert und sichergestellt, dass es keinen Konflikt zwischen verschiedenen Versionen der von Ihnen installierten Pakete gibt. Führen Sie dann diesen Terminalbefehl aus:

pip install opencv-python pillow

Dieser Befehl installiert die

OpenCV Bibliothek und PIL (Python Imaging Library) in Ihrer virtuellen Umgebung. Sie verwenden OpenCV für Computer-Vision-Funktionen und PIL für die Bildbearbeitung.

Der vollständige Quellcode dieses Projekts ist in a verfügbar GitHub-Repository.

Importieren der erforderlichen Bibliotheken

Sobald Sie diese Bibliotheken installiert haben, können Sie sie zusammen mit anderen erforderlichen Modulen aus der Standardbibliothek von Python importieren:

import tkinter as tk
import cv2
from PIL import Image, ImageTk
import os
import threading
import time

Du wirst verwenden tkinter um eine grafische Benutzeroberfläche zu erstellen für Ihre Anwendung und die Betriebssystem-, Threading- und Zeitmodule für die zugehörige Funktionalität. Indem Sie einen Teil Ihres Codes in Threads aufteilen, können Sie Folgendes erreichen: Aktivieren Sie die gleichzeitige Ausführung.

Erstellen eines Galerieverzeichnisses und Definieren globaler Variablen und Flags

Erstellen Sie ein Verzeichnis zum Speichern aufgenommener Bilder und aufgezeichneter Videos. Durch diesen Schritt wird sichergestellt, dass das Verzeichnis vorhanden ist, bevor mit der Aufnahme oder Aufnahme von Videos fortgefahren wird.

ifnot os.path.exists("gallery"):
os.makedirs("gallery")

Dann definieren image_thumbnails Und video_thumbnails Variablen. Dadurch werden Miniaturansichten von Bildern und Videos in der Galerie gespeichert.

# Initialize image_thumbnails as a global list
image_thumbnails = []
video_thumbnails = [] # New list for video thumbnails
update_camera = True

Der update_camera Flag steuert die Aktualisierung des Kamera-Feeds.

Aufnehmen von Bildern aus dem Kamera-Feed

Definieren Sie eine Funktion, die OpenCV verwendet, um ein Bild aus dem Kamera-Feed zu erfassen. Anschließend sollte ein Bild von der Kamera abgerufen und gespeichert werden Galerie Verzeichnis und zeigen Sie es mit an show_image.

defcapture_image():
ret, frame = cap.read()

if ret:
# Generate a unique filename with a timestamp
timestamp = time.strftime("%Y%m%d%H%M%S")
image_path = os.path.join("gallery", f"captured_image_{timestamp}.jpg")
cv2.imwrite(image_path, frame)
show_image(image_path)

Starten und Stoppen der Videoaufzeichnung

Bevor Sie ein Video anzeigen, müssen Sie eine Möglichkeit finden, es zu erstellen. Um dies zu erreichen, erstellen Sie eine Funktion, die den Videoaufzeichnungsprozess startet, wenn der Benutzer ein Video aufnehmen möchte. Die Funktion sollte auch das deaktivieren Aufzeichnen Taste (um mehrere Aufnahmen gleichzeitig zu verhindern) und aktivieren Sie die Höre auf, aufzunehmen Taste. Dies zeigt an, dass die Aufnahme läuft.

defstart_recording():
global video_writer, recording_start_time, recording_stopped, update_camera

ifnot video_writer:
timestamp = time.strftime("%Y%m%d%H%M%S")
video_path = os.path.join("gallery", f"recorded_video_{timestamp}.mp4")

# Use mp4v codec (or try other codecs)
fourcc = cv2.VideoWriter_fourcc(*'mp4v')

# Adjust frame rate and resolution if needed
video_writer = cv2.VideoWriter(video_path, fourcc, 20.0,
(640, 480))

recording_start_time = time.time()
recording_stopped = False
record_button.config(state=tk.DISABLED)
stop_button.config(state=tk.NORMAL)

# Start a separate thread for recording and time-lapse display
recording_thread = threading.Thread(target=record_and_display)
recording_thread.start()

Erstellen Sie dann eine Funktion, die die Videoaufzeichnung stoppt und den Videoschreiber freigibt.

defstop_recording():
global video_writer, recording_stopped

if video_writer:
video_writer.release()
recording_stopped = True
record_button.config(state=tk.NORMAL)
stop_button.config(state=tk.DISABLED)

Diese Funktion aktualisiert auch die Benutzeroberfläche und ermöglicht die Aufzeichnen Taste und Deaktivierung der Höre auf, aufzunehmen Taste. Dies zeigt an, dass die Aufnahme gestoppt wurde.

Aufnehmen und Anzeigen von Videos

Erstellen Sie eine Funktion, die kontinuierlich Bilder von der Kamera erfasst, verarbeitet und auf der GUI als Kamera-Feed anzeigt. Dies sollte der Fall sein, es sei denn, die Höre auf, aufzunehmen Taste gedrückt wird.

defrecord_and_display():
global recording_stopped, update_camera

while video_writer andnot recording_stopped:
ret, frame = cap.read()

if ret:
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

# Calculate elapsed time and add it to the frame
elapsed_time = time.time() - recording_start_time
timestamp = f"Time Elapsed: {int(elapsed_time)}s"

cv2.putText(frame, timestamp, (10, 30), cv2.FONT_HERSHEY_SIMPLEX,
0.5, (255, 255, 255), 2)

img = Image.fromarray(frame)
photo = ImageTk.PhotoImage(image=img)
camera_feed.config(image=photo)
camera_feed.image = photo

video_writer.write(frame)
time.sleep(0.05)

camera_feed.after(10, update_camera_feed)

Die Funktion berechnet auch die seit Beginn der Aufnahme verstrichene Zeit und zeigt sie im Videobild an.

Aufgenommene Bilder und Videos anzeigen

Nachdem Sie nun die Bilder aufgenommen und die Videos aufgezeichnet haben, benötigen Sie eine Möglichkeit, diese anzuzeigen.

Erstellen Sie zum Anzeigen der Bilder eine Funktion, die ein Bild öffnet und im Kamera-Feed anzeigt. Dies wird erreicht, indem Sie das Bild mit öffnen PIL, und konvertieren Sie es dann in ein Format, das tkinter anzeigen kann und schließlich das Kamera-Feed-Widget mit dem neuen Bild aktualisiert.

defshow_image(image_path):
image = Image.open(image_path)
photo = ImageTk.PhotoImage(image=image)
camera_feed.config(image=photo)
camera_feed.image = photo

Um die aufgenommenen Videos anzuzeigen, erstellen Sie eine Funktion, die ein Videoplayer-Fenster öffnet, in dem der Benutzer aufgezeichnete Videos ansehen kann. Außerdem werden die Aktualisierungen des Kamera-Feeds angehalten, während das Video abgespielt wird.

defplay_video(video_path):
defclose_video_player():
video_player.destroy()
global update_camera
update_camera = True

global update_camera
update_camera = False

video_player = tk.Toplevel(root)
video_player.title("Video Player")

video_cap = cv2.VideoCapture(video_path)

defupdate_video_frame():
ret, frame = video_cap.read()

if ret:
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
img = Image.fromarray(frame)
photo = ImageTk.PhotoImage(image=img)
video_label.config(image=photo)
video_label.image = photo

# Get the actual frame rate of the video
frame_rate = video_cap.get(cv2.CAP_PROP_FPS)
delay = int(1000 / frame_rate)

video_player.after(delay, update_video_frame)
else:
video_player.destroy()

video_label = tk.Label(video_player)
video_label.pack()

update_video_frame()

video_player.protocol("WM_DELETE_WINDOW", close_video_player)

Das Anhalten von Kamera-Feed-Updates sorgt für ein reibungsloses Seherlebnis.

Video-Miniaturansicht erstellen und Galerie öffnen

Erstellen Sie eine Funktion, die ein Miniaturbild für ein bestimmtes Video generiert. Dadurch wird es für Benutzer einfacher, das gewünschte Video zu identifizieren.

defcreate_video_thumbnail(video_path):
video_cap = cv2.VideoCapture(video_path)
ret, frame = video_cap.read()

if ret:
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
thumbnail = Image.fromarray(frame).resize((100, 100))
thumbnail_photo = ImageTk.PhotoImage(image=thumbnail)
return thumbnail_photo, os.path.basename(video_path)

returnNone, None

Erstellen Sie als Nächstes eine Funktion, die ein Video abspielt, wenn ein Benutzer auf die Miniaturansicht des Videos im Galeriefenster klickt:

defplay_video_from_thumbnail(video_path):
play_video(video_path)

Erstellen Sie dann eine Funktion, die ein neues Fenster erstellt, in dem der Benutzer die aufgenommenen Bilder und Videos ansehen kann.

defopen_gallery():
global update_camera
update_camera = False

gallery_window = tk.Toplevel(root)
gallery_window.title("Gallery")

defback_to_camera():
gallery_window.destroy()
global update_camera

# Resume updating the camera feed
update_camera = True

back_button = tk.Button(gallery_window, text="Back to Camera",
command=back_to_camera)

back_button.pack()

gallery_dir = "gallery"
image_files = [f for f in os.listdir(gallery_dir) if f.endswith(".jpg")]
video_files = [f for f in os.listdir(gallery_dir) if f.endswith(".mp4")]

# Clear the existing image_thumbnails and video_thumbnails lists
del image_thumbnails[:]
del video_thumbnails[:]

for image_file in image_files:
image_path = os.path.join(gallery_dir, image_file)
thumbnail = Image.open(image_path).resize((100, 100))
thumbnail_photo = ImageTk.PhotoImage(image=thumbnail)
image_name = os.path.basename(image_file)

defshow_image_in_gallery(img_path, img_name):
image_window = tk.Toplevel(gallery_window)
image_window.title("Image")
img = Image.open(img_path)
img_photo = ImageTk.PhotoImage(img)
img_label = tk.Label(image_window, image=img_photo)
img_label.image = img_photo
img_label.pack()
img_label_name = tk.Label(image_window, text=img_name)
img_label_name.pack()

thumbnail_label = tk.Label(gallery_window, image=thumbnail_photo)
thumbnail_label.image = thumbnail_photo

thumbnail_label.bind("", lambda event,
img_path=image_path,
img_name=image_name:
show_image_in_gallery(img_path, img_name))

thumbnail_label.pack()
image_thumbnails.append(thumbnail_photo)

# Display the image filename below the thumbnail
image_name_label = tk.Label(gallery_window, text=image_name)
image_name_label.pack()

for video_file in video_files:
video_path = os.path.join(gallery_dir, video_file)

# Create a video thumbnail and get the filename
thumbnail_photo, video_name = create_video_thumbnail(video_path)

if thumbnail_photo:
video_thumbnail_button = tk.Button(
gallery_window,
image=thumbnail_photo,
command=lambda path=video_path: play_video_from_thumbnail(path)
)

video_thumbnail_button.pack()

# Store the video thumbnail PhotoImage objects
video_thumbnails.append(thumbnail_photo)

# Display the video filename below the thumbnail
video_name_label = tk.Label(gallery_window, text=video_name)
video_name_label.pack()

Miniaturansichten werden sowohl für Bilder als auch für Videos erstellt. Das heißt, Sie können darauf klicken, um das Bild in voller Größe anzuzeigen oder das Video abzuspielen.

Erstellen der Hauptbenutzeroberfläche für Ihre Anwendung

Beginnen Sie mit der Erstellung der Hauptdatei tkinter Öffnen Sie das Anwendungsfenster und geben Sie ihm einen Titel.

root = tk.Tk()
root.title("Camera Application")

Anschließend initialisieren Sie die erforderlichen Variablen.

video_writer = None
recording_start_time = 0# Initialize recording start time
recording_stopped = False# Initialize recording_stopped flag

Erstellen Sie dann Schaltflächen für verschiedene Aktionen.

capture_button = tk.Button(root, text="Capture", command=capture_image)
record_button = tk.Button(root, text="Record", command=start_recording)
stop_button = tk.Button(root, text="Stop Recording", command=stop_recording)
gallery_button = tk.Button(root, text="Gallery", command=open_gallery)
quit_button = tk.Button(root, text="Quit", command=root.quit)

Verwenden Sie den Rasterlayout-Manager, um die Schaltflächen im Hauptfenster zu organisieren.

capture_button.grid(row=0, column=0, padx=10, pady=10)
record_button.grid(row=0, column=1, padx=10, pady=10)
stop_button.grid(row=0, column=2, padx=10, pady=10)
gallery_button.grid(row=0, column=3, padx=10, pady=10)
quit_button.grid(row=0, column=4, padx=10, pady=10)

Erstellen Sie ein Widget, um den Kamera-Feed anzuzeigen und zu initialisieren.

camera_feed = tk.Label(root)
camera_feed.grid(row=1, column=0, columnspan=5)
cap = cv2.VideoCapture(0)

Erstellen Sie dann eine Funktion, die den im angezeigten Kamera-Feed kontinuierlich aktualisiert tkinter Fenster.

defupdate_camera_feed():
if update_camera:
ifnot video_writer:
ret, frame = cap.read()

if ret:
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
img = Image.fromarray(frame)
photo = ImageTk.PhotoImage(image=img)
camera_feed.config(image=photo)
camera_feed.image = photo

root.after(10, update_camera_feed)

update_camera_feed()

Starten Sie schließlich den Hauptbildschirm tkinter Ereignisschleife.

root.mainloop()

Diese Schleife ist für die Verarbeitung von Benutzerinteraktionen verantwortlich.

Testen der App-Funktionen

Dieses Video demonstriert verschiedene Funktionen der App:

Schärfen Sie Ihre Python-Kenntnisse mit OpenCV

OpenCV dominiert, wenn es um Computer Vision geht. Es funktioniert mit vielen verschiedenen Bibliotheken, sodass Sie viele coole Projekte erstellen können. Sie können es mit Python verwenden, um Ihre Programmierkenntnisse zu üben und zu verbessern.