增加了相似菜品预览功能,更完整了,交互更方便了。

This commit is contained in:
2025-09-29 18:03:28 +08:00
parent 1f04bb5c01
commit f3e3bd048a
4 changed files with 163 additions and 26 deletions
+142 -5
View File
@@ -61,7 +61,7 @@ class EmbeddingFoodClassifierApp:
"""加载训练好的embedding模型和FAISS索引"""
try:
# 模型路径
model_path = "../model/embedding_20250917_145342/best_embedding_model.pth"
model_path = "../model/embedding_20250929_151102/best_embedding_model.pth"
# FAISS索引目录
index_dir = "../faiss_vector_db/faiss_index"
@@ -744,11 +744,13 @@ class EmbeddingFoodClassifierApp:
# 保存图片路径
paths_path = os.path.join(index_dir, 'image_paths.pkl')
with open(paths_path, 'wb') as f:
# 重新写入图片路径
pickle.dump(self.image_paths, f)
# 保存标签
labels_path = os.path.join(index_dir, 'labels.pkl')
with open(labels_path, 'wb') as f:
# 重新写入标签
pickle.dump(self.labels, f)
# 更新类别信息
@@ -1309,18 +1311,153 @@ class EmbeddingFoodClassifierApp:
)
similar_label.pack(fill="x", padx=5, pady=(5, 2))
# 显示前3张最相似的图片信息
for j, sim_img in enumerate(similar_images[:3]):
# 显示前5张最相似的图片信息
for j, sim_img in enumerate(similar_images[:5]):
# 创建一个水平框架来放置信息和按钮
sim_frame = ctk.CTkFrame(info_frame)
sim_frame.pack(fill="x", padx=15, pady=1)
# 相似图片信息
sim_info = f" {j+1}. {sim_img['class']} (相似度: {sim_img['score']:.3f})"
sim_info_label = ctk.CTkLabel(
info_frame,
sim_frame,
text=sim_info,
anchor="w",
font=("Arial", 9),
text_color="gray"
)
sim_info_label.pack(fill="x", padx=15, pady=1)
sim_info_label.pack(side="left", fill="x", expand=True, padx=5, pady=2)
# 查看按钮(使用眼睛图标)
view_btn = ctk.CTkButton(
sim_frame,
text="👁", # 眼睛图标
width=25,
height=20,
font=("Arial", 12),
command=lambda path=sim_img['path']: self.show_similar_image(path),
fg_color="#2196F3",
hover_color="#1976D2",
corner_radius=10
)
view_btn.pack(side="right", padx=5, pady=2)
def show_similar_image(self, image_path):
"""显示相似图片的窗口"""
try:
# 创建新窗口
similar_window = ctk.CTkToplevel(self.root)
similar_window.title("相似图片查看")
similar_window.geometry("600x500")
similar_window.resizable(True, True)
# 设置窗口属性,确保在主窗口上方
similar_window.transient(self.root) # 设置为主窗口的子窗口
similar_window.grab_set() # 设置为模态窗口
similar_window.lift() # 提升到最前面
similar_window.focus_set() # 设置焦点
# 居中显示
similar_window.update_idletasks()
x = (similar_window.winfo_screenwidth() // 2) - (600 // 2)
y = (similar_window.winfo_screenheight() // 2) - (500 // 2)
similar_window.geometry(f"600x500+{x}+{y}")
# 主框架
main_frame = ctk.CTkFrame(similar_window)
main_frame.pack(fill="both", expand=True, padx=10, pady=10)
# 标题
title_label = ctk.CTkLabel(
main_frame,
text="相似图片详情",
font=("Arial", 16, "bold")
)
title_label.pack(pady=(10, 20))
# 图片路径信息
path_label = ctk.CTkLabel(
main_frame,
text=f"图片路径: {image_path}",
font=("Arial", 10),
text_color="gray",
wraplength=550
)
path_label.pack(pady=(0, 10))
# 图片显示框架
image_frame = ctk.CTkFrame(main_frame)
image_frame.pack(fill="both", expand=True, padx=10, pady=10)
# 加载并显示图片
try:
# 打开图片
pil_image = Image.open(image_path)
# 计算合适的显示尺寸
max_width, max_height = 500, 350
img_width, img_height = pil_image.size
# 计算缩放比例
scale = min(max_width / img_width, max_height / img_height, 1.0)
new_width = int(img_width * scale)
new_height = int(img_height * scale)
# 调整图片大小
pil_image = pil_image.resize((new_width, new_height), Image.Resampling.LANCZOS)
# 转换为CTk图片
ctk_image = ctk.CTkImage(
light_image=pil_image,
dark_image=pil_image,
size=(new_width, new_height)
)
# 显示图片
image_label = ctk.CTkLabel(
image_frame,
image=ctk_image,
text=""
)
image_label.pack(expand=True, pady=20)
# 图片信息
info_text = f"原始尺寸: {img_width} × {img_height}显示尺寸: {new_width} × {new_height}"
info_label = ctk.CTkLabel(
main_frame,
text=info_text,
font=("Arial", 9),
text_color="gray"
)
info_label.pack(pady=(0, 10))
except Exception as e:
error_label = ctk.CTkLabel(
image_frame,
text=f"无法加载图片: {str(e)}",
font=("Arial", 12),
text_color="red"
)
error_label.pack(expand=True)
# 关闭按钮
close_btn = ctk.CTkButton(
main_frame,
text="关闭",
width=100,
command=similar_window.destroy,
fg_color="#f44336",
hover_color="#da190b"
)
close_btn.pack(pady=(10, 10))
# 让窗口获得焦点
similar_window.focus()
similar_window.lift()
except Exception as e:
messagebox.showerror("错误", f"显示相似图片时出错: {str(e)}")
def update_stats(self):
"""更新统计信息"""
total_images = len(self.uploaded_images)