vietmeagent / core /viet_meagent.py
Dangindev's picture
Upload folder using huggingface_hub
b0ce04d verified
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 []