Spaces:
Runtime error
Runtime error
| import torch | |
| import torch.nn as nn | |
| import json | |
| import cv2 | |
| import numpy as np | |
| from PIL import Image | |
| import google.generativeai as genai | |
| from typing import Dict, List, Tuple, Optional | |
| import logging | |
| from transformers import CLIPProcessor, CLIPModel | |
| import easyocr | |
| from sentence_transformers import SentenceTransformer | |
| import faiss | |
| import os | |
| logger = logging.getLogger(__name__) | |
| class VietMEAgent: | |
| """ | |
| VietMEAgent: Culturally-Aware Few-Shot Multimodal Explanation | |
| for Vietnamese Visual Question Answering - FIXED CULTURAL DETECTION | |
| """ | |
| def __init__(self, config_path: str = "configs/vietmeagent_config.json"): | |
| self.config = self.load_config(config_path) | |
| self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu") | |
| # Initialize components | |
| self.setup_models() | |
| self.load_cultural_knowledge() | |
| self.setup_few_shot_examples() | |
| logger.info(f"VietMEAgent initialized on {self.device}") | |
| def load_config(self, config_path: str) -> Dict: | |
| """Load VietMEAgent configuration""" | |
| try: | |
| with open(config_path, 'r', encoding='utf-8') as f: | |
| config = json.load(f) | |
| # Flatten nested config for backward compatibility | |
| flat_config = {} | |
| # Extract model_config keys to top level | |
| if 'model_config' in config: | |
| flat_config.update(config['model_config']) | |
| # Add other sections | |
| for section, values in config.items(): | |
| if section != 'model_config' and isinstance(values, dict): | |
| flat_config[section] = values | |
| elif section != 'model_config': | |
| flat_config[section] = values | |
| # Override with environment variables if available | |
| if os.getenv('GEMINI_API_KEY'): | |
| flat_config['gemini_api_key'] = os.getenv('GEMINI_API_KEY') | |
| if os.getenv('CULTURAL_THRESHOLD'): | |
| flat_config['cultural_threshold'] = float(os.getenv('CULTURAL_THRESHOLD')) | |
| if os.getenv('MAX_FEW_SHOT_EXAMPLES'): | |
| flat_config['max_few_shot_examples'] = int(os.getenv('MAX_FEW_SHOT_EXAMPLES')) | |
| return flat_config | |
| except FileNotFoundError: | |
| # Default config if file not found - use environment variables first | |
| default_config = { | |
| "gemini_api_key": os.getenv('GEMINI_API_KEY', "AIzaSyCgatP7izHkaBn6im8AfXq0Ufmb0Fr-7dc"), | |
| "max_few_shot_examples": int(os.getenv('MAX_FEW_SHOT_EXAMPLES', 16)), | |
| "cultural_threshold": float(os.getenv('CULTURAL_THRESHOLD', 0.15)), | |
| "explanation_max_length": 200, | |
| "heatmap_resolution": (224, 224), | |
| "paths": { | |
| "cultural_kb": os.getenv('CULTURAL_KB_PATH', "data/cultural_kb/vietnamese_cultural_knowledge.json"), | |
| "vqa_dataset": os.getenv('VQA_DATASET_PATH', "data/annotations/vietnamese_vqa_dataset.json"), | |
| "output_dir": os.getenv('OUTPUT_DIR', "results") | |
| } | |
| } | |
| return default_config | |
| def setup_models(self): | |
| """Initialize all required models""" | |
| logger.info("Setting up models...") | |
| # 1. Gemini for LLM reasoning | |
| genai.configure(api_key=self.config["gemini_api_key"]) | |
| self.llm_model = genai.GenerativeModel('gemini-1.5-flash') | |
| # 2. CLIP for vision-language understanding | |
| logger.info("Loading CLIP model...") | |
| self.clip_processor = CLIPProcessor.from_pretrained("openai/clip-vit-base-patch32") | |
| self.clip_model = CLIPModel.from_pretrained("openai/clip-vit-base-patch32").to(self.device) | |
| # 3. Vietnamese OCR | |
| logger.info("Setting up Vietnamese OCR...") | |
| self.ocr_reader = easyocr.Reader(['vi', 'en'], gpu=torch.cuda.is_available()) | |
| # 4. Sentence encoder for cultural similarity | |
| logger.info("Loading sentence encoder...") | |
| self.sentence_encoder = SentenceTransformer('paraphrase-multilingual-MiniLM-L12-v2') | |
| # 5. Cultural object detector (using CLIP for now) | |
| logger.info("Setting up cultural object detector...") | |
| self.cultural_detector = CulturalObjectDetector( | |
| self.clip_model, self.clip_processor, self.device | |
| ) | |
| logger.info("All models loaded successfully!") | |
| def load_cultural_knowledge(self): | |
| """Load Vietnamese cultural knowledge base""" | |
| kb_path = self.config["paths"]["cultural_kb"] | |
| with open(kb_path, 'r', encoding='utf-8') as f: | |
| self.cultural_kb = json.load(f) | |
| # Create cultural embeddings for fast retrieval | |
| self.create_cultural_embeddings() | |
| logger.info(f"Cultural KB loaded with {len(self.cultural_kb['objects'])} objects") | |
| def create_cultural_embeddings(self): | |
| """Create embeddings for cultural objects for fast similarity search""" | |
| cultural_texts = [] | |
| self.cultural_objects = [] | |
| for obj_name, obj_data in self.cultural_kb['objects'].items(): | |
| text = f"{obj_name} {obj_data['description']} {obj_data['cultural_significance']}" | |
| cultural_texts.append(text) | |
| self.cultural_objects.append(obj_name) | |
| # Create embeddings | |
| embeddings = self.sentence_encoder.encode(cultural_texts) | |
| # Build FAISS index for fast retrieval | |
| self.cultural_index = faiss.IndexFlatIP(embeddings.shape[1]) | |
| self.cultural_index.add(embeddings.astype('float32')) | |
| logger.info("Cultural embeddings created") | |
| def setup_few_shot_examples(self): | |
| """Load few-shot examples from VQA dataset""" | |
| vqa_path = self.config["paths"]["vqa_dataset"] | |
| with open(vqa_path, 'r', encoding='utf-8') as f: | |
| vqa_data = json.load(f) | |
| # Select diverse examples across categories | |
| self.few_shot_examples = self.select_diverse_examples( | |
| vqa_data, k=self.config["max_few_shot_examples"] | |
| ) | |
| logger.info(f"Selected {len(self.few_shot_examples)} few-shot examples") | |
| def select_diverse_examples(self, vqa_data: List[Dict], k: int = 16) -> List[Dict]: | |
| """Select diverse examples across categories for few-shot learning""" | |
| examples_by_category = {} | |
| for item in vqa_data: | |
| category = item.get('category', 'unknown') | |
| if category not in examples_by_category: | |
| examples_by_category[category] = [] | |
| examples_by_category[category].append(item) | |
| # Select examples from each category | |
| selected_examples = [] | |
| examples_per_category = max(1, k // len(examples_by_category)) | |
| for category, examples in examples_by_category.items(): | |
| # Sort by quality (number of questions) and select best | |
| examples.sort(key=lambda x: len(x.get('questions', [])), reverse=True) | |
| selected_examples.extend(examples[:examples_per_category]) | |
| return selected_examples[:k] | |
| def process_image(self, image_path: str) -> Dict: | |
| """Process image through complete VietMEAgent pipeline""" | |
| logger.info(f"Processing image: {image_path}") | |
| # Load image | |
| if isinstance(image_path, str): | |
| image = Image.open(image_path).convert('RGB') | |
| else: | |
| # Handle numpy array input | |
| image = Image.fromarray((image_path * 255).astype(np.uint8)).convert('RGB') | |
| # 1. Extract Vietnamese text | |
| vietnamese_text = self.extract_vietnamese_text(image) | |
| # 2. Detect cultural objects - IMPROVED | |
| cultural_objects = self.cultural_detector.detect_objects(image) | |
| logger.info(f"Detected cultural objects: {cultural_objects}") | |
| # 3. Retrieve cultural context | |
| cultural_context = self.retrieve_cultural_context(cultural_objects + vietnamese_text) | |
| # 4. Generate program and explanation | |
| result = { | |
| "image_path": image_path if isinstance(image_path, str) else "processed_array", | |
| "vietnamese_text": vietnamese_text, | |
| "cultural_objects": cultural_objects, | |
| "cultural_context": cultural_context, | |
| "processed_successfully": True | |
| } | |
| return result | |
| def extract_vietnamese_text(self, image: Image.Image) -> List[str]: | |
| """Extract Vietnamese text from image using OCR""" | |
| try: | |
| # Convert PIL to cv2 format | |
| img_cv = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR) | |
| # Run OCR | |
| results = self.ocr_reader.readtext(img_cv) | |
| # Extract Vietnamese text | |
| vietnamese_texts = [] | |
| for (bbox, text, confidence) in results: | |
| if confidence > 0.5: # Filter low-confidence detections | |
| vietnamese_texts.append(text) | |
| return vietnamese_texts | |
| except Exception as e: | |
| logger.warning(f"OCR extraction failed: {e}") | |
| return [] | |
| def retrieve_cultural_context(self, detected_items: List[str]) -> Dict: | |
| """Retrieve cultural context for detected items""" | |
| if not detected_items: | |
| return {} | |
| # Create query from detected items | |
| query_text = " ".join(detected_items) | |
| query_embedding = self.sentence_encoder.encode([query_text]) | |
| # Search in cultural knowledge base | |
| k = min(5, len(self.cultural_objects)) | |
| scores, indices = self.cultural_index.search(query_embedding.astype('float32'), k) | |
| # Retrieve relevant cultural information | |
| cultural_context = {} | |
| for score, idx in zip(scores[0], indices[0]): | |
| if score > self.config["cultural_threshold"]: | |
| obj_name = self.cultural_objects[idx] | |
| cultural_context[obj_name] = self.cultural_kb['objects'][obj_name] | |
| return cultural_context | |
| def generate_vietnamese_vqa(self, image_path: str, question: str = None) -> Dict: | |
| """Generate Vietnamese VQA with cultural explanation""" | |
| logger.info(f"Generating VQA for: {image_path}") | |
| # Process image | |
| image_analysis = self.process_image(image_path) | |
| # Load image for Gemini | |
| if isinstance(image_path, str): | |
| image = Image.open(image_path) | |
| else: | |
| image = Image.fromarray((image_path * 255).astype(np.uint8)).convert('RGB') | |
| # Create culturally-aware prompt | |
| prompt = self.create_cultural_prompt(image_analysis, question) | |
| try: | |
| # Generate with Gemini | |
| response = self.llm_model.generate_content([prompt, image]) | |
| # Parse response | |
| vqa_result = self.parse_vqa_response(response.text) | |
| # Add metadata | |
| vqa_result.update({ | |
| "image_analysis": image_analysis, | |
| "cultural_awareness": True, | |
| "processing_success": True | |
| }) | |
| return vqa_result | |
| except Exception as e: | |
| logger.error(f"VQA generation failed: {e}") | |
| return {"error": str(e), "processing_success": False} | |
| def create_cultural_prompt(self, image_analysis: Dict, question: str = None) -> str: | |
| """Create culturally-aware prompt for VQA generation""" | |
| prompt = f""" | |
| Bạn là chuyên gia về văn hóa Việt Nam. Hãy phân tích hình ảnh này và tạo câu hỏi-trả lời bằng tiếng Việt. | |
| THÔNG TIN PHÂN TÍCH: | |
| - Text trong ảnh: {', '.join(image_analysis.get('vietnamese_text', []))} | |
| - Đối tượng văn hóa: {', '.join(image_analysis.get('cultural_objects', []))} | |
| BỐI CẢNH VĂN HÓA: | |
| """ | |
| # Add cultural context | |
| for obj_name, obj_data in image_analysis.get('cultural_context', {}).items(): | |
| prompt += f"- {obj_name}: {obj_data.get('cultural_significance', '')}\n" | |
| prompt += f""" | |
| YÊU CẦU: | |
| 1. Tạo 2-3 câu hỏi về văn hóa Việt Nam (nếu không có câu hỏi cụ thể) | |
| 2. Câu trả lời phải chính xác và có giải thích văn hóa | |
| 3. Giải thích phải bao gồm ý nghĩa, nguồn gốc, cách sử dụng | |
| """ | |
| if question: | |
| prompt += f"CÂU HỎI CỤ THỂ: {question}\n" | |
| prompt += """ | |
| FORMAT JSON: | |
| { | |
| "questions": [ | |
| { | |
| "question": "Câu hỏi", | |
| "answer": "Câu trả lời", | |
| "explanation": "Giải thích có bối cảnh văn hóa", | |
| "cultural_objects": ["đối tượng 1", "đối tượng 2"], | |
| "confidence": 0.9 | |
| } | |
| ] | |
| } | |
| """ | |
| return prompt | |
| def parse_vqa_response(self, response_text: str) -> Dict: | |
| """Parse VQA response from Gemini""" | |
| try: | |
| # Try to extract JSON | |
| start_idx = response_text.find('{') | |
| end_idx = response_text.rfind('}') + 1 | |
| if start_idx != -1 and end_idx != -1: | |
| json_str = response_text[start_idx:end_idx] | |
| return json.loads(json_str) | |
| else: | |
| # Fallback parsing | |
| return self.fallback_parse_response(response_text) | |
| except json.JSONDecodeError: | |
| return self.fallback_parse_response(response_text) | |
| def fallback_parse_response(self, text: str) -> Dict: | |
| """Fallback parser for non-JSON responses""" | |
| lines = text.split('\n') | |
| result = {"questions": []} | |
| current_q = {"question": "", "answer": "", "explanation": "", "cultural_objects": []} | |
| for line in lines: | |
| line = line.strip() | |
| if 'question' in line.lower() or 'câu hỏi' in line.lower(): | |
| if ':' in line: | |
| current_q["question"] = line.split(':', 1)[1].strip() | |
| elif 'answer' in line.lower() or 'trả lời' in line.lower(): | |
| if ':' in line: | |
| current_q["answer"] = line.split(':', 1)[1].strip() | |
| elif 'explanation' in line.lower() or 'giải thích' in line.lower(): | |
| if ':' in line: | |
| current_q["explanation"] = line.split(':', 1)[1].strip() | |
| # If we have all required fields, add to results | |
| if all([current_q["question"], current_q["answer"], current_q["explanation"]]): | |
| current_q["confidence"] = 0.7 # Default confidence for fallback | |
| result["questions"].append(current_q.copy()) | |
| current_q = {"question": "", "answer": "", "explanation": "", "cultural_objects": []} | |
| return result | |
| def save_results(self, results: List[Dict], output_path: str): | |
| """Save VietMEAgent results""" | |
| with open(output_path, 'w', encoding='utf-8') as f: | |
| json.dump(results, f, ensure_ascii=False, indent=2) | |
| logger.info(f"Results saved to {output_path}") | |
| class CulturalObjectDetector: | |
| """Detect Vietnamese cultural objects using CLIP - FIXED VERSION""" | |
| def __init__(self, clip_model, clip_processor, device): | |
| self.clip_model = clip_model | |
| self.clip_processor = clip_processor | |
| self.device = device | |
| # Load cultural object vocabulary - EXPANDED & BILINGUAL | |
| self.cultural_vocabulary = self.load_cultural_vocabulary() | |
| logger.info(f"Cultural detector initialized with {len(self.cultural_vocabulary)} objects") | |
| def load_cultural_vocabulary(self) -> List[str]: | |
| """Load vocabulary of Vietnamese cultural objects - COMPREHENSIVE FROM CRAWL DATA""" | |
| # English-Vietnamese pairs based on crawl_summary.json (12 categories, 507 keywords) | |
| vocabulary_pairs = [ | |
| # ===== 1. ÂM THỰC (FOOD) ===== | |
| ("vietnamese pho soup", "phở"), | |
| ("vietnamese banh mi sandwich", "bánh mì"), | |
| ("vietnamese spring rolls", "gỏi cuốn"), | |
| ("vietnamese pancake", "bánh xèo"), | |
| ("sticky rice", "xôi"), | |
| ("vietnamese coffee", "cà phê"), | |
| ("vietnamese tea", "chè"), | |
| ("rice paper", "bánh tráng"), | |
| ("fish sauce", "nước mắm"), | |
| ("hue beef noodle soup", "bún bò Huế"), | |
| ("vietnamese sticky rice cake", "bánh chưng"), | |
| ("broken rice", "cơm tấm"), | |
| ("cao lau noodles", "cao lầu"), | |
| ("mi quang noodles", "mì Quảng"), | |
| ("hanoi grilled pork noodles", "bún chả"), | |
| ("steamed rice rolls", "bánh cuốn"), | |
| ("cha ca fish", "chả cá"), | |
| ("grilled pork skewers", "nem nướng"), | |
| ("vietnamese steamed buns", "bánh bao"), | |
| ("red sticky rice", "xôi gấc"), | |
| ("vietnamese flan", "bánh flan"), | |
| ("grilled rice paper", "bánh tráng nướng"), | |
| ("vietnamese filter coffee", "cà phê phin"), | |
| ("phan thiet pancakes", "bánh căn"), | |
| ("grilled pork vermicelli", "bún thịt nướng"), | |
| ("mini pancakes", "bánh khọt"), | |
| ("pork offal porridge", "cháo lòng"), | |
| ("tapioca dumplings", "bánh bột lọc"), | |
| ("small dumplings", "bánh ít"), | |
| ("cylindrical sticky rice cake", "bánh tét"), | |
| ("pounded rice cake", "bánh chày"), | |
| ("hue imperial rice", "cơm âm phủ"), | |
| ("fermented shrimp paste", "mắm ruốc"), | |
| ("phu quoc fish sauce", "nước mắm Phú Quốc"), | |
| ("chili sauce", "tương ớt"), | |
| ("mung bean cake", "bánh đậu xanh"), | |
| ("durian cake", "bánh pía"), | |
| ("ben tre coconut candy", "kẹo dừa Bến Tre"), | |
| ("tet jam", "mứt Tết"), | |
| ("molded cake", "bánh in"), | |
| ("pyramid dumpling", "bánh giò"), | |
| ("black sticky rice cake", "bánh gai"), | |
| ("fried doughnut", "bánh rán"), | |
| ("hung yen cinnamon sausage", "chả quế Hưng Yên"), | |
| ("fermented pork roll", "nem chua"), | |
| ("dried shrimp", "tôm khô"), | |
| ("shrimp paste", "mắm tôm"), | |
| ("fish porridge", "cháo cá"), | |
| ("sour soup", "canh chua"), | |
| ("grilled chicken", "gà nướng"), | |
| ("roasted duck", "vịt quay"), | |
| ("vietnamese ham", "chả lụa"), | |
| ("pork head cheese", "giò thủ"), | |
| ("special sticky rice cake", "bánh chưng gù"), | |
| ("rice cake", "bánh dày"), | |
| # ===== 2. KIẾN TRÚC (ARCHITECTURE) ===== | |
| ("vietnamese temple", "chùa"), | |
| ("vietnamese pagoda", "chùa"), | |
| ("village communal house", "đình làng"), | |
| ("stilt house", "nhà sàn"), | |
| ("hanoi flag tower", "cột cờ Hà Nội"), | |
| ("one pillar pagoda", "chùa Một Cột"), | |
| ("tran quoc pagoda", "chùa Trấn Quốc"), | |
| ("temple of literature", "Văn Miếu"), | |
| ("ho chi minh mausoleum", "lăng Hồ Chí Minh"), | |
| ("dragon house", "nhà rồng"), | |
| ("ba den temple", "chùa Bà Đen"), | |
| ("ngoc son temple", "đền Ngọc Sơn"), | |
| ("hanoi old quarter", "phố cổ Hà Nội"), | |
| ("hue imperial architecture", "kiến trúc Huế"), | |
| ("an dinh palace", "cung An Định"), | |
| ("independence palace", "dinh Độc Lập"), | |
| ("dong xuan market", "chợ Đồng Xuân"), | |
| ("japanese covered bridge", "cầu Nhật Bản"), | |
| ("hoi an ancient house", "nhà cổ Hội An"), | |
| ("terraced fields architecture", "ruộng bậc thang"), | |
| ("notre dame cathedral", "nhà thờ Đức Bà"), | |
| ("saigon post office", "bưu điện Sài Gòn"), | |
| ("hanoi opera house", "nhà hát Lớn Hà Nội"), | |
| ("long bien bridge", "cầu Long Biên"), | |
| ("thang long imperial citadel", "hoàng thành Thăng Long"), | |
| ("hue imperial city", "kinh thành Huế"), | |
| ("khai dinh tomb", "lăng Khải Định"), | |
| ("minh mang tomb", "lăng Minh Mạng"), | |
| ("bai dinh pagoda", "chùa Bái Đính"), | |
| ("tam chuc pagoda", "chùa Tam Chúc"), | |
| ("hung kings temple", "đền Hùng"), | |
| ("bach ma temple", "đền Bạch Mã"), | |
| ("hanoi citadel gate", "cổng thành Hà Nội"), | |
| ("turtle tower", "tháp Rùa"), | |
| ("the huc bridge", "cầu Thê Húc"), | |
| ("ho chi minh house", "nhà Bác Hồ"), | |
| ("presidential palace", "phủ Chủ tịch"), | |
| ("ba dinh square", "quảng trường Ba Đình"), | |
| ("tu duc tomb", "lăng Tự Đức"), | |
| ("jade emperor pagoda", "chùa Ngọc Hoàng"), | |
| ("cao dai temple", "chùa Cao Đài"), | |
| ("hmong stilt house", "nhà sàn H'Mông"), | |
| ("ede longhouse", "nhà dài Ê Đê"), | |
| ("mekong traditional house", "nhà truyền thống miền Tây"), | |
| ("hue garden house", "nhà vườn Huế"), | |
| ("french villa", "biệt thự Pháp"), | |
| ("gothic architecture", "kiến trúc Gothic"), | |
| # ===== 3. TRANG PHỤC (CLOTHING) ===== | |
| ("vietnamese traditional dress", "áo dài"), | |
| ("conical hat", "nón lá"), | |
| ("vietnamese traditional clothing", "trang phục truyền thống"), | |
| ("ethnic costume", "trang phục dân tộc"), | |
| ("vietnamese traditional shirt", "áo bà ba"), | |
| ("thai headscarf", "khăn piêu"), | |
| ("hmong traditional costume", "trang phục H'Mông"), | |
| ("hue brocade dress", "áo gấm Huế"), | |
| ("hue turban", "khăn đóng Huế"), | |
| ("wooden shoes", "giày gỗ"), | |
| ("four-panel dress", "áo tứ thân"), | |
| ("traditional bra", "yếm đào"), | |
| ("wedding ao dai", "áo dài cưới"), | |
| ("chin strap hat", "nón quai thao"), | |
| ("brocade fabric", "thổ cẩm"), | |
| ("silk scarf", "khăn lụa"), | |
| ("mens ao dai", "áo dài nam"), | |
| ("childrens ao dai", "áo dài trẻ em"), | |
| ("student ao dai", "áo dài học sinh"), | |
| ("modern ao dai", "áo dài cách tân"), | |
| ("hue conical hat", "nón lá Huế"), | |
| ("poem hat", "nón bài thơ"), | |
| ("southern checkered scarf", "khăn rằn Nam Bộ"), | |
| ("traditional halter top", "áo yếm truyền thống"), | |
| ("tay traditional costume", "trang phục Tày"), | |
| ("nung traditional costume", "trang phục Nùng"), | |
| ("muong traditional costume", "trang phục Mường"), | |
| ("khmer traditional costume", "trang phục Khmer"), | |
| ("cham traditional costume", "trang phục Chăm"), | |
| ("cham sarong", "sarong Chăm"), | |
| ("cham turban", "turban Chăm"), | |
| ("ede traditional costume", "trang phục Ê Đê"), | |
| ("co tu traditional costume", "trang phục Cơ Tu"), | |
| ("dao traditional costume", "trang phục Dao"), | |
| ("giay traditional costume", "trang phục Giáy"), | |
| ("la chi traditional costume", "trang phục La Chí"), | |
| ("brocade skirt", "váy thổ cẩm"), | |
| ("brocade headscarf", "khăn thổ cẩm"), | |
| ("brocade bag", "túi thổ cẩm"), | |
| ("silver bracelet", "vòng tay bạc"), | |
| ("silver necklace", "dây chuyền bạc"), | |
| ("ethnic earrings", "khuyên tai dân tộc"), | |
| ("hmong collar", "vòng cổ H'Mông"), | |
| ("brocade belt", "thắt lưng thổ cẩm"), | |
| # ===== 4. LỄ HỘI (FESTIVALS) ===== | |
| ("vietnamese new year", "Tết Nguyên Đán"), | |
| ("cherry blossom festival", "lễ hội hoa anh đào"), | |
| ("mid autumn festival", "Trung thu"), | |
| ("hung kings festival", "lễ hội đền Hùng"), | |
| ("hue festival", "festival Huế"), | |
| ("perfume pagoda festival", "lễ hội chùa Hương"), | |
| ("kate festival", "Kate festival"), | |
| ("whale worship festival", "lễ hội cầu ngư"), | |
| ("buffalo fighting festival", "lễ hội chọi trâu"), | |
| ("sticky rice cake festival", "lễ hội bánh chưng"), | |
| ("giong festival", "Gióng festival"), | |
| ("village festival", "lễ hội làng"), | |
| ("vietnamese wedding", "đám cưới Việt Nam"), | |
| ("water festival", "lễ hội nước"), | |
| ("harvest festival", "lễ hội harvest"), | |
| ("vu lan festival", "Vu Lan festival"), | |
| ("boat racing festival", "lễ hội đua thuyền"), | |
| ("buffalo fighting festival", "lễ hội chọi trâu"), | |
| ("rice harvest festival", "lễ hội hái lúa"), | |
| ("thanksgiving festival", "lễ hội cúng ơn"), | |
| ("ok om bok festival", "lễ hội Óc Om Bóc"), | |
| ("don ta festival", "lễ hội Dôn Ta"), | |
| ("khmer new year", "lễ hội Chaul Chnam Thmey"), | |
| ("roong pooc festival", "lễ hội Roóng Poọc"), | |
| ("nang hai festival", "lễ hội Nàng Hai"), | |
| ("lion dance festival", "lễ hội múa lân"), | |
| ("fireworks festival", "lễ hội pháo hoa"), | |
| ("ban flower festival", "lễ hội hoa ban"), | |
| ("coffee festival", "lễ hội café"), | |
| ("con throwing festival", "lễ hội ném còn"), | |
| ("love festival", "lễ hội tình yêu"), | |
| ("vietnamese valentine", "Valentine Việt Nam"), | |
| ("first full moon", "rằm tháng Giêng"), | |
| ("cold food festival", "tết Hàn thực"), | |
| ("doan ngo festival", "tết Đoan ngọ"), | |
| ("seventh month full moon", "rằm tháng Bảy"), | |
| ("mid autumn festival", "tết Trung thu"), | |
| ("teachers day", "lễ 20/11"), | |
| ("womens day", "lễ 8/3"), | |
| ("hung kings commemoration", "lễ giỗ tổ Hùng Vương"), | |
| ("national day", "lễ Quốc khánh"), | |
| # ===== 5. THỦ CÔNG MỸ NGHỆ (HANDICRAFTS) ===== | |
| ("bat trang ceramics", "gốm sứ Bát Tràng"), | |
| ("dong ho paintings", "tranh Đông Hồ"), | |
| ("vietnamese embroidery", "thêu Việt Nam"), | |
| ("weaving", "đan lát"), | |
| ("bamboo weaving", "mây tre đan"), | |
| ("vietnamese lacquer", "sơn mài Việt Nam"), | |
| ("wood carving", "điêu khắc gỗ"), | |
| ("hue ceramics", "gốm Huế"), | |
| ("silk painting vietnam", "tranh lụa"), | |
| ("bronze casting", "đúc đồng"), | |
| ("stone carving", "chạm khắc"), | |
| ("brocade weaving", "thổ cẩm dệt"), | |
| ("chu dau ceramics", "gốm Chu Đậu"), | |
| ("hue porcelain", "sứ Huế"), | |
| ("phu lang ceramics", "gốm Phù Lãng"), | |
| ("silk painting", "tranh lụa"), | |
| ("lacquer painting", "tranh sơn mài"), | |
| ("mother of pearl inlay", "khảm trai"), | |
| ("wood sculpture", "tượng gỗ"), | |
| ("stone sculpture", "tượng đá"), | |
| ("bronze items", "đồ đồng"), | |
| ("silver items", "đồ bạc"), | |
| ("ethnic jewelry", "trang sức dân tộc"), | |
| ("folk masks", "mặt nạ dân gian"), | |
| ("water puppets", "rối nước"), | |
| ("carpet weaving", "dệt thảm"), | |
| ("sedge mat", "chiếu cói"), | |
| ("handmade conical hat", "nón lá thủ công"), | |
| ("incense making", "làm hương"), | |
| ("do paper", "giấy dó"), | |
| ("cake mold making", "làm bánh in"), | |
| ("folk candy", "kẹo dân gian"), | |
| # ===== 6. NHẠC CỤ (MUSICAL INSTRUMENTS) ===== | |
| ("vietnamese monochord", "đàn bầu"), | |
| ("vietnamese drums", "trống"), | |
| ("bamboo flute", "sáo trúc"), | |
| ("vietnamese zither", "đàn tranh"), | |
| ("moon lute", "đàn nguyệt"), | |
| ("vietnamese pipa", "đàn tỳ bà"), | |
| ("gourd trumpet", "kèn bầu"), | |
| ("bronze gong", "cồng chiêng"), | |
| ("two string fiddle", "đàn nhị"), | |
| ("pan flute", "sáo điếu"), | |
| ("rice drum", "trống cơm"), | |
| ("vietnamese lute", "đàn đáy"), | |
| ("vietnamese guitar", "đàn sến"), | |
| ("36 string zither", "đàn tam thập lục"), | |
| ("16 string zither", "đàn thập lục"), | |
| ("leaf trumpet", "kèn lá"), | |
| ("ethnic flute", "sáo mọi"), | |
| ("ceremonial drum", "trống chầu"), | |
| ("wooden bell", "mõ gỗ"), | |
| ("temple bell", "chuông chùa"), | |
| ("bronze cymbal", "chiêng đồng"), | |
| ("kni string instrument", "đàn K'ni"), | |
| ("trung bamboo xylophone", "đàn T'rưng"), | |
| ("pi flute", "sáo pí"), | |
| ("bronze drum", "trống đồng"), | |
| ("single string instrument", "đàn bầu độc huyền"), | |
| # ===== 7. PHONG CẢNH (LANDSCAPES) ===== | |
| ("ha long bay", "vịnh Hạ Long"), | |
| ("sapa terraced fields", "ruộng bậc thang Sapa"), | |
| ("mekong delta", "delta sông Mekong"), | |
| ("hoan kiem lake", "Hồ Gươm"), | |
| ("west lake hanoi", "Hồ Tây Hà Nội"), | |
| ("phong nha cave", "Phong Nha cave"), | |
| ("ba be lake", "Ba Be lake"), | |
| ("mui ne sand dunes", "Mũi Né sand dunes"), | |
| ("ninh binh landscape", "Ninh Bình landscape"), | |
| ("tam coc", "Tam Cốc"), | |
| ("hoi an ancient town", "Hội An ancient town"), | |
| ("da lat hills", "Đà Lạt hills"), | |
| ("can tho floating market", "Cần Thơ floating market"), | |
| ("muong hoa valley", "Mường Hoa valley"), | |
| ("ha long bay caves", "Hạ Long Bay caves"), | |
| ("fansipan mountain", "núi Phan Xi Păng"), | |
| ("dong van plateau", "cao nguyên Đồng Văn"), | |
| ("cuc phuong national park", "vườn quốc gia Cúc Phương"), | |
| ("u minh national park", "vườn quốc gia U Minh"), | |
| ("phu quoc island", "đảo Phú Quốc"), | |
| ("cat ba island", "đảo Cát Bà"), | |
| ("thoi son islet", "cồn Thoi Son"), | |
| ("moc chau tea hills", "đồi chè Mộc Châu"), | |
| ("mui ne sand hills", "đồi cát Mũi Né"), | |
| ("quy nhon beach", "biển Quy Nhon"), | |
| ("nha trang beach", "biển Nha Trang"), | |
| ("da nang beach", "biển Đà Nẵng"), | |
| ("vung tau beach", "biển Vũng Tàu"), | |
| ("ha long beach", "biển Hạ Long"), | |
| ("sam son beach", "biển Sầm Sơn"), | |
| ("red river", "sông Hồng"), | |
| ("mekong river", "sông Mekong"), | |
| ("perfume river", "sông Hương"), | |
| ("thu bon river", "sông Thu Bồn"), | |
| ("ban gioc waterfall", "thác Ban Giốc"), | |
| ("can gio mangrove forest", "rừng ngập mặn Cần Giờ"), | |
| ("tram chim forest", "rừng Tràm Chim"), | |
| ("yok don national park", "vườn quốc gia Yok Đôn"), | |
| # ===== 8. VĂN HÓA DÂN GIAN (FOLK CULTURE) ===== | |
| ("water puppet show", "múa rối nước"), | |
| ("ca tru performance", "Ca trù performance"), | |
| ("cheo opera", "Chèo opera"), | |
| ("cai luong opera", "Cải lương"), | |
| ("tuong classical opera", "Tuồng classical opera"), | |
| ("vietnamese folklore", "văn hóa dân gian"), | |
| ("dragon dance", "múa rồng"), | |
| ("lion dance", "múa lân"), | |
| ("traditional storytelling", "kể chuyện"), | |
| ("vietnamese folk songs", "hát dân ca"), | |
| ("quan ho singing", "quan họ singing"), | |
| ("hat van ritual", "hát văn ritual"), | |
| ("xam singing", "xẩm singing"), | |
| ("folk tales vietnam", "folk tales Vietnam"), | |
| ("thang long water puppets", "rối nước Thăng Long"), | |
| ("traditional dance", "múa truyền thống"), | |
| ("sap dance", "múa sạp"), | |
| ("xoang dance", "múa xoang"), | |
| ("shadow dance", "múa bóng rỗi"), | |
| ("silk dance", "múa lụa"), | |
| ("lullaby", "hát ru"), | |
| ("bac ninh quan ho", "hát quan họ Bắc Ninh"), | |
| ("chau van singing", "hát chầu văn"), | |
| ("vi giam folk song", "ví giặm"), | |
| ("ho khoan work song", "hò khoan"), | |
| ("soong co singing", "hát soong cọ"), | |
| ("quan ho folk song", "dân ca quan họ"), | |
| ("xoan singing", "hát xoan"), | |
| ("hue royal music", "ca Huế"), | |
| ("nghe tinh folk song", "hò Nghệ Tĩnh"), | |
| # ===== 9. GIAO THÔNG (TRANSPORTATION) ===== | |
| ("vietnamese motorbike", "xe máy"), | |
| ("cyclo vietnam", "xích lô"), | |
| ("motorbike taxi", "xe ôm"), | |
| ("mekong boat", "thuyền Mekong"), | |
| ("vietnamese train", "tàu hỏa"), | |
| ("vietnamese transportation", "giao thông Việt Nam"), | |
| ("traditional boat vietnam", "thuyền truyền thống"), | |
| ("basket boat", "thúng chai"), | |
| ("dragon boat vietnam", "thuyền rồng"), | |
| ("vietnamese bus", "xe buýt"), | |
| ("vietnamese taxi", "taxi"), | |
| ("grab bike", "grab bike"), | |
| ("electric vehicle vietnam", "xe điện"), | |
| ("round boat", "thuyền thúng"), | |
| ("cargo boat", "ghe bầu"), | |
| ("kayak vietnam", "thuyền kayak"), | |
| ("ox cart", "xe bò"), | |
| ("buffalo cart", "xe trâu"), | |
| ("palanquin vietnam", "kiệu"), | |
| ("wedding palanquin", "kiệu hoa"), | |
| ("three wheeler", "xe lam"), | |
| ("ferry boat", "đò nang"), | |
| # ===== 10. ĐỜI SỐNG HÀNG NGÀY (DAILY LIFE) ===== | |
| ("vietnamese market", "chợ Việt Nam"), | |
| ("street food vietnam", "street food Vietnam"), | |
| ("coffee shop vietnam", "coffee shop Vietnam"), | |
| ("vietnamese family", "gia đình Việt Nam"), | |
| ("vietnam daily life", "đời sống hàng ngày"), | |
| ("rice farming vietnam", "rice farming Vietnam"), | |
| ("fishing village vietnam", "fishing village Vietnam"), | |
| ("vietnamese school", "trường học Việt Nam"), | |
| ("traditional market", "chợ truyền thống"), | |
| ("vietnamese wedding", "đám cưới Việt Nam"), | |
| ("tet celebration family", "Tết gia đình"), | |
| ("vietnamese kitchen", "nhà bếp Việt Nam"), | |
| ("can tho floating market", "chợ nổi Cần Thơ"), | |
| ("ben thanh market", "chợ Bến Thành"), | |
| ("dong xuan market", "chợ Đồng Xuân"), | |
| ("countryside market", "chợ quê"), | |
| ("craft village vietnam", "làng nghề"), | |
| ("pottery village", "làng gốm"), | |
| ("weaving village", "làng dệt"), | |
| ("fishing village", "làng chài"), | |
| ("vietnamese farmer", "nông dân"), | |
| ("rice harvest", "thu hoạch lúa"), | |
| ("rice planting", "cấy lúa"), | |
| ("rice threshing", "đập lúa"), | |
| ("shrimp farming", "nuôi tôm"), | |
| ("fish farming", "nuôi cá"), | |
| ("buffalo herding", "chăn trâu bò"), | |
| ("duck herding", "chăn vịt"), | |
| ("family meal", "bữa cơm gia đình"), | |
| ("ancestor altar", "bàn thờ gia tiên"), | |
| ("vietnamese student", "học sinh Việt Nam"), | |
| ("classroom", "lớp học"), | |
| ("playground", "sân chơi"), | |
| ("vietnamese neighborhood", "khu phố"), | |
| ("sidewalk cafe", "quán cà phê vỉa hè"), | |
| ("street food stall", "quán ăn đường phố"), | |
| ("street vendor", "xe hàng rong"), | |
| ("daily work", "công việc hàng ngày"), | |
| ("rural life", "sinh hoạt làng quê"), | |
| ("city life", "đời sống thành phố"), | |
| # ===== 11. TRÒ CHƠI DÂN GIAN (TRADITIONAL GAMES) ===== | |
| ("tug of war vietnam", "kéo co"), | |
| ("shuttlecock kicking", "đá cầu"), | |
| ("bamboo dancing", "nhảy sạp"), | |
| ("kite flying", "thả diều"), | |
| ("o an quan game", "ô ăn quan"), | |
| ("blind mans bluff", "bịt mắt bắt dê"), | |
| ("stick hitting game", "đánh khăng"), | |
| ("pot breaking game", "đập niêu"), | |
| ("buffalo fighting", "chọi trâu"), | |
| ("swing game", "đu tiên"), | |
| ("vietnamese traditional games", "trò chơi dân gian"), | |
| ("village wrestling", "hội vật làng"), | |
| ("traditional jump rope", "nhảy dây truyền thống"), | |
| ("bamboo spinning top", "đánh quay tre"), | |
| ("bamboo ring throwing", "thả vòng tre"), | |
| ("con throwing", "tung còn"), | |
| ("traditional wrestling", "vật truyền thống"), | |
| ("cockfighting vietnam", "chọi gà"), | |
| ("spinning top vietnam", "đánh quay"), | |
| ("hide and seek vietnam", "trốn tìm"), | |
| ("stilts walking", "đi cà kheo"), | |
| ("shuttlecock passing", "chơi chuyền"), | |
| ("badminton throwing", "ném gà bông"), | |
| ("marble shooting", "bắn bi"), | |
| ("hopscotch vietnam", "chơi lò cò"), | |
| ("tree climbing", "trèo cây"), | |
| ("river swimming", "bơi sông"), | |
| ("boat racing", "đua thuyền"), | |
| ("dragon dancing", "múa rồng"), | |
| ("children lion dance", "múa lân trẻ em"), | |
| ("drum playing", "đánh trống"), | |
| ("flute playing", "thổi kèn"), | |
| ("instrument playing", "chơi đàn"), | |
| ("storytelling", "kể chuyện"), | |
| ("poetry reciting", "đọc thơ"), | |
| # ===== 12. THỂ THAO TRUYỀN THỐNG (TRADITIONAL SPORTS) ===== | |
| ("dragon boat racing vietnam", "đua thuyền rồng"), | |
| ("vietnamese traditional wrestling", "vật cổ truyền"), | |
| ("stick pushing", "đẩy gậy"), | |
| ("crossbow shooting", "bắn nỏ"), | |
| ("sepak takraw vietnam", "cầu mây"), | |
| ("vietnamese martial arts", "võ cổ truyền"), | |
| ("lion dragon competition", "lân sư rồng thi đấu"), | |
| ("vietnamese chess", "cờ tướng"), | |
| ("traditional stick fighting", "đánh gậy truyền thống"), | |
| ("ghe ngo boat racing", "đua ghe ngo"), | |
| ("bay nui ox racing", "đua bò Bảy Núi"), | |
| ("ha long kayak racing", "đua thuyền kayak Hạ Long"), | |
| ("vovinam demonstration", "vovinam biểu diễn"), | |
| ("vietnamese boxing", "muay Việt Nam"), | |
| ("binh dinh martial arts", "võ Bình Định"), | |
| ("tay son martial arts", "võ Tây Sơn"), | |
| ("traditional weapons", "kim khí"), | |
| ("nunchaku", "côn nhị khúc"), | |
| ("tai chi vietnam", "thái cực quyền"), | |
| ("boxing vietnam", "quyền anh"), | |
| ("judo vietnam", "judo"), | |
| ("wrestling vietnam", "đấu vật"), | |
| ("weightlifting vietnam", "cử tạ"), | |
| ("swimming vietnam", "bơi lội"), | |
| ("cycling racing", "đua xe đạp"), | |
| ("marathon vietnam", "marathon"), | |
| ("badminton vietnam", "cầu lông"), | |
| ("tennis vietnam", "tennis"), | |
| ("table tennis vietnam", "bóng bàn"), | |
| ("karate vietnam", "karatedo"), | |
| ("taekwondo vietnam", "taekwondo"), | |
| ("football vietnam", "bóng đá"), | |
| ("beach volleyball vietnam", "bóng chuyền bãi biển"), | |
| ("street basketball vietnam", "bóng rổ đường phố"), | |
| ("athletics sea games vietnam", "điền kinh SEA Games"), | |
| ("kickboxing vietnam", "kickboxing"), | |
| ("mma vietnam", "MMA"), | |
| ("gymnastics vietnam", "gymnastics"), | |
| ("diving vietnam", "diving"), | |
| # ===== GENERAL CULTURAL TERMS ===== | |
| ("vietnamese culture", "văn hóa Việt Nam"), | |
| ("traditional festival", "lễ hội truyền thống"), | |
| ("vietnamese tradition", "truyền thống Việt Nam"), | |
| ("vietnamese heritage", "di sản Việt Nam"), | |
| ("folk culture", "văn hóa dân gian"), | |
| ("traditional art", "nghệ thuật truyền thống"), | |
| ("vietnamese customs", "phong tục Việt Nam"), | |
| ("cultural performance", "biểu diễn văn hóa"), | |
| ("ethnic minority", "dân tộc thiểu số"), | |
| ("cultural identity", "bản sắc văn hóa"), | |
| ] | |
| # Extract English terms for CLIP detection | |
| english_terms = [pair[0] for pair in vocabulary_pairs] | |
| vietnamese_terms = [pair[1] for pair in vocabulary_pairs] | |
| # Store mapping for result translation | |
| self.en_to_vi_mapping = dict(vocabulary_pairs) | |
| logger.info(f"Loaded comprehensive cultural vocabulary: {len(english_terms)} items across 12 categories") | |
| return english_terms | |
| def detect_objects(self, image: Image.Image, threshold: float = 0.15) -> List[str]: | |
| """Detect cultural objects in image using CLIP - IMPROVED""" | |
| try: | |
| # Prepare image and text inputs - MULTIPLE TEMPLATES | |
| templates = [ | |
| "a photo of {}", | |
| "an image showing {}", | |
| "{}", | |
| "traditional {}", | |
| "vietnamese {}" | |
| ] | |
| all_text_inputs = [] | |
| all_labels = [] | |
| for obj in self.cultural_vocabulary: | |
| for template in templates: | |
| text_input = template.format(obj) | |
| all_text_inputs.append(text_input) | |
| all_labels.append(obj) | |
| # Process in batches to avoid memory issues | |
| batch_size = 50 | |
| all_probs = [] | |
| for i in range(0, len(all_text_inputs), batch_size): | |
| batch_texts = all_text_inputs[i:i+batch_size] | |
| inputs = self.clip_processor( | |
| text=batch_texts, | |
| images=image, | |
| return_tensors="pt", | |
| padding=True | |
| ).to(self.device) | |
| # Get predictions | |
| with torch.no_grad(): | |
| outputs = self.clip_model(**inputs) | |
| logits_per_image = outputs.logits_per_image | |
| probs = logits_per_image.softmax(dim=1) | |
| all_probs.extend(probs[0].cpu().numpy()) | |
| # Group probabilities by object (average across templates) | |
| object_probs = {} | |
| for i, (prob, label) in enumerate(zip(all_probs, all_labels)): | |
| if label not in object_probs: | |
| object_probs[label] = [] | |
| object_probs[label].append(prob) | |
| # Average probabilities and filter | |
| detected_objects = [] | |
| for obj, probs in object_probs.items(): | |
| avg_prob = np.mean(probs) | |
| max_prob = np.max(probs) | |
| # Use both average and max for decision | |
| final_score = (avg_prob * 0.3 + max_prob * 0.7) | |
| if final_score > threshold: | |
| # Translate back to Vietnamese | |
| vietnamese_name = self.en_to_vi_mapping.get(obj, obj) | |
| detected_objects.append(vietnamese_name) | |
| logger.debug(f"Detected {obj} -> {vietnamese_name} (score: {final_score:.3f})") | |
| return detected_objects | |
| except Exception as e: | |
| logger.warning(f"Object detection failed: {e}") | |
| return [] | |