""" 全局配置 - 服务器版(192.168.77.249, ~/顾工交接/wzj) 模型/训练代码目录与框架根同级(旧 ~/wzj/wzj → 上级 ~/wzj;现 ~/顾工交接/wzj → 上级 ~/顾工交接)。 """ import os PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__)) # 框架根的上一级:模型目录(正在使用的模型_.../、20260415_.../)与之同级。 # 用 dirname(PROJECT_ROOT) 自适应,避免迁移路径后硬编码失效。 WZJ_ROOT = os.path.dirname(PROJECT_ROOT) # ==================== 模型路径 ==================== YOLO_MODEL_PATH = os.path.join(WZJ_ROOT, "20260415_球星卡和宝可梦模型数据处理和训练代码/yolov11n_card_seg01.onnx") DINOV2_MODEL_PATH = os.path.join(WZJ_ROOT, "正在使用的模型_3球星卡_1宝可梦/dinov2_base_retrieval_392_PokemonCN04") # 评级卡检测模型(YOLO26 card_v1,检测封装壳上的评级公司标签 PSA/BGS/CGC/SGC) # ultralytics 目录在框架树内,用 PROJECT_ROOT 相对路径(本地镜像 D:\顾工交接\wzj 与服务器 ~/wzj/wzj 都自洽) GRADING_MODEL_PATH = os.path.join(PROJECT_ROOT, "ultralytics/runs/detect/card_v1/weights/best.pt") # ==================== 数据目录 ==================== DATA_DIR = os.path.join(PROJECT_ROOT, "data") GALLERY_IMG_DIR = os.path.join(DATA_DIR, "gallery_images") QUERY_IMG_DIR = os.path.join(DATA_DIR, "query_images") GALLERY_FEATURES_PATH = os.path.join(DATA_DIR, "gallery_features.npy") GALLERY_META_PATH = os.path.join(DATA_DIR, "gallery_meta.json") RESULT_PATH = os.path.join(DATA_DIR, "match_results.json") # CSV 数据源(服务器读不了PG/CH,从本地导出CSV传入) CARD_MASTER_CSV = os.path.join(DATA_DIR, "card_master.csv") TRANSACTIONS_CSV = os.path.join(DATA_DIR, "transactions.csv") # ==================== 数据库配置(服务器网络隔离,暂不可用,留作参考)==================== PG_CONFIG = { "host": "100.64.0.10", "port": 25432, "user": "readonlyuser", "password": "Pass2026", "database": "hs_sync_data", } PG_TABLE = "public.cards_master_v2" CLICKHOUSE_CONFIG = { "host": "192.168.31.233", "port": 8123, "username": "card_transactions_ro", "password": "CardTxReadOnly2026!", "database": "card_transactions", } CLICKHOUSE_TABLE = "card_transactions_unified_sync" # ==================== MinIO(交易图,已验证凭据)==================== MINIO_CONFIG = { "endpoint": "127.0.0.1:9000", # 服务器本地访问 "access_key": "minioadmin", "secret_key": "minioadmin", "secure": False, "bucket": "reverse.search", } # C 端 /match_fields 拍摄图落盘(249 MinIO grading 桶,与树莓派同源凭据; # SDK 走本机 127.0.0.1,对外回显用 public_base) CAPP_MINIO = { "endpoint": "127.0.0.1:9000", "public_base": "http://192.168.77.249:9000", "access_key": "pZEwCGnpNN05KPnmC2Yh", "secret_key": "KfJRuWiv9pVxhIMcFqbkv8hZT9SnNTZ6LPx592D4", "secure": False, "bucket": "grading", "prefix": "capp_img_data", } # ==================== 模型参数 ==================== YOLO_CONF_THRESHOLD = 0.25 YOLO_IMG_SIZE = 640 DINOV2_FEATURE_DIM = 768 GRADING_CONF_THRESHOLD = 0.25 # 评级公司标签检测置信度 GRADING_IMG_SIZE = 640 # ==================== 检索参数 ==================== TOP_K = 5 SIMILARITY_THRESHOLD = 0.50 # 100张人工核验:sim>=0.50 几乎无误,定为高/低置信界限(2026-09-02从0.60同步158生产值) GALLERY_FILTER = None DOWNLOAD_WORKERS = 16 FEATURE_BATCH_SIZE = 32 def ensure_dirs(): for d in [DATA_DIR, GALLERY_IMG_DIR, QUERY_IMG_DIR]: os.makedirs(d, exist_ok=True) # ===== 双区级联(2026-08 从本地同步追加,供 cascade_match / 生产入库)===== CARD_CROP_MODE = os.environ.get("CARD_CROP_MODE", "seg_warp") CARD_SEG_MODEL_PATH = os.path.join(PROJECT_ROOT, "ultralytics/runs/segment/card_seg_pn_v2/weights/best.pt") YOLO_MODEL_PATH_LEGACY = YOLO_MODEL_PATH # 保留旧 A4 onnx 路径 # 查询侧默认走 card_seg_v2;旧 serve 若依赖 YOLO_MODEL_PATH=onnx 请用 CARD_CROP_MODE=bbox_legacy if CARD_CROP_MODE == "seg_warp" and os.path.exists(CARD_SEG_MODEL_PATH): YOLO_MODEL_PATH = CARD_SEG_MODEL_PATH UPPER_MODEL_PATH = os.path.join(PROJECT_ROOT, "upper_model_output_v0904/best_upper_half_model.pth") LOWER_MODEL_PATH = os.path.join(PROJECT_ROOT, "layer3_bg_model_output_v0904/best_layer3_bottom_model.pth") UPPER_HALF_CROPS_DIR = os.path.join(PROJECT_ROOT, "_upper_half_crops") GALLERY_UPPER_FEATURES_PATH = os.path.join(DATA_DIR, "gallery_v0904/gallery_upper_features.npy") GALLERY_LOWER_FEATURES_PATH = os.path.join(DATA_DIR, "gallery_v0904/gallery_lower_features.npy") GALLERY_DUAL_META_PATH = os.path.join(DATA_DIR, "gallery_v0904/gallery_dual_meta.json") CARD_MASTER_ALL_CSV = os.path.join(DATA_DIR, "card_master_all.csv") DUAL_FEATURE_DIM = 1024 CASCADE_TOP_K_RECALL = 30 CASCADE_ALPHA = 0.5 CASCADE_BACKEND = "gpu" # 2026-09-03 切 GPU 常驻图库召回(bench Top-5 与 milvus 全等,40ms→0.4ms/卡);回滚改回 milvus # 249 默认走本机 Milvus 双区库 MILVUS_HOST = "127.0.0.1" MILVUS_PORT = "19530" MILVUS_UPPER_COLLECTION = "pokemon_dual_upper_dinov2l_1024" MILVUS_LOWER_COLLECTION = "pokemon_dual_lower_dinov2l_1024" # ==================== 8020 生产接口(serve_card_match_v2)排队/缓存 ==================== # 全部支持环境变量覆盖;本地调试与 249 生产用同一套默认值 V2_QUEUE_SIZE = int(os.environ.get("V2_QUEUE_SIZE", "32")) # 任务队列上限,满即 429 V2_WORKERS = int(os.environ.get("V2_WORKERS", "0")) # 推理 worker 数;0=自动(=可见GPU数,至少1);>GPU数=每卡多worker(压测后再开) V2_WAIT_TIMEOUT = float(os.environ.get("V2_WAIT_TIMEOUT", "60")) # handler 等结果超时(秒),超时 504 V2_CACHE_MAX = int(os.environ.get("V2_CACHE_MAX", "256")) # 内容 md5 → 结果缓存条数(LRU) V2_CACHE_TTL = float(os.environ.get("V2_CACHE_TTL", "900")) # 缓存 TTL(秒) V2_MAX_CONTENT_MB = int(os.environ.get("V2_MAX_CONTENT_MB", "20")) # 上传图大小上限(MB) # ==================== 卡牌分割近距 mask 合并(yolo_detector.detect_and_crop_all)==================== # 两实例中心(mask 质心,回退 bbox 中心)距离 <= CARD_MERGE_DIST_PX 视为同一张卡的重复分割, # 保留 conf 高者;CARD_MERGE_DIST_PX<=0 关闭合并。 # CARD_MERGE_MIN_IOU:可选 IoU 门槛(>0 启用:距离近且 IoU 达标才合并,防误杀紧贴的不同卡); # 0 = 纯距离口径(默认,与 8020 接口定稿一致)。 CARD_MERGE_DIST_PX = float(os.environ.get("CARD_MERGE_DIST_PX", "50")) CARD_MERGE_MIN_IOU = float(os.environ.get("CARD_MERGE_MIN_IOU", "0"))