diff --git a/classifier/embedding_food_classifier_app.py b/classifier/embedding_food_classifier_app.py index fe868a0..617594c 100644 --- a/classifier/embedding_food_classifier_app.py +++ b/classifier/embedding_food_classifier_app.py @@ -109,6 +109,34 @@ class EmbeddingFoodClassifierApp: paths_path = os.path.join(index_dir, 'image_paths.pkl') with open(paths_path, 'rb') as f: self.image_paths = pickle.load(f) + # 兼容 python -m:将相对路径规范为绝对路径(基于项目根目录) + PROJECT_ROOT = os.path.abspath(os.path.join(BASE_DIR, "..")) + INDEX_DIR = index_dir + def _resolve_path(p): + # 若已是绝对路径且存在 + if os.path.isabs(p) and os.path.exists(p): + return p + # 统一规范相对路径 + rp = os.path.normpath(p) + candidates = [ + os.path.abspath(os.path.join(PROJECT_ROOT, rp)), + os.path.abspath(os.path.join(BASE_DIR, rp)), + os.path.abspath(os.path.join(INDEX_DIR, rp)), + ] + # 特殊修正:如果路径误指向 PythonProjects\\dataset,尝试插入 FoodClassifier + try: + proj_root_parent = os.path.dirname(PROJECT_ROOT) + fixed = rp.replace(os.path.join("PythonProjects", "dataset"), + os.path.join("PythonProjects", "FoodClassifier", "dataset")) + candidates.append(os.path.abspath(os.path.join(proj_root_parent, fixed))) + except Exception: + pass + for c in candidates: + if os.path.exists(c): + return c + # 找不到就退回 PROJECT_ROOT 拼接的绝对路径 + return os.path.abspath(os.path.join(PROJECT_ROOT, rp)) + self.image_paths = [_resolve_path(p) for p in self.image_paths] # 加载标签映射,就是一个list,一张张图片的分类,不过是0,1,2,3,4这种 labels_path = os.path.join(index_dir, 'labels.pkl') @@ -748,10 +776,18 @@ class EmbeddingFoodClassifierApp: faiss.write_index(self.faiss_index, index_path) # 保存图片路径 + # 保存图片路径(统一存为绝对路径,避免工作目录变化带来的问题) + PROJECT_ROOT = os.path.abspath(os.path.join(BASE_DIR, "..")) + abs_image_paths = [] + for p in self.image_paths: + if not os.path.isabs(p): + abs_image_paths.append(os.path.abspath(os.path.join(PROJECT_ROOT, p))) + else: + abs_image_paths.append(p) paths_path = os.path.join(index_dir, 'image_paths.pkl') with open(paths_path, 'wb') as f: - # 重新写入图片路径 - pickle.dump(self.image_paths, f) + # 重新写入图片路径(绝对路径) + pickle.dump(abs_image_paths, f) # 保存标签 labels_path = os.path.join(index_dir, 'labels.pkl') @@ -1396,28 +1432,28 @@ class EmbeddingFoodClassifierApp: # 加载并显示图片 try: - # 打开图片 - pil_image = Image.open(image_path) - + # 加载图片(兼容中文路径) + cv_img = self.load_image_with_chinese_path(image_path) + if cv_img is None: + raise FileNotFoundError(f"无法读取图片,路径可能不存在或不可访问: {image_path}") + # 转为 PIL 并缩放 + image_rgb = cv2.cvtColor(cv_img, cv2.COLOR_BGR2RGB) + pil_image = Image.fromarray(image_rgb) # 计算合适的显示尺寸 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, @@ -1425,9 +1461,8 @@ class EmbeddingFoodClassifierApp: text="" ) image_label.pack(expand=True, pady=20) - # 图片信息 - info_text = f"原始尺寸: {img_width} × {img_height}显示尺寸: {new_width} × {new_height}" + info_text = f"原始尺寸: {img_width} × {img_height} 显示尺寸: {new_width} × {new_height}" info_label = ctk.CTkLabel( main_frame, text=info_text,