iT邦幫忙

2024 iThome 鐵人賽

DAY 12
0

今天是第十二天我們可以寫一個斑馬魚的使用者介面,以下是python程式

import tkinter as tk
from tkinter import filedialog, messagebox
from tkinter import ttk

def yolo_calculate(image_path, weight_path):
    # 假設這是一個 YOLO 計算的函數
    # 這裡放置你的 YOLO 計算邏輯
    result_image_path = image_path  # 這是個假設,實際上應該返回處理過的圖片路徑
    return result_image_path

def lstm_calculate(image_path):
    # 假設這是一個 LSTM 計算的函數
    # 這裡放置你的 LSTM 計算邏輯
    return "LSTM Calculation Result"

def zebrafish_yolo_v8(video_path):
    # 假設這是一個 YOLO v8 斑馬魚運動軌跡計算的函數
    # 這裡放置你的 YOLO v8 計算邏輯
    result_video_path = video_path  # 這是個假設,實際上應該返回處理過的影片路徑
    return result_video_path

def analyze_zebrafish_behavior(video_path):
    # 假設這是一個分析斑馬魚行為的函數
    # 返回行為佔比的字典
    return {
        "正常": 50,
        "害怕": 20,
        "焦慮": 15,
        "壓抑": 15
    }

def select_file():
    file_path = filedialog.askopenfilename(filetypes=[("Image/Video Files", "*.gif;*.mp4;*.avi")])
    if file_path:
        file_path_var.set(file_path)

def select_weight():
    weight_path = filedialog.askopenfilename(filetypes=[("Weight Files", "*.weights")])
    if weight_path:
        weight_path_var.set(weight_path)

def perform_yolo():
    file_path = file_path_var.get()
    weight_path = weight_path_var.get()
    if not file_path or not weight_path:
        messagebox.showerror("Error", "Please select both file and weight paths.")
        return

    result_image_path = yolo_calculate(file_path, weight_path)
    load_image(result_image_path)

def perform_lstm():
    file_path = file_path_var.get()
    if not file_path:
        messagebox.showerror("Error", "Please select a file path.")
        return

    result = lstm_calculate(file_path)
    result_var.set(result)

def perform_zebrafish_yolo_v8():
    video_path = file_path_var.get()
    if not video_path:
        messagebox.showerror("Error", "Please select a video path.")
        return

    result_video_path = zebrafish_yolo_v8(video_path)
    load_video(result_video_path)

def show_behavior(behavior):
    video_path = file_path_var.get()
    if not video_path:
        messagebox.showerror("Error", "Please select a video path.")
        return

    behavior_data = analyze_zebrafish_behavior(video_path)
    behavior_percentage = behavior_data.get(behavior, 0)
    messagebox.showinfo(f"{behavior}行為佔比", f"{behavior}行為佔比為: {behavior_percentage}%")

def load_image(image_path):
    try:
        img = tk.PhotoImage(file=image_path)
        image_label.config(image=img)
        image_label.image = img
    except Exception as e:
        messagebox.showerror("Error", f"Cannot load image: {e}")

def load_video(video_path):
    # 這裡你可以加入播放影片的邏輯,或者顯示影片處理結果的圖片
    messagebox.showinfo("Video Processed", f"Video processed and saved to: {video_path}")

# 建立主視窗
root = tk.Tk()
root.title("YOLO and LSTM GUI")
root.geometry("800x600")

# 檔案路徑變數
file_path_var = tk.StringVar()
weight_path_var = tk.StringVar()
result_var = tk.StringVar()

# 創建一個框架以容納所有的小部件
main_frame = ttk.Frame(root, padding="10")
main_frame.place(relwidth=0.9, relheight=0.9, relx=0.05, rely=0.05)

# 檔案選擇
ttk.Label(main_frame, text="Select Image/Video:").grid(row=0, column=0, padx=5, pady=5, sticky="e")
ttk.Entry(main_frame, textvariable=file_path_var, width=50).grid(row=0, column=1, padx=5, pady=5, sticky="ew")
ttk.Button(main_frame, text="Browse", command=select_file).grid(row=0, column=2, padx=5, pady=5, sticky="w")

# 權重檔選擇
ttk.Label(main_frame, text="Select Weight File:").grid(row=1, column=0, padx=5, pady=5, sticky="e")
ttk.Entry(main_frame, textvariable=weight_path_var, width=50).grid(row=1, column=1, padx=5, pady=5, sticky="ew")
ttk.Button(main_frame, text="Browse", command=select_weight).grid(row=1, column=2, padx=5, pady=5, sticky="w")

# YOLO 計算按鈕
ttk.Button(main_frame, text="YOLO 辨識結果", command=perform_yolo).grid(row=2, column=0, columnspan=3, padx=5, pady=5, sticky="ew")

# LSTM 計算按鈕
ttk.Button(main_frame, text="LSTM 計算結果", command=perform_lstm).grid(row=3, column=0, columnspan=3, padx=5, pady=5, sticky="ew")

# YOLO v8 斑馬魚運動軌跡計算按鈕
ttk.Button(main_frame, text="顯示斑馬魚運動軌跡影片", command=perform_zebrafish_yolo_v8).grid(row=4, column=0, columnspan=3, padx=5, pady=5, sticky="ew")

# 行為分析按鈕
ttk.Button(main_frame, text="正常行為佔比", command=lambda: show_behavior("正常")).grid(row=5, column=0, padx=5, pady=5, sticky="ew")
ttk.Button(main_frame, text="害怕行為佔比", command=lambda: show_behavior("害怕")).grid(row=5, column=1, padx=5, pady=5, sticky="ew")
ttk.Button(main_frame, text="焦慮行為佔比", command=lambda: show_behavior("焦慮")).grid(row=5, column=2, padx=5, pady=5, sticky="ew")
ttk.Button(main_frame, text="壓抑行為佔比", command=lambda: show_behavior("壓抑")).grid(row=6, column=0, padx=5, pady=5, sticky="ew")

# 顯示結果
ttk.Label(main_frame, text="LSTM Result:").grid(row=7, column=0, padx=5, pady=5, sticky="e")
ttk.Entry(main_frame, textvariable=result_var, width=50, state="readonly").grid(row=7, column=1, padx=5, pady=5, columnspan=2, sticky="ew")

# 圖像顯示
image_label = ttk.Label(main_frame)
image_label.grid(row=8, column=0, columnspan=3, padx=5, pady=5, sticky="nsew")

# 啟動主迴圈
root.mainloop()

1. 匯入模組

import tkinter as tk
from tkinter import filedialog, messagebox
from tkinter import ttk
  • tkinter 是 Python 的標準 GUI 工具包,用於創建桌面應用程式。
  • filedialog 提供了一組用於選擇文件的對話框函數。
  • messagebox 提供彈出消息框,通常用於顯示錯誤、警告或資訊訊息。
  • ttktkinter 的增強版,提供了一組改進的 GUI 元件,如按鈕、標籤和輸入框,具有更現代的外觀。

2. 計算函數

這些函數模擬了應用程式中不同的計算過程,雖然目前它們只是一個框架或佔位符,但它們展示了不同計算模組之間的分工。

(1) YOLO 計算函數

def yolo_calculate(image_path, weight_path):
    # 假設這是一個 YOLO 計算的函數
    # 這裡放置你的 YOLO 計算邏輯
    result_image_path = image_path  # 這是個假設,實際上應該返回處理過的圖片路徑
    return result_image_path
  • YOLO (You Only Look Once) 是一種實時物體檢測演算法。在這個函數中,你將影像的檔案路徑 (image_path) 和權重檔案的路徑 (weight_path) 作為輸入。
  • 這個函數內應該包含 YOLO 的具體計算邏輯,例如加載權重檔案,對影像進行物體檢測,並輸出結果。
  • 目前,這個函數只返回輸入的影像路徑,假設這是處理過的影像的存放位置。

(2) LSTM 計算函數

def lstm_calculate(image_path):
    # 假設這是一個 LSTM 計算的函數
    # 這裡放置你的 LSTM 計算邏輯
    return "LSTM Calculation Result"
  • LSTM (Long Short-Term Memory) 是一種適合處理和預測時間序列的深度學習模型。在這個函數中,你將影像的檔案路徑作為輸入。
  • 這個函數內應該包含 LSTM 模型的具體邏輯,例如處理輸入數據,進行預測或分析,然後返回結果。
  • 目前,這個函數只返回一個假設的計算結果字串 "LSTM Calculation Result"

(3) YOLO v8 斑馬魚運動軌跡計算函數

def zebrafish_yolo_v8(video_path):
    # 假設這是一個 YOLO v8 斑馬魚運動軌跡計算的函數
    # 這裡放置你的 YOLO v8 計算邏輯
    result_video_path = video_path  # 這是個假設,實際上應該返回處理過的影片路徑
    return result_video_path
  • 這個函數專門處理 YOLO v8 算法應用於斑馬魚運動軌跡的計算。
  • 輸入是影片的檔案路徑 (video_path),函數內應包含 YOLO v8 的邏輯,用來分析影片中的斑馬魚運動軌跡。
  • 當完成計算後,應返回處理過的影片路徑。此處只是假設返回輸入的影片路徑。

(4) 分析斑馬魚行為的函數

def analyze_zebrafish_behavior(video_path):
    # 假設這是一個分析斑馬魚行為的函數
    # 返回行為佔比的字典
    return {
        "正常": 50,
        "害怕": 20,
        "焦慮": 15,
        "壓抑": 15
    }
  • 這個函數負責分析斑馬魚的行為,基於輸入的影片檔案路徑進行分析。
  • 返回值是一個字典,表示不同行為的佔比。這些行為包括 "正常"、"害怕"、"焦慮" 和 "壓抑"。

3. 檔案選擇與計算操作的函數

這些函數提供了 GUI 用戶操作與核心功能之間的接口,使得用戶可以通過介面選擇文件、觸發計算並查看結果。

(1) 檔案選擇函數

def select_file():
    file_path = filedialog.askopenfilename(filetypes=[("Image/Video Files", "*.gif;*.mp4;*.avi")])
    if file_path:
        file_path_var.set(file_path)
  • 使用 filedialog.askopenfilename 打開一個檔案選擇對話框,讓用戶選擇影像或影片檔案。
  • 文件類型限制為 .gif, .mp4, .avi,選擇的文件路徑會存儲在 file_path_var 變數中。

(2) 權重檔案選擇函數

def select_weight():
    weight_path = filedialog.askopenfilename(filetypes=[("Weight Files", "*.weights")])
    if weight_path:
        weight_path_var.set(weight_path)
  • 這個函數與檔案選擇函數類似,但它專門用於選擇 YOLO 模型的權重檔案,文件類型限制為 .weights

(3) 執行 YOLO 計算的函數

def perform_yolo():
    file_path = file_path_var.get()
    weight_path = weight_path_var.get()
    if not file_path or not weight_path:
        messagebox.showerror("Error", "Please select both file and weight paths.")
        return

    result_image_path = yolo_calculate(file_path, weight_path)
    load_image(result_image_path)
  • 這個函數會獲取用戶選擇的檔案路徑和權重檔案路徑,如果任何一項未選擇,會彈出錯誤訊息。
  • 如果路徑選擇完整,則會執行 yolo_calculate 函數進行 YOLO 計算,並將結果加載到 GUI 中顯示。

(4) 執行 LSTM 計算的函數

def perform_lstm():
    file_path = file_path_var.get()
    if not file_path:
        messagebox.showerror("Error", "Please select a file path.")
        return

    result = lstm_calculate(file_path)
    result_var.set(result)
  • 這個函數會獲取用戶選擇的檔案路徑,如果未選擇,會彈出錯誤訊息。
  • 如果路徑選擇完整,則會執行 lstm_calculate 函數進行 LSTM 計算,並將結果顯示在 GUI 中。

(5) 執行斑馬魚 YOLO v8 計算的函數

def perform_zebrafish_yolo_v8():
    video_path = file_path_var.get()
    if not video_path:
        messagebox.showerror("Error", "Please select a video path.")
        return

    result_video_path = zebrafish_yolo_v8(video_path)
    load_video(result_video_path)
  • 這個函數會獲取用戶選擇的影片檔案路徑,如果未選擇,會彈出錯誤訊息。
  • 如果路徑選擇完整,則會執行 zebrafish_yolo_v8 函數進行斑馬魚運動軌跡的計算,並將結果加載到 GUI 中顯示。

(6) 顯示斑馬魚行為佔比的函數

def show_behavior(behavior):
    video_path = file_path_var.get()
    if not video_path:
        messagebox.showerror("Error", "Please select a video path.")
        return

    behavior_data = analyze_zebrafish_behavior(video_path)
    behavior_percentage = behavior_data.get(behavior, 0)
    messagebox.showinfo(f"{behavior}行為佔比", f"{behavior

}行為佔比為 {behavior_percentage}%")
  • 這個函數會獲取用戶選擇的影片檔案路徑並分析斑馬魚的行為。
  • 如果未選擇路徑會彈出錯誤訊息,否則會執行 analyze_zebrafish_behavior 函數,並顯示指定行為的佔比。

4. 建立主視窗與配置

這些部分的代碼負責創建和配置 GUI 界面,讓用戶能夠與應用程式進行互動。

(1) 創建主視窗

root = tk.Tk()
root.title("YOLO 和 LSTM 圖形界面")
root.configure(bg='lightblue')  # 設定背景顏色為淺藍色
  • root 是應用程式的主視窗。這裡設置了窗口標題為 "YOLO 和 LSTM 圖形界面" 並且設置背景顏色為淺藍色。

(2) 配置主框架

file_path_var = tk.StringVar()
weight_path_var = tk.StringVar()
result_var = tk.StringVar()

frame = ttk.Frame(root, padding="10")
frame.grid(row=0, column=0, sticky="nsew")

root.grid_columnconfigure(0, weight=1)
root.grid_rowconfigure(0, weight=1)

frame.grid_columnconfigure(0, weight=1)
frame.grid_rowconfigure(0, weight=1)
  • file_path_varweight_path_varresult_var 是字符串變數,用來存儲檔案路徑、權重路徑和計算結果。
  • frame 是主框架,包含所有的 GUI 元件,並配置為可以隨視窗大小動態調整。

(3) 添加 GUI 元件

ttk.Label(frame, text="選擇影像/影片:").grid(row=0, column=0, padx=5, pady=5)
ttk.Entry(frame, textvariable=file_path_var).grid(row=0, column=1, padx=5, pady=5)
ttk.Button(frame, text="選擇檔案", command=select_file).grid(row=0, column=2, padx=5, pady=5)

ttk.Label(frame, text="選擇權重:").grid(row=1, column=0, padx=5, pady=5)
ttk.Entry(frame, textvariable=weight_path_var).grid(row=1, column=1, padx=5, pady=5)
ttk.Button(frame, text="選擇檔案", command=select_weight).grid(row=1, column=2, padx=5, pady=5)

ttk.Button(frame, text="執行 YOLO", command=perform_yolo).grid(row=2, column=0, padx=5, pady=5, columnspan=3, sticky="ew")
ttk.Button(frame, text="執行 LSTM", command=perform_lstm).grid(row=3, column=0, padx=5, pady=5, columnspan=3, sticky="ew")
ttk.Button(frame, text="執行斑馬魚 YOLO v8", command=perform_zebrafish_yolo_v8).grid(row=4, column=0, padx=5, pady=5, columnspan=3, sticky="ew")

ttk.Button(frame, text="顯示正常行為佔比", command=lambda: show_behavior("正常")).grid(row=5, column=0, padx=5, pady=5, sticky="ew")
ttk.Button(frame, text="顯示害怕行為佔比", command=lambda: show_behavior("害怕")).grid(row=5, column=1, padx=5, pady=5, sticky="ew")
ttk.Button(frame, text="顯示焦慮行為佔比", command=lambda: show_behavior("焦慮")).grid(row=5, column=2, padx=5, pady=5, sticky="ew")
ttk.Button(frame, text="顯示壓抑行為佔比", command=lambda: show_behavior("壓抑")).grid(row=6, column=0, padx=5, pady=5, sticky="ew")

result_label = ttk.Label(frame, textvariable=result_var)
result_label.grid(row=7, column=0, padx=5, pady=5, columnspan=3)
  • 添加了各種 Label, Entry, Button 元件,組成了一個完整的 GUI 介面。
  • 用戶可以通過這些元件來選擇檔案、權重、觸發不同的計算過程,並查看結果。

(4) 啟動應用程式主循環

root.mainloop()
  • 最後,使用 root.mainloop() 啟動應用程式的主事件循環,讓 GUI 能夠持續運行,並響應用戶操作。

這整個範例展示了如何使用 tkinter 創建一個完整的 GUI 應用程式來執行 YOLO 和 LSTM 計算,並處理斑馬魚的行為分析。


上一篇
day Lstm模型訓練完成成果圖
下一篇
Day 13 模型訓練
系列文
LSTM結合Yolo v8對於多隻斑馬魚行為分析30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言