Sledujte tento komplexný projekt a zistite viac o Pythone a spracovaní obrázkov.

Či už chcete pracovať na pútavom projekte v jazyku Python alebo preskúmať rôzne aspekty programovania v jazyku Python, vytvorenie aplikácie fotoaparátu slúži na tento účel. Zahŕňa kombináciu rôznych aspektov programovania v Pythone, ako je vývoj grafického používateľského rozhrania (GUI), spracovanie obrázkov a videa a multi-threading.

Riešenie praktických výziev, ako je táto, tiež pomáha zdokonaliť vaše zručnosti pri riešení problémov. Tieto zručnosti sú cenné v akomkoľvek programátorskom úsilí.

Nastavenie vášho prostredia

Začnite tým vytvorenie nového virtuálneho prostredia. Tým sa izoluje váš projekt a zaistí sa, že medzi rôznymi verziami balíkov, ktoré inštalujete, nebude konflikt. Potom spustite tento príkaz terminálu:

pip install opencv-python pillow

Tento príkaz nainštaluje OpenCV knižnica a PIL (Python Imaging Library) vo vašom virtuálnom prostredí. OpenCV budete používať na funkčnosť počítačového videnia a PIL na manipuláciu s obrázkami.

instagram viewer

Úplný zdrojový kód tohto projektu je dostupný v a úložisko GitHub.

Import požadovaných knižníc

Po nainštalovaní týchto knižníc ich môžete importovať spolu s ďalšími potrebnými modulmi zo štandardnej knižnice Pythonu:

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

budete použitie tkinter na vytvorenie grafického používateľského rozhrania pre vašu aplikáciu a moduly operačného systému, vlákna a časové moduly pre ich súvisiace funkcie. Rozdelením časti kódu do vlákien to urobíte umožniť jej súbežné spustenie.

Vytvorenie adresára galérie a definovanie globálnych premenných a príznakov

Vytvorte adresár na ukladanie zachytených obrázkov a nahraných videí. Tento krok zaistí, že adresár existuje pred pokračovaním v zaznamenávaní alebo nahrávaní videí.

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

Potom definujte image_thumbnails a video_thumbnails premenných. Tieto budú ukladať miniatúry obrázkov a videí do galérie.

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

The update_camera vlajka bude ovládať aktualizácie kanálov kamery.

Snímanie obrázkov z podávača fotoaparátu

Definujte funkciu, ktorá bude používať OpenCV na zachytenie obrazu z kamery. Potom by mal získať snímku z fotoaparátu a uložiť ju do galéria adresár a zobrazte ho pomocou zobraziť_obrázok.

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)

Spustenie a zastavenie nahrávania videa

Pred zobrazením videa potrebujete spôsob, ako ho vytvoriť. Aby ste to dosiahli, vytvorte funkciu, ktorá spustí proces nahrávania videa, keď chce používateľ zachytiť video. Funkcia by mala tiež vypnúť Záznam (aby sa zabránilo viacnásobnému nahrávaniu súčasne) a aktivujte Zastaviť nahrávanie tlačidlo. To znamená, že prebieha nahrávanie.

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()

Potom vytvorte funkciu, ktorá zastaví nahrávanie videa a uvoľní zapisovač videa.

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)

Táto funkcia tiež aktualizuje používateľské rozhranie umožňujúce Záznam tlačidlo a zakázanie Zastaviť nahrávanie tlačidlo. To znamená, že nahrávanie sa zastavilo.

Nahrávanie a zobrazovanie videí

Vytvorte funkciu, ktorá bude nepretržite zachytávať snímky z fotoaparátu, spracovávať ich a zobrazovať v grafickom používateľskom rozhraní ako signál z fotoaparátu. Malo by tak urobiť, pokiaľ nie je Zastaviť nahrávanie je stlačené tlačidlo.

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)

Funkcia tiež vypočíta čas, ktorý uplynul od začiatku nahrávania a zobrazí ho na snímke videa.

Zobrazenie nasnímaných obrázkov a videí

Teraz, keď ste zachytili obrázky a nahrali videá, potrebujete spôsob, ako ich zobraziť.

Ak chcete zobraziť obrázky, vytvorte funkciu, ktorá otvorí obrázok a zobrazí ho vo fotoaparáte. To sa dosiahne otvorením obrázka pomocou PIL, potom ho skonvertujte do formátu, ktorý tkinter môžete zobraziť a nakoniec aktualizovať miniaplikáciu fotoaparátu s novým obrázkom.

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

Ak chcete zobraziť zachytené videá, vytvorte funkciu, ktorá otvorí okno prehrávača videa, kde si používateľ môže prezerať zaznamenané videá. Počas prehrávania videa tiež pozastaví aktualizácie napájania z fotoaparátu.

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)

Pozastavenie aktualizácií napájania fotoaparátu zaisťuje plynulý zážitok zo sledovania.

Vytvorenie miniatúry videa a otvorenie galérie

Vytvorte funkciu, ktorá vygeneruje miniatúrny obrázok pre dané video. Používatelia tak budú môcť ľahšie identifikovať video, ktoré ich zaujíma.

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

Ďalej vytvorte funkciu, ktorá prehrá video, keď používateľ klikne na miniatúru videa v okne galérie:

defplay_video_from_thumbnail(video_path):
play_video(video_path)

Potom vytvorte funkciu, ktorá vytvorí nové okno, v ktorom si používateľ môže prezerať nasnímané obrázky a videá.

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()

Pre obrázky aj videá sa vytvárajú miniatúry. To znamená, že kliknutím na ne zobrazíte obrázok v plnej veľkosti alebo prehráte video.

Vytvorenie hlavného používateľského rozhrania pre vašu aplikáciu

Začnite vytvorením hlavného tkinter okno aplikácie a potom mu dajte názov.

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

Potom inicializujte požadované premenné.

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

Potom vytvorte tlačidlá pre rôzne akcie.

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)

Pomocou správcu rozloženia mriežky usporiadajte tlačidlá v hlavnom okne.

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)

Vytvorte miniaplikáciu na zobrazenie informačného kanála fotoaparátu a jeho inicializáciu.

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

Potom vytvorte funkciu, ktorá nepretržite aktualizuje informačný kanál fotoaparátu zobrazený v tkinter okno.

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()

Nakoniec začnite hlavné tkinter slučka udalostí.

root.mainloop()

Táto slučka je zodpovedná za spracovanie interakcií používateľov.

Testovanie funkcií aplikácie

Toto video ukazuje rôzne funkcie aplikácie:

Vylepšite svoje zručnosti v jazyku Python pomocou OpenCV

OpenCV dominuje, pokiaľ ide o počítačové videnie. Pracuje s množstvom rôznych knižníc, čo vám umožňuje vytvárať veľa skvelých projektov. Môžete ho použiť s Pythonom na precvičenie a zdokonalenie svojich programovacích zručností.