Пратите овај свеобухватни пројекат да бисте сазнали више о Питхон-у и обради слика.

Без обзира да ли желите да радите на занимљивом Питхон пројекту или истражите различите аспекте Питхон програмирања, изградња апликације за камеру служи овој сврси. Укључује комбиновање различитих аспеката Питхон програмирања, као што су развој графичког корисничког интерфејса (ГУИ), обрада слика и видеа и вишенитност.

Такође, решавање практичних изазова као што је овај помаже вам да изоштрите своје вештине решавања проблема. Ове вештине су драгоцене у сваком подухвату програмирања.

Подешавање вашег окружења

Старт би стварање новог виртуелног окружења. Ово ће изоловати ваш пројекат и осигурати да нема сукоба између различитих верзија пакета које инсталирате. Затим покрените ову терминалну команду:

pip install opencv-python pillow

Ова команда ће инсталирати ОпенЦВ библиотека и ПИЛ (Питхон Имагинг Либрари) у вашем виртуелном окружењу. Користићете ОпенЦВ за функционалност компјутерског вида и ПИЛ за манипулацију сликама.

instagram viewer

Комплетан изворни код овог пројекта доступан је у а ГитХуб спремиште.

Увоз потребних библиотека

Када инсталирате ове библиотеке, можете да их увезете заједно са другим неопходним модулима из Питхон стандардне библиотеке:

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

Ти ћеш користити ткинтер за креирање графичког корисничког интерфејса за вашу апликацију и модуле ОС, тхреадинг и временске модуле за њихову придружену функционалност. Одвајањем неког свог кода у нити, ви ћете омогућити да ради истовремено.

Креирање директоријума галерије и дефинисање глобалних променљивих и заставица

Направите директоријум за чување снимљених слика и видео записа. Овај корак ће осигурати да директоријум постоји пре него што наставите са снимањем или снимањем видео записа.

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

Затим дефинишите имаге_тхумбнаилс и видео_тхумбнаилс Променљиве. Они ће чувати сличице слика и видео записа у галерији.

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

Тхе упдате_цамера заставица ће контролисати ажурирања фееда камере.

Снимање слика из фееда камере

Дефинишите функцију која ће користити ОпенЦВ за снимање слике из фида камере. Затим би требало да преузме оквир из камере и сачува га у галерија директоријум и прикажите га помоћу схов_имаге.

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)

Ова функција такође ажурира кориснички интерфејс омогућавајући Запис дугме и онемогућавање Заустави снимање дугме. Ово указује да је снимање заустављено.

Снимање и приказивање видео записа

Креирајте функцију која ће континуирано снимати кадрове са камере, обрадити их и приказати на ГУИ-у као феед камере. То би требало да уради осим ако Заустави снимање дугме је притиснуто.

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)

Функција такође израчунава време које је протекло од почетка снимања и приказује га на видео кадру.

Приказ снимљених слика и видео записа

Сада када сте снимили слике и видео записе, потребан вам је начин да их прикажете.

Да бисте приказали слике, креирајте функцију која отвара слику и приказује је у фиду камере. Ово се постиже отварањем слике помоћу ПИЛ, а затим га конвертује у формат који ткинтер може да прикаже и коначно ажурира виџет за феед камере новом сликом.

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

Сличице се креирају и за слике и за видео записе. То значи да можете кликнути на њих да бисте видели слику у пуној величини или пустили видео.

Креирање главног корисничког интерфејса за вашу апликацију

Почните креирањем главног ткинтер прозор апликације, а затим му дајте наслов.

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)

Направите виџет за приказ фида камере и иницијализујте га.

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

Затим креирајте функцију која континуирано ажурира феед камере приказан у ткинтер прозор.

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

На крају, започните главни ткинтер петља догађаја.

root.mainloop()

Ова петља је одговорна за руковање интеракцијама корисника.

Тестирање функција апликације

Овај видео приказује различите функције апликације:

Изоштравање ваших Питхон вештина помоћу ОпенЦВ-а

ОпенЦВ доминира када је у питању компјутерски вид. Ради са много различитих библиотека што вам омогућава да креирате много цоол пројеката. Можете га користити са Питхон-ом да вежбате и изоштрите своје вештине програмирања.