Vykdykite šį išsamų projektą, kad sužinotumėte daugiau apie Python ir vaizdo apdorojimą.

Nesvarbu, ar norite dirbti su patraukliu Python projektu, ar tyrinėti įvairius Python programavimo aspektus, fotoaparato programos kūrimas tarnauja šiam tikslui. Tai apima įvairių Python programavimo aspektų, tokių kaip grafinės vartotojo sąsajos (GUI) kūrimas, vaizdo ir vaizdo apdorojimas bei kelių gijų apdorojimas, derinimą.

Be to, tokių praktinių iššūkių sprendimas kaip šis padeda patobulinti jūsų problemų sprendimo įgūdžius. Šie įgūdžiai yra vertingi bet kokioje programavimo veikloje.

Aplinkos nustatymas

Pradėkite nuo sukurti naują virtualią aplinką. Tai izoliuos jūsų projektą ir užtikrins, kad nebūtų konfliktų tarp skirtingų įdiegtų paketų versijų. Tada paleiskite šią terminalo komandą:

pip install opencv-python pillow

Ši komanda įdiegs OpenCV biblioteka ir PIL (Python Imaging Library) savo virtualioje aplinkoje. Kompiuterinio matymo funkcionalumui naudosite OpenCV, o vaizdo manipuliavimui PIL.

Visą šio projekto šaltinio kodą rasite a GitHub saugykla.

instagram viewer

Reikalingų bibliotekų importavimas

Įdiegę šias bibliotekas, galite importuoti jas kartu su kitais reikalingais moduliais iš standartinės Python bibliotekos:

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

Jūs padarysite naudoti tkinteris sukurti grafinę vartotojo sąsają jūsų programai ir su jais susijusioms OS, sriegimo ir laiko moduliams. Atskirdami dalį savo kodo į gijas, jūs leisti jam veikti vienu metu.

Galerijos katalogo kūrimas ir visuotinių kintamųjų bei vėliavėlių apibrėžimas

Sukurkite katalogą užfiksuotiems vaizdams ir įrašytiems vaizdo įrašams saugoti. Šis veiksmas užtikrins, kad katalogas egzistuoja prieš fiksuojant ar įrašant vaizdo įrašus.

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

Tada apibrėžkite image_thumbnails ir video_thumbnails kintamieji. Tai išsaugos vaizdų ir vaizdo įrašų miniatiūras galerijoje.

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

The update_camera vėliavėlė valdys kameros tiekimo naujinimus.

Vaizdų fiksavimas iš fotoaparato tiekimo

Apibrėžkite funkciją, kuri naudos OpenCV, kad užfiksuotų vaizdą iš fotoaparato tiekimo. Tada jis turėtų gauti kadrą iš fotoaparato ir išsaugoti jį galerija katalogą ir parodykite jį naudodami rodyti_vaizdą.

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)

Vaizdo įrašymo pradžia ir sustabdymas

Prieš rodydami vaizdo įrašą, turite jį sukurti. Norėdami tai padaryti, sukurkite funkciją, kuri inicijuoja vaizdo įrašymo procesą, kai vartotojas nori užfiksuoti vaizdo įrašą. Funkcija taip pat turėtų išjungti Įrašas mygtuką (kad būtų išvengta kelių įrašų vienu metu) ir įgalinkite Sustabdykite įrašymą mygtuką. Tai rodo, kad vyksta įrašymas.

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

Tada sukurkite funkciją, kuri sustabdo vaizdo įrašymą ir atleidžia vaizdo įrašymo programą.

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)

Ši funkcija taip pat atnaujina vartotojo sąsają, leidžiančią Įrašas mygtuką ir išjungti Sustabdykite įrašymą mygtuką. Tai rodo, kad įrašymas sustabdytas.

Vaizdo įrašų įrašymas ir rodymas

Sukurkite funkciją, kuri nuolat fiksuos kadrus iš fotoaparato, juos apdoros ir rodys GUI kaip kameros tiekimą. Tai turėtų padaryti, nebent Sustabdykite įrašymą paspaudžiamas mygtukas.

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)

Funkcija taip pat apskaičiuoja laiką, praėjusį nuo įrašymo pradžios, ir parodo jį vaizdo kadre.

Užfiksuotų vaizdų ir vaizdo įrašų rodymas

Dabar, kai užfiksavote vaizdus ir įrašėte vaizdo įrašus, jums reikia būdo, kaip juos rodyti.

Norėdami rodyti vaizdus, ​​sukurkite funkciją, kuri atidaro vaizdą ir rodo jį fotoaparato tiekimo kanale. Tai pasiekiama atidarius vaizdą naudojant PIL, tada konvertuokite jį į formatą, kuris tkinteris gali rodyti ir galiausiai atnaujinti fotoaparato tiekimo valdiklį nauju vaizdu.

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

Norėdami rodyti užfiksuotus vaizdo įrašus, sukurkite funkciją, kuri atidaro vaizdo grotuvo langą, kuriame vartotojas gali peržiūrėti įrašytus vaizdo įrašus. Jis taip pat pristabdo fotoaparato tiekimo atnaujinimus, kol vaizdo įrašas leidžiamas.

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)

Pristabdžius fotoaparato tiekimo naujinimus užtikrinama sklandi žiūrėjimo patirtis.

Vaizdo įrašo miniatiūros kūrimas ir galerijos atidarymas

Sukurkite funkciją, kuri sukurs tam tikro vaizdo įrašo miniatiūrą. Taip naudotojai galės lengviau atpažinti dominantį vaizdo įrašą.

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

Tada sukurkite funkciją, kuri paleidžia vaizdo įrašą, kai vartotojas galerijos lange spusteli vaizdo įrašo miniatiūrą:

defplay_video_from_thumbnail(video_path):
play_video(video_path)

Tada sukurkite funkciją, kuri sukuria naują langą, kuriame vartotojas gali peržiūrėti užfiksuotus vaizdus ir vaizdo įrašus.

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

Miniatiūros kuriamos ir vaizdams, ir vaizdo įrašams. Tai reiškia, kad galite spustelėti juos ir peržiūrėti viso dydžio vaizdą arba paleisti vaizdo įrašą.

Pagrindinės programos vartotojo sąsajos sukūrimas

Pradėkite kurdami pagrindinį tkinteris programos langą ir suteikite jam pavadinimą.

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

Tada inicijuokite reikiamus kintamuosius.

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

Tada sukurkite mygtukus įvairiems veiksmams.

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)

Naudokite tinklelio išdėstymo tvarkyklę, kad tvarkytumėte mygtukus pagrindiniame lange.

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)

Sukurkite valdiklį, kad būtų rodomas fotoaparato tiekimas, ir jį inicijuokite.

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

Tada sukurkite funkciją, kuri nuolat atnaujina kameros tiekimą, rodomą tkinteris langas.

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

Galiausiai pradėkite pagrindinį tkinteris renginio kilpa.

root.mainloop()

Ši kilpa yra atsakinga už vartotojo sąveikos tvarkymą.

Programos funkcijų testavimas

Šiame vaizdo įraše demonstruojamos įvairios programos funkcijos:

Patobulinkite savo Python įgūdžius naudojant OpenCV

„OpenCV“ dominuoja, kai kalbama apie kompiuterinį regėjimą. Jis veikia su daugybe skirtingų bibliotekų, todėl galite sukurti daug puikių projektų. Galite naudoti jį kartu su Python, norėdami praktikuoti ir patobulinti savo programavimo įgūdžius.