Contents

วิธีสร้างแอปพลิเคชันกล้องโดยใช้ Python

ไม่ว่าคุณจะต้องการทำงานในโปรเจ็กต์ Python ที่น่าสนใจหรือสำรวจแง่มุมต่างๆ ของการเขียนโปรแกรม Python การสร้างแอปพลิเคชันกล้องก็ตอบสนองจุดประสงค์นี้ โดยเกี่ยวข้องกับการรวมแง่มุมต่างๆ ของการเขียนโปรแกรม Python เช่น การพัฒนาส่วนติดต่อผู้ใช้แบบกราฟิก (GUI) การประมวลผลภาพและวิดีโอ และมัลติเธรด

นอกจากนี้ การแก้ปัญหาในโลกแห่งความเป็นจริงเช่นนี้ยังช่วยเพิ่มความสามารถในการคิดอย่างมีวิจารณญาณและความสามารถในการแก้ปัญหาอีกด้วย ความสามารถดังกล่าวมีความสำคัญอย่างยิ่งในโครงการพัฒนาซอฟต์แวร์ที่หลากหลาย

การตั้งค่าสภาพแวดล้อมของคุณ

ในการเริ่มต้น ให้สร้างสภาพแวดล้อมเสมือนใหม่ที่จะแยกโปรเจ็กต์ของคุณออกจากความคลาดเคลื่อนที่อาจเกิดขึ้นเนื่องจากเวอร์ชันแพ็คเกจที่ขัดแย้งกัน จากนั้น รันคำสั่งต่อไปนี้ในเทอร์มินัลของคุณ:

 pip install opencv-python pillow 

คำสั่งปัจจุบันจะอำนวยความสะดวกในการติดตั้งทั้งไลบรารี OpenCV ซึ่งมีชุดเครื่องมือที่ครอบคลุมสำหรับการปฏิบัติงานด้านการมองเห็นคอมพิวเตอร์ต่างๆ เช่นเดียวกับ Python Imaging Library (PIL) ซึ่งเป็นโมดูลสำคัญที่ช่วยให้ผู้ใช้สามารถดำเนินการประมวลผลภาพได้อย่างครอบคลุม. ด้วยเหตุนี้ คุณอาจใช้ OpenCV สำหรับฟังก์ชันการทำงานของคอมพิวเตอร์วิทัศน์ที่แข็งแกร่ง ขณะเดียวกันก็ใช้ PIL สำหรับการจัดการรูปภาพที่ซับซ้อนภายในสภาพแวดล้อมเสมือนของคุณ

ซอร์สโค้ดที่สมบูรณ์ของโปรเจ็กต์นี้สามารถเข้าถึงได้ผ่านพื้นที่เก็บข้อมูล GitHub ซึ่งทำหน้าที่เป็นพื้นที่เก็บข้อมูลดิจิทัลสำหรับนักพัฒนาในการแบ่งปันและทำงานร่วมกันในงานของพวกเขา

การนำเข้าไลบรารีที่จำเป็น

เมื่อติดตั้งไลบรารีเหล่านี้ ไลบรารีเหล่านี้อาจถูกนำเข้าควบคู่ไปกับโมดูลเพิ่มเติมที่ได้มาจากไลบรารีพื้นฐานของ Python ตามข้อกำหนดเฉพาะของแอปพลิเคชันหรืองานที่กำหนด

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

ฉันจะพัฒนาส่วนติดต่อผู้ใช้แบบกราฟิก (GUI) ที่ดึงดูดสายตาด้วยการใช้ไลบรารี Tkinter ซึ่งจะช่วยปรับปรุงประสบการณ์ผู้ใช้โดยรวมของแอปพลิเคชันของฉัน นอกจากนี้ การใช้ประโยชน์จากระบบปฏิบัติการ เธรดดิ้ง และโมดูลเวลาจะมอบฟังก์ชันการทำงานที่จำเป็นในการปรับปรุงประสิทธิภาพของระบบ ด้วยการใช้การทำงานพร้อมกันโดยการแยกบางส่วนของโค้ดออกเป็นเธรดที่แยกจากกัน ฉันตั้งเป้าที่จะเพิ่มประสิทธิภาพการดำเนินการและปรับปรุงการดำเนินงาน

การสร้างไดเร็กทอรีแกลเลอรีและการกำหนดตัวแปรและแฟล็กส่วนกลาง

กระบวนการนี้เกี่ยวข้องกับการสร้างโฟลเดอร์ที่กำหนดไว้สำหรับจัดเก็บทั้งภาพถ่ายที่ได้มาและวิดีโอฟุตเทจที่บันทึกไว้ ดังนั้นจึงมั่นใจได้ว่ามีพื้นที่จัดเก็บข้อมูลที่จำเป็นก่อนที่จะบันทึกหรือบันทึกเนื้อหาภาพใดๆ

 if not 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 

ธง"อัปเดต\_กล้อง"ทำหน้าที่ควบคุมความถี่ของการอัปเดตฟีดกล้อง

การถ่ายภาพจากฟีดกล้อง

pythondef process_frame(กล้อง):# จับภาพเฟรมจากกล้อง feedframe=cv2.imread(‘input_video.mp4’)# บันทึกเฟรมลงในไดเร็กทอรี’gallery’ด้วยชื่อไฟล์ที่ไม่ซ้ำกันตามหมายเลขดัชนี i=0 ในขณะที่ True:filename=f"{i}.jpg"if not os.path.exists(“gallery”):os.makedirs(“gallery”)retval=cv2.imwrite(filename, frame)i +=1# แสดงเฟรมที่บันทึกไว้โดยใช้ show\_image cv2.imshow(cv2.namedWindow(“แกลเลอรี”, cv2.WINDOW

 def capture_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) 

การเริ่มต้นและหยุดการบันทึกวิดีโอ

ในการจัดแสดงวิดีโอ จำเป็นต้องกำหนดวิธีการสร้างวิดีโอขึ้นมา ดังนั้น เราจะพัฒนาฟังก์ชันที่เริ่มการบันทึกวิดีโอตามคำแนะนำจากผู้ใช้ในการจับภาพวิดีโอ นอกจากนี้ ฟังก์ชันนี้จะปิดใช้งานปุ่ม"บันทึก"(เพื่อป้องกันไม่ให้มีการบันทึกพร้อมกัน) ในขณะที่เปิดใช้งานปุ่ม"หยุดการบันทึก"การดำเนินการนี้แสดงว่าการบันทึกได้เริ่มต้นแล้ว

 def start_recording():
    global video_writer, recording_start_time, recording_stopped, update_camera

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

ต่อจากนั้น พัฒนาฟังก์ชันที่จะยุติกระบวนการจับภาพวิดีโอและปลดปล่อยตัวเข้ารหัสวิดีโอ

 def stop_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)

ฟังก์ชันที่กล่าวมาข้างต้นจะดำเนินการเพิ่มเติมในการอัปเดตอินเทอร์เฟซผู้ใช้ ซึ่งจะต้องมีการเปิดใช้งานปุ่ม"บันทึก"ในขณะที่ปิดใช้งานปุ่ม"หยุดการบันทึก"การกระทำดังกล่าวแสดงว่ากระบวนการบันทึกได้สิ้นสุดลงแล้ว

การบันทึกและการแสดงวิดีโอ

โปรดพัฒนาฟังก์ชันที่จะรับเฟรมจากแหล่งวิดีโอได้อย่างราบรื่น ดำเนินการประมวลผลที่จำเป็น และนำเสนอภายในอินเทอร์เฟซผู้ใช้แบบกราฟิกจนกว่าจะถึงเวลาที่คำสั่ง"หยุดการบันทึก"ถูกเปิดใช้งาน การดำเนินการตามกระบวนการนี้จะถูกยกเลิกเมื่อมีการดำเนินการดังกล่าวข้างต้น

 def record_and_display():
    global recording_stopped, update_camera

    while video_writer and not 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)

ฟังก์ชันการทำงานของฟังก์ชันยังครอบคลุมถึงการคำนวณและการแสดงระยะเวลาเป็นนาทีและวินาที ซึ่งเกิดขึ้นนับตั้งแต่เริ่มการบันทึก ภายในเฟรมวิดีโอแต่ละเฟรม

การแสดงรูปภาพและวิดีโอที่ถ่าย

เพื่อที่จะแสดงเนื้อหาภาพที่ได้รับมาอย่างประสบความสำเร็จผ่านกระบวนการถ่ายภาพและการบันทึกวิดีโอ จำเป็นต้องมีวิธีการนำเสนอที่เหมาะสม

เพื่อแสดงเนื้อหาภาพบนอินเทอร์เฟซผู้ใช้ จำเป็นต้องพัฒนาฟังก์ชันการทำงานที่ดึงไฟล์ภาพจากตำแหน่งที่เก็บข้อมูล แปลงเป็นรูปแบบที่เข้ากันได้กับอินเทอร์เฟซผู้ใช้แบบกราฟิกของไลบรารี Python Tkinter และอัปเดตวิวพอร์ตที่แสดง ด้วยข้อมูลภาพที่ได้รับมาใหม่ กระบวนการนี้เกี่ยวข้องกับการใช้ Python Imaging Library (PIL) ในการเข้าถึงและประมวลผลภาพที่เก็บไว้ ตามด้วยการใช้วิธีการที่เหมาะสมของเฟรมเวิร์ก Tkinter GUI เพื่อรวมภาพที่แปลงแล้วไว้ภายในพื้นที่ที่กำหนดของหน้าจอแสดงตัวอย่างกล้อง

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

ในการแสดงวิดีโอที่บันทึกไว้ ควรใช้ฟังก์ชันที่เปิดใช้งานอินเทอร์เฟซการเล่นวิดีโอที่ทำให้ผู้ชมสามารถชมภาพที่บันทึกไว้ได้ นอกจากนี้ กระบวนการนี้จะระงับการอัปเดตเพิ่มเติมใดๆ ของการสตรีมของกล้องระหว่างการเล่นวิดีโอ

 def play_video(video_path):
    def close_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)

    def update_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)

การหยุดการเผยแพร่การอัปเดตสตรีมวิดีโอจะก่อให้เกิดการรับรู้ภาพที่ราบรื่น

การสร้างภาพขนาดย่อของวิดีโอและการเปิดแกลเลอรี

ใช้ข้อความต่อไปนี้ในลักษณะที่มีคารมคมคาย:การใช้คุณลักษณะการสร้างภาพขนาดย่อถือเป็นสิ่งสำคัญ เนื่องจากช่วยให้ผู้ใช้สามารถแยกแยะและเลือกเนื้อหาวิดีโอที่ต้องการได้อย่างรวดเร็วผ่านการนำเสนอภาพขนาดย่อที่กระชับ

 def create_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)

     return None, None 

สร้างฟังก์ชัน JavaScript ใหม่ที่เรียกว่า"playVideo"ซึ่งจะถูกเรียกใช้เมื่อคลิกที่ภาพขนาดย่อของวิดีโอภายในหน้าต่างแกลเลอรี ฟังก์ชันนี้ควรเริ่มเล่นวิดีโอที่เลือกและแสดงภายในคอนเทนเนอร์ของเครื่องเล่นวิดีโอ

 def play_video_from_thumbnail(video_path):
    play_video(video_path) 

แน่นอนว่า นี่คือตัวอย่างวิธีที่คุณสามารถใช้ฟังก์ชันนี้ใน Python โดยใช้ไลบรารี OpenCV:pythonimport cv2import numpy as npfrom tkinter import Tk, Frame, Button, Label, Text, Scrollbar, VERTICAL)def save_captured_frames(window):# Define capture parameter (สามารถเปลี่ยนเพื่อปรับความละเอียด อัตราเฟรม ฯลฯ)cap=cv2.VideoCapture(0)fourcc=cv2.VideoWriter_fourcc(*“mp4v”)fps=int(cap.get(cv2.CAP_PROP_FPS))width=int( cap.get(cv2.CAP_PROP_FRAME_WIDTH))

 def open_gallery():
    global update_camera
    update_camera = False

     gallery_window = tk.Toplevel(root)
    gallery_window.title("Gallery")

    def back_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)

        def show_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("<Button-1>", 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)

การใช้ Grid Layout Manager เป็นกลยุทธ์ที่มีประสิทธิภาพในการจัดเรียงปุ่มภายในหน้าต่างหลักของแอปพลิเคชัน ทำให้มีการนำเสนอที่ดึงดูดสายตาและเป็นระเบียบ ในขณะเดียวกันก็รับประกันความสะดวกในการเข้าถึงและการโต้ตอบกับปุ่มแต่ละปุ่ม

 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)

แน่นอน! นี่คือตัวอย่างวิธีที่คุณสามารถใช้ฟังก์ชันนี้โดยใช้ OpenCV และ Python:pythonimport cv2from tkinter import *import threadingimport timedef update_camera_feed():# Initialize the video capture devicecap=cv2.VideoCapture(0) While True:# อ่านเฟรมจากวิดีโอ streamret, frame=cap.read()if not ret:break# แสดงเฟรมบน GUIlabel.config(image=frame)# รอการกดปุ่มเพื่อออกจาก looproot.update()event=root.wait_event()if เหตุการณ์==‘q’:

 def update_camera_feed():
    if update_camera:
        if not 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()

สุดท้าย ให้เริ่มลูป maintkinterevent

 root.mainloop()

วงปัจจุบันมีบทบาทสำคัญในการจัดการการมีส่วนร่วมของผู้ใช้และอำนวยความสะดวกในการโต้ตอบกับระบบ

การทดสอบคุณสมบัติของแอพ

เนื้อหาการนำเสนอนำเสนอฟังก์ชันต่างๆ ที่แสดงโดยแอปพลิเคชัน โดยเน้นย้ำถึงความสามารถและความอเนกประสงค์ในการใช้งาน

เบราว์เซอร์ของคุณไม่รองรับแท็กวิดีโอ

ฝึกฝนทักษะ Python ของคุณด้วย OpenCV

OpenCV ได้รับการยอมรับอย่างกว้างขวางว่าเป็นเครื่องมือที่โดดเด่นสำหรับแอปพลิเคชันคอมพิวเตอร์วิทัศน์ เนื่องจากสามารถใช้งานร่วมกับไลบรารีที่หลากหลายซึ่งอำนวยความสะดวกในการพัฒนาโครงการนวัตกรรมต่างๆ นอกจากนี้ ผู้ใช้ยังมีทางเลือกในการใช้ประโยชน์จากความสามารถผ่าน Python ซึ่งทำหน้าที่เป็นแพลตฟอร์มที่ยอดเยี่ยมสำหรับการพัฒนาความสามารถในการเขียนโปรแกรม