Spaces:
Sleeping
Sleeping
Download app.py from Cookiesukaze/ImgAnalysis: direct link, hf CLI and curl.
- Browser
- Download file 4.53 kB
-
https://huggingface.co/spaces/Cookiesukaze/ImgAnalysis/resolve/main/app.py
- Command line
-
hf download hf://spaces/Cookiesukaze/ImgAnalysis/app.py
-
curl -L -o app.py https://huggingface.co/spaces/Cookiesukaze/ImgAnalysis/resolve/main/app.py
4.53 kB
| import gradio as gr | |
| import cv2 | |
| import numpy as np | |
| import matplotlib.pyplot as plt | |
| import time | |
| import os | |
| from sklearn.cluster import MiniBatchKMeans | |
| from PIL import Image | |
| from transformers import ViTImageProcessor, ViTForImageClassification | |
| import torch | |
| from numba import jit, prange | |
| # 设置环境变量以防止内存泄漏 | |
| os.environ["OMP_NUM_THREADS"] = "1" | |
| # 加载预训练的 ViT 模型和图像处理器 | |
| model_name = "google/vit-base-patch16-224" | |
| image_processor = ViTImageProcessor.from_pretrained(model_name) | |
| model = ViTForImageClassification.from_pretrained(model_name) | |
| def rgb_to_gray_numba(image): | |
| """使用 Numba JIT 编译器将 RGB 图像转换为灰度图像""" | |
| h, w, _ = image.shape | |
| gray_image = np.empty((h, w), dtype=np.uint8) | |
| for i in prange(h): | |
| for j in prange(w): | |
| r, g, b = image[i, j] | |
| gray_image[i, j] = 0.2989 * r + 0.5870 * g + 0.1140 * b | |
| return gray_image | |
| def create_color_palette(colors, size=100): | |
| """创建颜色调色板""" | |
| palette = np.zeros((4 * size, 4 * size, 3), dtype=np.uint8) | |
| for i in range(4): | |
| for j in range(4): | |
| palette[i * size:(i + 1) * size, j * size:(j + 1) * size] = colors[i * 4 + j] | |
| return palette | |
| def identify_image(image): | |
| """识别图像中的对象""" | |
| inputs = image_processor(images=image, return_tensors="pt") | |
| with torch.no_grad(): | |
| outputs = model(**inputs) | |
| logits = outputs.logits | |
| probabilities = torch.nn.functional.softmax(logits, dim=-1)[0] | |
| top_5 = torch.topk(probabilities, 5) | |
| results = [] | |
| for i in range(5): | |
| label = model.config.id2label[top_5.indices[i].item()] | |
| score = top_5.values[i].item() | |
| results.append(f"{label}: {score:.2f}") | |
| return ", ".join(results) | |
| def analyze_image(image): | |
| overall_start_time = time.time() | |
| times = {} | |
| # 0. 图像分类 | |
| start_time = time.time() | |
| top_5_classes = identify_image(image) | |
| times['classification'] = f"{time.time() - start_time:.3f} seconds" | |
| # 将图像转换为 NumPy 数组以进行 OpenCV 操作 | |
| image_np = np.array(image) | |
| # 1. 直方图 | |
| start_time = time.time() | |
| gray_image = cv2.cvtColor(image_np, cv2.COLOR_RGB2GRAY) | |
| hist = cv2.calcHist([gray_image], [0], None, [256], [0, 256]) | |
| hist = cv2.normalize(hist, hist).flatten() | |
| fig, ax = plt.subplots(figsize=(2.56, 1), dpi=100) | |
| ax.plot(hist, color='black') | |
| ax.set_xlim([0, 256]) | |
| ax.set_ylim([0, 1]) | |
| ax.axis('off') | |
| histogram_path = "histogram.png" | |
| plt.savefig(histogram_path, format='png', bbox_inches='tight', pad_inches=0) | |
| plt.close(fig) | |
| times['histogram'] = f"{time.time() - start_time:.3f} seconds" | |
| # 2. 边缘检测 | |
| start_time = time.time() | |
| edges = cv2.Canny(gray_image, 100, 200) | |
| edges_path = "edges.png" | |
| cv2.imwrite(edges_path, edges) | |
| times['edge_detection'] = f"{time.time() - start_time:.3f} seconds" | |
| # 3. 主颜色提取(16种颜色) | |
| start_time = time.time() | |
| # 调整图像大小以加快处理速度 | |
| small_image = cv2.resize(image_np, (100, 100)) | |
| pixels = small_image.reshape((-1, 3)) | |
| pixels = np.float32(pixels) | |
| # 使用 MiniBatchKMeans 代替 K-means | |
| kmeans = MiniBatchKMeans(n_clusters=16, batch_size=100, max_iter=10) | |
| kmeans.fit(pixels) | |
| colors = kmeans.cluster_centers_ | |
| # 创建颜色调色板 | |
| color_palette = create_color_palette(colors) | |
| palette_path = "palette.png" | |
| cv2.imwrite(palette_path, color_palette) | |
| times['main_colors'] = f"{time.time() - start_time:.3f} seconds" | |
| # 计算总体耗时 | |
| overall_elapsed_time = time.time() - overall_start_time | |
| times['overall'] = f"{overall_elapsed_time:.3f} seconds" | |
| # 准备时间输出 | |
| timing_output = "\n".join([f"{k}: {v}" for k, v in times.items()]) | |
| return top_5_classes, histogram_path, edges_path, palette_path, timing_output | |
| # 定义 Gradio 界面 | |
| interface = gr.Interface( | |
| fn=analyze_image, | |
| inputs=gr.Image(type="pil", label="上传图像"), | |
| outputs=[ | |
| gr.Textbox(label="图像分类 (Top 5)"), | |
| gr.Image(label="灰度直方图"), | |
| gr.Image(label="边缘检测"), | |
| gr.Image(label="颜色调色板"), | |
| gr.Textbox(label="处理时间") | |
| ], | |
| title="高级图像分析", | |
| description="上传图像以分析其分类、直方图、边缘和主要颜色。", | |
| allow_flagging="never" | |
| ) | |
| # 启动界面 | |
| interface.launch(share=True) |