Spaces:
Sleeping
Sleeping
File size: 9,284 Bytes
df0d440 be16e3e 105430f ed25dd4 b17860b 840bb85 c507cd4 d8ef608 2d3c414 df0d440 840bb85 105430f 0a8537c d562d13 f66696f df0d440 2d3c414 105430f 4acae3e c2fcab3 161d980 e548086 f66696f 105430f a7f0ae3 105430f 4acae3e 105430f c2fcab3 105430f 16ac16b f296b4f 4dd8b9b 7114c54 4acae3e 696f1ca 105430f c2fcab3 105430f 3787a8c 4acae3e 105430f 9a98ec7 105430f 696f1ca c2fcab3 3787a8c e720316 be16e3e df0d440 c507cd4 2d3c414 c507cd4 2d3c414 3787a8c 2d3c414 a49b159 4dd8b9b a49b159 d562d13 df0d440 f66696f df0d440 d562d13 df0d440 105430f df0d440 c507cd4 6cbb81f 2d3c414 3787a8c d8ef608 be16e3e 715f512 be16e3e 52063f0 43498e1 4dd8b9b 2b81936 4dd8b9b 2069c30 d562d13 43498e1 fb0868b 14c5f38 75856bb 3bf0eab 75856bb 83dfc8d c507cd4 d8ef608 c507cd4 4dd8b9b 72231fb 079e149 c507cd4 2d3c414 3787a8c c2fcab3 3787a8c 4dd8b9b 2beb357 83dfc8d 3787a8c c2fcab3 4dd8b9b f66696f 27d4de9 4dd8b9b 3787a8c c2fcab3 3787a8c c2fcab3 3787a8c c2fcab3 2d3c414 d562d13 c2fcab3 2d3c414 4dd8b9b 2beb357 2d3c414 c2fcab3 2d3c414 c2fcab3 2b81936 2d3c414 52063f0 df0d440 0c120b4 be16e3e 0c120b4 df0d440 be16e3e |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 |
import os
import time
import numpy as np
from PIL import Image
import torchvision.transforms as transforms
from pathlib import Path
from ultralytics import YOLO
import io
import base64
import uuid
import glob
from tensorflow import keras
from flask import Flask, jsonify, request, render_template, send_file
import torch
from collections import Counter
import psutil
from gradio_client import Client, handle_file
# Disable tensorflow warnings
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
load_type = 'local'
MODEL_YOLO = "yolo11_detect_best_241024_1.pt"
MODEL_DIR = "./artifacts/models"
YOLO_DIR = "./artifacts/yolo"
GRADIO_URL = "https://50094cfbc694a82dea.gradio.live/"
#REPO_ID = "1vash/mnist_demo_model"
# Load the saved YOLO model into memory
if load_type == 'local':
# 本地模型路徑
model_path = f'{MODEL_DIR}/{MODEL_YOLO}'
if not os.path.exists(model_path):
raise FileNotFoundError(f"Model file not found at {model_path}")
model = YOLO(model_path)
print("***** 1. LOAD YOLO MODEL DONE *****")
#model.eval() # 設定模型為推理模式
elif load_type == 'remote_hub_download':
from huggingface_hub import hf_hub_download
# 從 Hugging Face Hub 下載模型
model_path = hf_hub_download(repo_id=REPO_ID, filename=MODEL_YOLO)
model = torch.load(model_path)
#model.eval()
elif load_type == 'remote_hub_from_pretrained':
# 使用 Hugging Face Hub 預訓練的模型方式下載
os.environ['TRANSFORMERS_CACHE'] = str(Path(MODEL_DIR).absolute())
from huggingface_hub import from_pretrained
model = from_pretrained(REPO_ID, filename=MODEL_YOLO, cache_dir=MODEL_DIR)
#model.eval()
else:
raise AssertionError('No load type is specified!')
# image to base64
def image_to_base64(image_path):
with open(image_path, "rb") as image_file:
encoded_string = base64.b64encode(image_file.read()).decode('utf-8')
return encoded_string
# 抓取指定路徑下的所有 JPG 檔案
def get_jpg_files(path):
"""
Args:
path: 要搜尋的目錄路徑。
Returns:
一個包含所有 JPG 檔案路徑的列表。
"""
return glob.glob(os.path.join(path, "*.jpg"))
# 使用範例
# image_folder = '/content/drive/MyDrive/chiikawa' # 替換成你的目錄路徑
# jpg_files = get_jpg_files(image_folder)
def check_memory_usage():
# Get memory details
memory_info = psutil.virtual_memory()
total_memory = memory_info.total / (1024 * 1024) # Convert bytes to MB
available_memory = memory_info.available / (1024 * 1024)
used_memory = memory_info.used / (1024 * 1024)
memory_usage_percent = memory_info.percent
print(f"^^^^^^ Total Memory: {total_memory:.2f} MB ^^^^^^")
print(f"^^^^^^ Available Memory: {available_memory:.2f} MB ^^^^^^")
print(f"^^^^^^ Used Memory: {used_memory:.2f} MB ^^^^^^")
print(f"^^^^^^ Memory Usage (%): {memory_usage_percent}% ^^^^^^")
# Run the function
check_memory_usage()
# Initialize the Flask application
app = Flask(__name__)
# # Initialize the ClipModel at the start
# clip_model = ClipModel()
# API route for prediction(YOLO)
@app.route('/predict', methods=['POST'])
def predict():
#user_id = request.args.get('user_id')
file = request.files['image']
message_id = request.form.get('message_id') #str(uuid.uuid4())
if 'image' not in request.files:
# Handle if no file is selected
return jsonify({"error": "No image part"}), 400
#return 'No file selected'
# 讀取圖像
try:
image_data = Image.open(file)
except Exception as e:
return jsonify({'error': str(e)}), 400
print("***** 2. Start YOLO predict *****")
# Make a prediction using YOLO
results = model(image_data)
print ("===== YOLO predict result:",results,"=====")
print("***** YOLO predict DONE *****")
check_memory_usage()
# 檢查 YOLO 是否返回了有效的結果
if results is None or len(results) == 0:
return jsonify({'error': 'No results from YOLO model'}), 400
saved_images = []
# 儲存辨識後的圖片到指定資料夾
for result in results:
encoded_images=[]
element_list =[]
top_k_words =[]
# 保存圖片
result.save_crop(f"{YOLO_DIR}/{message_id}")
num_detections = len(result.boxes) # Get the number of detections
labels = result.boxes.cls # Get predicted label IDs
label_names = [model.names[int(label)] for label in labels] # Convert to names
print(f"====== 3. YOLO label_names: {label_names}======")
element_counts = Counter(label_names)
for element, count in element_counts.items():
yolo_path = f"{YOLO_DIR}/{message_id}/{element}"
yolo_file = get_jpg_files(yolo_path)
print(f"***** 處理:{yolo_path} *****")
if len(yolo_file) == 0:
print(f"警告:{element} 沒有找到相關的 JPG 檔案")
continue
element_list.append(element)
for yolo_img in yolo_file: # 每張切圖yolo_img
print("***** 4. START CLIP *****")
client = Client(GRADIO_URL)
clip_result = client.predict(
image=handle_file(yolo_img),
top_k=3,
api_name="/predict"
)
top_k_words.append(clip_result) # CLIP預測3個結果(top_k_words)
#encoded_images.append(image_to_base64(yolo_img))
print(f"===== CLIP result:{top_k_words} =====\n")
# if element_counts[element] > 1: #某隻角色的數量>1
# yolo_path = f"{YOLO_DIR}/{message_id}/{element}"
# yolo_file = get_jpg_files(yolo_path)
# for yolo_img in yolo_file: # 取得每張圖的路徑
# encoded_images.append(image_to_base64(yolo_img))
# else : #某隻角色的數量=1
# yolo_path = f"{YOLO_DIR}/{message_id}/{element}/im.jpg.jpg"
# encoded_images.append(image_to_base64(yolo_path))
## 建立回應資料
# response_data = {
# 'message_id': message_id,
# 'description': element_list,
# 'images': [
# {
# 'encoded_image': encoded_image,
# 'description_list': top_k_words
# }
# for encoded_image, description_list in zip(encoded_images, top_k_words)
# ]
# }
# response_data = {
# 'message_id': message_id,
# 'images': encoded_images,
# 'description': element_list
# }
return jsonify(top_k_words), 200 #jsonify(response_data)
# for label_name in label_names:
# yolo_file=f"{YOLO_DIR}/{message_id}/{label_name}/im.jpg.jpg"
# # 將圖片轉換為 base64 編碼
# encoded_images.append(image_to_base64(yolo_file))
# # dictionary is not a JSON: https://www.quora.com/What-is-the-difference-between-JSON-and-a-dictionary
# # flask.jsonify vs json.dumps https://sentry.io/answers/difference-between-json-dumps-and-flask-jsonify/
# # The flask.jsonify() function returns a Response object with Serializable JSON and content_type=application/json.
# return jsonify(response)
# # Helper function to preprocess the image
# def preprocess_image(image_data):
# """Preprocess image for YOLO Model Inference
# :param image_data: Raw image (PIL.Image)
# :return: image: Preprocessed Image (Tensor)
# """
# # Define the YOLO input size (example 640x640, you can modify this based on your model)
# input_size = (640, 640)
# # Define transformation: Resize the image, convert to Tensor, and normalize pixel values
# transform = transforms.Compose([
# transforms.Resize(input_size), # Resize to YOLO input size
# transforms.ToTensor(), # Convert image to PyTorch Tensor (通道數、影像高度和寬度)
# transforms.Normalize([0.0, 0.0, 0.0], [1.0, 1.0, 1.0]) # Normalization (if needed)
# ])
# # Apply transformations to the image
# image = transform(image_data)
# # Add batch dimension (1, C, H, W) since YOLO expects a batch
# image = image.unsqueeze(0)
# return image
# API route for health check
@app.route('/health', methods=['GET'])
def health():
"""
Health check API to ensure the application is running.
Returns "OK" if the application is healthy.
Demo Usage: "curl http://localhost:5000/health" or using alias "curl http://127.0.0.1:5000/health"
"""
return 'OK'
# API route for version
@app.route('/version', methods=['GET'])
def version():
"""
Returns the version of the application.
Demo Usage: "curl http://127.0.0.1:5000/version" or using alias "curl http://127.0.0.1:5000/version"
"""
return '1.0'
@app.route("/")
def hello_world():
return render_template("index.html")
# return "<p>Hello, Team!</p>"
# Start the Flask application
if __name__ == '__main__':
app.run(debug=True)
|