Ακολουθήστε αυτό το ολοκληρωμένο έργο για να μάθετε περισσότερα σχετικά με την Python και την επεξεργασία εικόνας.

Είτε θέλετε να εργαστείτε σε ένα συναρπαστικό έργο Python είτε να εξερευνήσετε διάφορες πτυχές του προγραμματισμού Python, η δημιουργία μιας εφαρμογής κάμερας εξυπηρετεί αυτόν τον σκοπό. Περιλαμβάνει το συνδυασμό διαφορετικών πτυχών του προγραμματισμού Python, όπως η ανάπτυξη γραφικών διεπαφής χρήστη (GUI), η επεξεργασία εικόνας και βίντεο και η πολυνηματική επεξεργασία.

Επίσης, η επίλυση πρακτικών προκλήσεων όπως αυτή συμβάλλει στην ενίσχυση των δεξιοτήτων επίλυσης προβλημάτων σας. Αυτές οι δεξιότητες είναι πολύτιμες σε κάθε προγραμματιστική προσπάθεια.

Ρύθμιση του περιβάλλοντος σας

Ξεκινήστε από δημιουργώντας ένα νέο εικονικό περιβάλλον. Αυτό θα απομονώσει το έργο σας και θα διασφαλίσει ότι δεν υπάρχει διένεξη μεταξύ των διαφορετικών εκδόσεων των πακέτων που εγκαθιστάτε. Στη συνέχεια, εκτελέστε αυτήν την εντολή τερματικού:

pip install opencv-python pillow

Αυτή η εντολή θα εγκαταστήσει το

instagram viewer
OpenCV βιβλιοθήκη και PIL (Python Imaging Library) στο εικονικό σας περιβάλλον. Θα χρησιμοποιήσετε OpenCV για λειτουργικότητα όρασης υπολογιστή και PIL για χειρισμό εικόνας.

Ο πλήρης πηγαίος κώδικας αυτού του έργου είναι διαθέσιμος στο α Αποθετήριο GitHub.

Εισαγωγή των Απαιτούμενων Βιβλιοθηκών

Αφού εγκαταστήσετε αυτές τις βιβλιοθήκες, μπορείτε να τις εισαγάγετε μαζί με άλλες απαραίτητες ενότητες από την τυπική βιβλιοθήκη της Python:

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

Θα χρήση tkinter για να δημιουργήσετε μια γραφική διεπαφή χρήστη για την εφαρμογή σας και τις λειτουργικές μονάδες, το threading και το χρόνο για τη σχετική λειτουργικότητά τους. Διαχωρίζοντας μέρος του κώδικά σας σε νήματα, θα ενεργοποιήστε το να εκτελείται ταυτόχρονα.

Δημιουργία καταλόγου συλλογής και ορισμός καθολικών μεταβλητών και σημαιών

Δημιουργήστε έναν κατάλογο για την αποθήκευση φωτογραφιών και εγγεγραμμένων βίντεο. Αυτό το βήμα θα διασφαλίσει ότι ο κατάλογος υπάρχει πριν προχωρήσετε στη λήψη ή την εγγραφή βίντεο.

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

Στη συνέχεια ορίστε image_μικρογραφίες και video_μικρογραφίες μεταβλητές. Αυτά θα αποθηκεύουν μικρογραφίες εικόνων και βίντεο στη συλλογή.

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

ο update_camera Η σημαία θα ελέγχει τις ενημερώσεις ροών κάμερας.

Λήψη εικόνων από την τροφοδοσία της κάμερας

Καθορίστε μια λειτουργία που θα χρησιμοποιεί το OpenCV για τη λήψη μιας εικόνας από την τροφοδοσία της κάμερας. Στη συνέχεια, θα πρέπει να ανακτήσει ένα πλαίσιο από την κάμερα και να το αποθηκεύσει στο εκθεσιακός χώρος καταλόγου και εμφανίστε τον χρησιμοποιώντας εμφάνιση_εικόνας.

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)

Έναρξη και διακοπή εγγραφής βίντεο

Προτού εμφανίσετε ένα βίντεο, χρειάζεστε έναν τρόπο για να το δημιουργήσετε. Για να το πετύχετε αυτό, δημιουργήστε μια λειτουργία που ξεκινά τη διαδικασία εγγραφής βίντεο όταν ο χρήστης θέλει να τραβήξει ένα βίντεο. Η λειτουργία θα πρέπει επίσης να απενεργοποιήσει το Ρεκόρ κουμπί (για την αποτροπή πολλαπλών εγγραφών ταυτόχρονα) και ενεργοποιήστε το Διακοπή εγγραφής κουμπί. Αυτό σημαίνει ότι η εγγραφή είναι σε εξέλιξη.

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

Στη συνέχεια, δημιουργήστε μια λειτουργία που σταματά την εγγραφή βίντεο και απελευθερώνει το πρόγραμμα εγγραφής βίντεο.

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)

Αυτή η λειτουργία ενημερώνει επίσης το UI ενεργοποιώντας το Ρεκόρ κουμπί και απενεργοποιώντας το Διακοπή εγγραφής κουμπί. Αυτό σημαίνει ότι η εγγραφή έχει σταματήσει.

Εγγραφή και προβολή βίντεο

Δημιουργήστε μια λειτουργία που θα καταγράφει συνεχώς καρέ από την κάμερα, θα τα επεξεργάζεται και θα τα εμφανίζει στο GUI ως τροφοδοσία της κάμερας. Θα πρέπει να το κάνει εκτός εάν το Διακοπή εγγραφής πατιέται το κουμπί.

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)

Η λειτουργία υπολογίζει επίσης τον χρόνο που έχει παρέλθει από την έναρξη της εγγραφής και τον εμφανίζει στο πλαίσιο του βίντεο.

Εμφάνιση τραβηγμένων εικόνων και βίντεο

Τώρα που έχετε τραβήξει τις εικόνες και καταγράψατε τα βίντεο, χρειάζεστε έναν τρόπο για να τις εμφανίσετε.

Για να εμφανίσετε τις εικόνες, δημιουργήστε μια λειτουργία που ανοίγει μια εικόνα και την εμφανίζει στη ροή της κάμερας. Αυτό επιτυγχάνεται ανοίγοντας την εικόνα χρησιμοποιώντας το PIL, στη συνέχεια μετατρέποντάς το σε μορφή που tkinter μπορεί να εμφανίσει και, τέλος, να ενημερώσει το widget τροφοδοσίας της κάμερας με τη νέα εικόνα.

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

Για να εμφανίσετε τα βίντεο που τραβήξατε, δημιουργήστε μια λειτουργία που ανοίγει ένα παράθυρο αναπαραγωγής βίντεο όπου ο χρήστης μπορεί να δει τα εγγεγραμμένα βίντεο. Επίσης, διακόπτει τις ενημερώσεις τροφοδοσίας κάμερας κατά την αναπαραγωγή του βίντεο.

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)

Η παύση των ενημερώσεων τροφοδοσίας κάμερας εξασφαλίζει μια ομαλή εμπειρία προβολής.

Δημιουργία μικρογραφίας βίντεο και άνοιγμα της συλλογής

Δημιουργήστε μια συνάρτηση που θα δημιουργήσει μια μικρογραφία για ένα δεδομένο βίντεο. Αυτό θα διευκολύνει τους χρήστες να αναγνωρίσουν το βίντεο που ενδιαφέρει.

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

Στη συνέχεια, δημιουργήστε μια συνάρτηση που αναπαράγει ένα βίντεο όταν ένας χρήστης κάνει κλικ στη μικρογραφία του βίντεο στο παράθυρο της συλλογής:

defplay_video_from_thumbnail(video_path):
play_video(video_path)

Στη συνέχεια, δημιουργήστε μια συνάρτηση που δημιουργεί ένα νέο παράθυρο όπου ο χρήστης μπορεί να δει τις εικόνες και τα βίντεο που τραβήχτηκαν.

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

Οι μικρογραφίες δημιουργούνται τόσο για εικόνες όσο και για βίντεο. Αυτό σημαίνει ότι μπορείτε να κάνετε κλικ πάνω τους για να δείτε την εικόνα πλήρους μεγέθους ή να αναπαράγετε το βίντεο.

Δημιουργία της κύριας διεπαφής χρήστη για την εφαρμογή σας

Ξεκινήστε δημιουργώντας το κύριο tkinter παράθυρο της εφαρμογής και μετά δώστε της έναν τίτλο.

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

Στη συνέχεια αρχικοποιήστε τις απαιτούμενες μεταβλητές.

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

Στη συνέχεια, δημιουργήστε κουμπιά για διάφορες ενέργειες.

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)

Χρησιμοποιήστε τη διαχείριση διάταξης πλέγματος για να οργανώσετε τα κουμπιά στο κύριο παράθυρο.

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)

Δημιουργήστε ένα widget για να εμφανίσετε τη ροή της κάμερας και να την αρχικοποιήσετε.

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

Στη συνέχεια, δημιουργήστε μια λειτουργία που ενημερώνει συνεχώς τη ροή της κάμερας που εμφανίζεται στο tkinter παράθυρο.

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

Τέλος, ξεκινήστε το κύριο tkinter βρόχος συμβάντος.

root.mainloop()

Αυτός ο βρόχος είναι υπεύθυνος για το χειρισμό των αλληλεπιδράσεων των χρηστών.

Δοκιμή των δυνατοτήτων της εφαρμογής

Αυτό το βίντεο δείχνει διάφορα χαρακτηριστικά της εφαρμογής:

Ακονίζοντας τις δεξιότητές σας στην Python με το OpenCV

Το OpenCV κυριαρχεί όταν πρόκειται για την όραση υπολογιστή. Λειτουργεί με πολλές διαφορετικές βιβλιοθήκες δίνοντάς σας τη δυνατότητα να δημιουργήσετε πολλά ωραία έργα. Μπορείτε να το χρησιμοποιήσετε με την Python για να εξασκηθείτε και να βελτιώσετε τις προγραμματιστικές σας δεξιότητες.