Izpildiet šo visaptverošo projektu, lai uzzinātu vairāk par Python un attēlu apstrādi.

Neatkarīgi no tā, vai vēlaties strādāt pie saistoša Python projekta vai izpētīt dažādus Python programmēšanas aspektus, kameras lietojumprogrammas izveide kalpo šim nolūkam. Tas ietver dažādu Python programmēšanas aspektu apvienošanu, piemēram, grafiskā lietotāja interfeisa (GUI) izstrādi, attēlu un video apstrādi un vairāku pavedienu izmantošanu.

Turklāt tādu praktisku izaicinājumu risināšana kā šis palīdz uzlabot jūsu problēmu risināšanas prasmes. Šīs prasmes ir vērtīgas jebkurā programmēšanas darbā.

Jūsu vides iestatīšana

Sāciet ar jaunas virtuālās vides izveide. Tas izolēs jūsu projektu un nodrošinās, ka nav konfliktu starp dažādām instalēto pakotņu versijām. Pēc tam palaidiet šo termināļa komandu:

pip install opencv-python pillow

Šī komanda instalēs OpenCV bibliotēka un PIL (Python Imaging Library) savā virtuālajā vidē. Datorredzes funkcionalitātei izmantosit OpenCV un attēlu manipulācijām PIL.

Pilns šī projekta pirmkods ir pieejams a GitHub repozitorijs.

instagram viewer

Nepieciešamo bibliotēku importēšana

Kad šīs bibliotēkas ir instalētas, varat tās importēt kopā ar citiem nepieciešamajiem moduļiem no Python standarta bibliotēkas:

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

Jūs to darīsit izmantot tkinter lai izveidotu grafisku lietotāja interfeisu jūsu lietojumprogrammai un operētājsistēmas, pavedienu veidošanas un laika moduļiem ar tiem saistītajai funkcionalitātei. Sadalot daļu sava koda pavedienos, jūs ļauj tai darboties vienlaikus.

Galerijas direktorija izveide un globālo mainīgo un karogu definēšana

Izveidojiet direktoriju uzņemto attēlu un ierakstīto video glabāšanai. Šī darbība nodrošinās, ka direktorijs pastāv, pirms turpināt uzņemt vai ierakstīt video.

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

Pēc tam definējiet image_thumbnails un video_thumbnails mainīgie. Tie saglabās attēlu un videoklipu sīktēlus galerijā.

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

The update_camera karodziņš kontrolēs kameras plūsmas atjauninājumus.

Attēlu tveršana no kameras plūsmas

Definējiet funkciju, kas izmantos OpenCV, lai uzņemtu attēlu no kameras plūsmas. Pēc tam tai vajadzētu izgūt rāmi no kameras un saglabāt to mapē galerija direktorijā un parādiet to, izmantojot parādīt_attēlu.

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)

Video ierakstīšanas sākšana un apturēšana

Pirms videoklipa parādīšanas jums ir nepieciešams veids, kā to izveidot. Lai to panāktu, izveidojiet funkciju, kas uzsāk video ierakstīšanas procesu, kad lietotājs vēlas uzņemt video. Funkcijai ir arī jāatspējo Ieraksts pogu (lai novērstu vairākus ierakstus vienlaicīgi) un iespējojiet Pārtraukt ierakstīšanu pogu. Tas norāda, ka notiek ierakstīšana.

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

Pēc tam izveidojiet funkciju, kas aptur video ierakstīšanu un atbrīvo video rakstītāju.

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)

Šī funkcija arī atjaunina lietotāja interfeisu, ļaujot Ieraksts pogu un atspējojot Pārtraukt ierakstīšanu pogu. Tas norāda, ka ierakstīšana ir pārtraukta.

Video ierakstīšana un rādīšana

Izveidojiet funkciju, kas nepārtraukti uzņems kadrus no kameras, apstrādās tos un parādīs tos GUI kā kameras plūsmu. Tas jādara, ja vien Pārtraukt ierakstīšanu tiek nospiesta poga.

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 arī aprēķina laiku, kas pagājis kopš ierakstīšanas sākuma, un parāda to video kadrā.

Uzņemto attēlu un video parādīšana

Tagad, kad esat uzņēmis attēlus un ierakstījis videoklipus, jums ir nepieciešams veids, kā tos parādīt.

Lai parādītu attēlus, izveidojiet funkciju, kas atver attēlu un parāda to kameras plūsmā. Tas tiek panākts, atverot attēlu, izmantojot PIL, pēc tam konvertējot to formātā, kas tkinter var parādīt un visbeidzot atjaunināt kameras plūsmas logrīku ar jauno attēlu.

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

Lai parādītu uzņemtos videoklipus, izveidojiet funkciju, kas atver video atskaņotāja logu, kurā lietotājs var skatīt ierakstītos videoklipus. Tas arī aptur kameras plūsmas atjauninājumus, kamēr tiek atskaņots video.

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)

Kameras plūsmas atjauninājumu apturēšana nodrošina vienmērīgu skatīšanās pieredzi.

Video sīktēla izveide un galerijas atvēršana

Izveidojiet funkciju, kas ģenerēs sīktēlu konkrētajam videoklipam. Tādējādi lietotājiem būs vieglāk identificēt interesējošo videoklipu.

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

Pēc tam izveidojiet funkciju, kas atskaņo videoklipu, kad lietotājs galerijas logā noklikšķina uz videoklipa sīktēla.

defplay_video_from_thumbnail(video_path):
play_video(video_path)

Pēc tam izveidojiet funkciju, kas izveido jaunu logu, kurā lietotājs var apskatīt uzņemtos attēlus un video.

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

Sīktēli tiek izveidoti gan attēliem, gan videoklipiem. Tas nozīmē, ka varat noklikšķināt uz tiem, lai skatītu pilna izmēra attēlu vai atskaņotu videoklipu.

Galvenās lietotāja saskarnes izveide jūsu lietojumprogrammai

Sāciet, izveidojot galveno tkinter lietojumprogrammas logu un pēc tam piešķiriet tam nosaukumu.

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

Pēc tam inicializējiet nepieciešamos mainīgos.

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

Pēc tam izveidojiet pogas dažādām darbībām.

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)

Izmantojiet režģa izkārtojuma pārvaldnieku, lai sakārtotu pogas galvenajā logā.

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)

Izveidojiet logrīku, lai parādītu kameras plūsmu, un inicializējiet to.

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

Pēc tam izveidojiet funkciju, kas nepārtraukti atjaunina kamerā parādīto kameras plūsmu tkinter logs.

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

Visbeidzot, sāciet galveno tkinter notikumu cilpa.

root.mainloop()

Šī cilpa ir atbildīga par lietotāja mijiedarbības apstrādi.

Lietotņu funkciju pārbaude

Šis video parāda dažādas lietotnes funkcijas:

Uzlabojiet savas Python prasmes, izmantojot OpenCV

OpenCV dominē, kad runa ir par datora redzi. Tas darbojas ar daudzām dažādām bibliotēkām, ļaujot jums izveidot daudz lielisku projektu. Varat to izmantot kopā ar Python, lai praktizētu un uzlabotu savas programmēšanas prasmes.