Spaces:
Sleeping
Sleeping
| # 1. 扫描当前目录下所有image文件 包含png jpg jpeg webp,进行编号 存储下list | |
| import os, json | |
| import uuid # 添加导入uuid模块 | |
| image_pathes = [] | |
| root = '/data/lizhen/resources/image' | |
| image_root = os.path.join(root, 'images') | |
| image_path_file = os.path.join(root, 'image_pathes.txt') | |
| result_map_file = os.path.join(root, 'result_map.txt') | |
| # Load existing result mappings | |
| result_map = {} | |
| if os.path.exists(result_map_file): | |
| with open(result_map_file, 'r') as f: | |
| for line in f: | |
| filename, result_file = line.strip().split(',') | |
| result_map[filename] = result_file | |
| existing_paths = set() | |
| if os.path.exists(image_path_file): | |
| with open(image_path_file, 'r') as f: | |
| existing_paths = set(line.strip() for line in f.readlines()) | |
| image_pathes = [os.path.join(image_root, path) for path in existing_paths] | |
| print(f"Loaded {len(image_pathes)} existing image paths") | |
| print('Scanning images...') | |
| new_paths = [] | |
| for root_dir, dirs, files in os.walk(image_root): | |
| for file in files: | |
| if file.lower().endswith(('.png', '.jpg', '.jpeg', '.webp')): | |
| abs_path = os.path.join(root_dir, file) | |
| rel_path = os.path.relpath(abs_path, image_root) | |
| if rel_path not in existing_paths: | |
| new_paths.append(rel_path) | |
| image_pathes.append(abs_path) | |
| if new_paths: | |
| print(f"Found {len(new_paths)} new images") | |
| with open(image_path_file, 'a') as f: | |
| for path in new_paths: | |
| f.write(path + '\n') | |
| print(f"Total images: {len(image_pathes)}") | |
| from openai import OpenAI | |
| from PIL import Image | |
| import base64 | |
| from io import BytesIO | |
| import requests | |
| from concurrent.futures import ThreadPoolExecutor | |
| import threading | |
| client = OpenAI( | |
| api_key=os.getenv("OPENAI_API_KEY") or os.getenv("AIHUBMIX_API_KEY", ""), | |
| base_url=os.getenv("OPENAI_BASE_URL", "https://aihubmix.com/v1") | |
| ) | |
| def resize_image(img, max_size=512): | |
| width, height = img.size | |
| ratio = min(max_size / width, max_size / height) | |
| if ratio >= 1: | |
| return img | |
| new_width = int(width * ratio) | |
| new_height = int(height * ratio) | |
| resized_img = img.resize((new_width, new_height), Image.Resampling.LANCZOS) | |
| return resized_img | |
| def repaint_image(img): | |
| # rapaint transparent area with white color | |
| img = img.convert('RGBA') | |
| data = img.getdata() | |
| new_data = [] | |
| for item in data: | |
| if item[3] == 0: | |
| new_data.append((255, 255, 255, 255)) | |
| else: | |
| new_data.append(item) | |
| img.putdata(new_data) | |
| img = img.convert('RGB') | |
| # img.save('temp.png') | |
| return img | |
| def image_to_base64(image_path, show=False, target_size=512): | |
| with Image.open(image_path) as img: | |
| # img = img.resize(size) | |
| img = resize_image(img, 512) | |
| img = repaint_image(img) | |
| buffered = BytesIO() | |
| img.save(buffered, format="PNG") | |
| img_base64 = base64.b64encode(buffered.getvalue()).decode('utf-8') | |
| return img_base64 | |
| wwxxhh = 0 | |
| def ask_image(prompt, image_data): | |
| number_of_trials = 0 | |
| while number_of_trials < 5: | |
| try: | |
| response = requests.post( | |
| "https://aihubmix.com/v1/chat/completions", | |
| headers={ | |
| "Authorization": f"Bearer {os.getenv('OPENAI_API_KEY') or os.getenv('AIHUBMIX_API_KEY', '')}", | |
| "Content-Type": "application/json" | |
| }, | |
| json={ | |
| "model": "gemini-2.0-flash", | |
| "messages": [{ | |
| "role": "user", | |
| "content": [ | |
| {"type": "text", "text": prompt}, | |
| { | |
| "type": "image_url", | |
| "image_url": { | |
| "url": f"data:image/jpeg;base64,{image_data}" | |
| } | |
| } | |
| ] | |
| }] | |
| } | |
| ) | |
| if response.status_code == 200: | |
| return response.json()['choices'][0]['message']['content'] | |
| else: | |
| print(f"Error status code: {response.status_code}") | |
| number_of_trials += 1 | |
| except Exception as e: | |
| print(f"Request error: {e}") | |
| number_of_trials += 1 | |
| return 'Error!' | |
| # 2. 读取prompt.json文件,读取整个作为字符串,逐个读取image文件,调用ask_image函数,将返回的结果存储下来 | |
| import json | |
| with open('modules/image_recommender/prompt.json', 'r') as f: | |
| prompt = f.read() | |
| # print(prompt) | |
| results_path = os.path.join(root, 'results') | |
| if not os.path.exists(results_path): | |
| os.makedirs(results_path) | |
| def process_image(args): | |
| i, image_path, prompt, results_path = args | |
| rel_path = os.path.relpath(image_path, image_root) | |
| # 使用UUID生成随机文件名,而不是使用索引 | |
| random_filename = str(uuid.uuid4()) | |
| target_path = os.path.join(results_path, f'{random_filename}.json') | |
| # Skip if already processed | |
| if rel_path in result_map: | |
| print(f'Skipping {i+1}/{len(image_pathes)} (already exists in result map)') | |
| return | |
| print(f'Processing {i+1}/{len(image_pathes)}') | |
| try: | |
| image_data = image_to_base64(image_path) | |
| result = ask_image(prompt, image_data) | |
| try: | |
| result = json.loads(result) | |
| except: | |
| result = result.replace('```json', '').replace('```', '') | |
| result = json.loads(result) | |
| # Add filename and remove explanation | |
| result['filename'] = rel_path | |
| if 'explanation' in result: | |
| del result['explanation'] | |
| with open(target_path, 'w') as f: | |
| json.dump(result, f) | |
| # Update result mapping | |
| with open(result_map_file, 'a') as f: | |
| f.write(f"{rel_path},{target_path}\n") | |
| result_map[rel_path] = target_path | |
| except Exception as e: | |
| print(f'Failed to process {i+1}/{len(image_pathes)}: {str(e)}') | |
| # Pre-scan for existing results | |
| print("Pre-scanning for existing results...") | |
| results_path = os.path.join(root, 'results') | |
| if not os.path.exists(results_path): | |
| os.makedirs(results_path) | |
| # Filter out already processed images | |
| image_pathes = [path for path in image_pathes if os.path.relpath(path, image_root) not in result_map] | |
| print(f"Remaining images to process: {len(image_pathes)}") | |
| # Main processing loop with thread pool | |
| num_threads = 20 | |
| with ThreadPoolExecutor(max_workers=num_threads) as executor: | |
| tasks = [ | |
| (i, image_pathes[i], prompt, results_path) for i in range(len(image_pathes)) | |
| ] | |
| executor.map(process_image, tasks) | |