Kövesse ezt az átfogó projektet, hogy többet tudjon meg a Pythonról és a képfeldolgozásról.

Akár egy lebilincselő Python-projekten szeretne dolgozni, akár a Python programozás különböző aspektusait szeretné felfedezni, egy kameraalkalmazás elkészítése ezt a célt szolgálja. Ez magában foglalja a Python programozás különböző aspektusainak kombinálását, mint például a grafikus felhasználói felület (GUI) fejlesztése, a kép- és videófeldolgozás, valamint a többszálú feldolgozás.

Ezenkívül az ehhez hasonló gyakorlati kihívások megoldása segít a problémamegoldó készségeinek fejlesztésében. Ezek a készségek értékesek minden programozási törekvésben.

Környezetének beállítása

Kezdje ezzel új virtuális környezet létrehozása. Ez elszigeteli a projektet, és biztosítja, hogy ne legyen ütközés a telepített csomagok különböző verziói között. Ezután futtassa ezt a terminálparancsot:

pip install opencv-python pillow

Ez a parancs telepíti a OpenCV könyvtár és PIL (Python Imaging Library) a virtuális környezetben. Az OpenCV-t a számítógépes látásfunkciókhoz, a PIL-t pedig a képkezeléshez használja.

instagram viewer

A projekt teljes forráskódja elérhető a GitHub adattár.

A szükséges könyvtárak importálása

Miután telepítette ezeket a könyvtárakat, importálhatja őket a többi szükséges modullal együtt a Python szabványos könyvtárából:

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

fogsz használat tkinter grafikus felhasználói felület létrehozásához alkalmazásához, valamint az operációs rendszerhez, a szálfűzéshez és az időmodulokhoz a kapcsolódó funkciókhoz. Ha a kód egy részét szálakra választja, akkor lehetővé teszi egyidejű futtatását.

Galériakönyvtár létrehozása és globális változók és zászlók meghatározása

Hozzon létre egy könyvtárat a rögzített képek és rögzített videók tárolására. Ez a lépés biztosítja, hogy a könyvtár létezik-e, mielőtt folytatná a videók rögzítését vagy rögzítését.

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

Ezután határozza meg image_thumbnails és video_thumbnails változók. Ezek a képek és videók miniatűrjeit tárolják a galériában.

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

A update_camera zászló fogja szabályozni a kamera hírfolyamának frissítéseit.

Képek rögzítése a kamera feedből

Határozzon meg egy funkciót, amely az OpenCV-t használja a kép rögzítésére a kamera feedből. Ezután le kell kérnie egy keretet a kamerából, és el kell mentenie a Képtár könyvtárat, és jelenítse meg a használatával 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)

Videofelvétel indítása és leállítása

Mielőtt megjelenítene egy videót, szüksége van egy módra a létrehozásához. Ennek eléréséhez hozzon létre egy funkciót, amely elindítja a videó rögzítési folyamatát, amikor a felhasználó videót szeretne rögzíteni. A funkciónak le kell tiltania a Rekord gombot (több felvétel egyidejű megakadályozásához), és engedélyezze a Felvétel leállítása gomb. Ez azt jelzi, hogy a felvétel folyamatban van.

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

Ezután hozzon létre egy funkciót, amely leállítja a videofelvételt, és felszabadítja a videóírót.

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)

Ez a funkció frissíti a felhasználói felületet is, lehetővé téve a Rekord gombot és letiltja a Felvétel leállítása gomb. Ez azt jelzi, hogy a felvétel leállt.

Videók rögzítése és megjelenítése

Hozzon létre egy funkciót, amely folyamatosan rögzíti a képkockákat a kamerából, feldolgozza azokat, és megjeleníti a grafikus felhasználói felületen, mint a kamera feedje. Ezt meg kell tennie, kivéve ha a Felvétel leállítása gombot megnyomják.

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)

A funkció kiszámítja a felvétel kezdete óta eltelt időt is, és megjeleníti a videókockán.

Rögzített képek és videók megjelenítése

Most, hogy elkészítette a képeket és rögzítette a videókat, meg kell jelenítenie őket.

A képek megjelenítéséhez hozzon létre egy funkciót, amely megnyit egy képet, és megjeleníti azt a kamera hírfolyamában. Ez a kép megnyitásával érhető el a PIL, majd konvertálja olyan formátumba, amely tkinter képes megjeleníteni, és végül frissíteni a kamera feed widgetet az új képpel.

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

A rögzített videók megjelenítéséhez hozzon létre egy funkciót, amely megnyit egy videólejátszó ablakot, ahol a felhasználó megtekintheti a rögzített videókat. A videó lejátszása közben szünetelteti a kamera hírfolyamának frissítését is.

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)

A kamera feed-frissítéseinek szüneteltetése zökkenőmentes megtekintési élményt biztosít.

Videó miniatűr létrehozása és a galéria megnyitása

Hozzon létre egy függvényt, amely egy miniatűr képet generál egy adott videóhoz. Ez megkönnyíti a felhasználók számára az érdeklődési körnek megfelelő videó azonosítását.

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

Ezután hozzon létre egy funkciót, amely lejátssza a videót, amikor a felhasználó a videó miniatűrére kattint a galériaablakban:

defplay_video_from_thumbnail(video_path):
play_video(video_path)

Ezután hozzon létre egy funkciót, amely egy új ablakot hoz létre, ahol a felhasználó megtekintheti a rögzített képeket és videókat.

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

A miniatűrök mind a képekhez, mind a videókhoz készülnek. Ez azt jelenti, hogy rájuk kattintva megtekintheti a teljes méretű képet vagy lejátszhatja a videót.

A fő felhasználói felület létrehozása az alkalmazáshoz

Kezdje a fő létrehozásával tkinter alkalmazás ablakát, majd adjon neki címet.

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

Ezután inicializálja a szükséges változókat.

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

Ezután hozzon létre gombokat a különféle műveletekhez.

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)

A főablak gombjainak rendszerezéséhez használja a rácselrendezés-kezelőt.

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)

Hozzon létre egy widgetet a kamera hírfolyamának megjelenítéséhez, és inicializálja azt.

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

Ezután hozzon létre egy funkciót, amely folyamatosan frissíti a kamera hírfolyamát, amely a képernyőn jelenik meg tkinter ablak.

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

Végül indítsa el a fő tkinter eseményhurok.

root.mainloop()

Ez a hurok felelős a felhasználói interakciók kezeléséért.

Az alkalmazás funkcióinak tesztelése

Ez a videó az alkalmazás különféle funkcióit mutatja be:

Élesítse Python-készségeit OpenCV-vel

Az OpenCV dominál a számítógépes látás terén. Számos különböző könyvtárral működik, így számos nagyszerű projektet hozhat létre. Használhatja a Pythonnal programozási készségeinek gyakorlására és élesítésére.