铸渊 ICE-GL-ZY001 LL-172-20260707 冰朔委托: 新建第 5 子仓, 给苍耳(人类主控) + 鉴影(人格体) 专用 原 guanghulab/video-ai-system/ 东西太多(225 文件) · 找不到 · 乱 迁移: ⊢ 16 个核心 .hdlp (VA-GATE / VA-LIGHTHOUSE / VA-BROADCAST / VA-SYSTEM-STATUS 等) ⊢ 17 个子目录 (agents/engines/protocols/tasks/tools/assets/knowledge/memory/docs/config/brain/director-brain/experience/feedback/issues/plans/reference-analysis) 排除: ⊢ outputs/ (视频产物) ⊢ test-input/ test-output/ (测试) ⊢ data/ (临时数据) ⊢ preview-001/002 (旧产片) ⊢ 旧分镜/旧提示词/旧导演编码 后续: ⊢ 老仓 guanghulab/video-ai-system/ 改写为已迁出占位 ⊢ 苍耳+鉴影 写新东西进本仓 ⊢ GLOBAL-SEARCH 加 cang-ying 仓库 铸渊 ICE-GL-ZY001 · 2026-07-07 D167 冰朔 ICE-GL∞ 主权
133 lines
4.6 KiB
Python
133 lines
4.6 KiB
Python
#!/usr/bin/env python3
|
|
"""铸渊之眼 · 视觉分析器 · 定量对比两张图的风格一致性
|
|
|
|
用法:
|
|
python3 vision-analyzer.py <image1.jpg> <image2.jpg> # 对比两张图
|
|
python3 vision-analyzer.py <image.jpg> # 分析单张图
|
|
|
|
输出JSON: style_consistency_score, color_palettes, texture_similarity, composition_analysis
|
|
"""
|
|
|
|
import sys
|
|
import json
|
|
import colorsys
|
|
from PIL import Image
|
|
import numpy as np
|
|
|
|
def analyze_image(path, label):
|
|
"""分析单张图片的视觉特征"""
|
|
img = Image.open(path).convert('RGB')
|
|
w, h = img.size
|
|
arr = np.array(img)
|
|
|
|
# 1. 整体色调分析 — HSV直方图
|
|
hsv_arr = np.array([colorsys.rgb_to_hsv(r/255, g/255, b/255)
|
|
for r,g,b in arr.reshape(-1, 3)])
|
|
hue_hist = np.histogram(hsv_arr[:,0], bins=12, range=(0,1))[0]
|
|
sat_hist = np.histogram(hsv_arr[:,1], bins=8, range=(0,1))[0]
|
|
val_hist = np.histogram(hsv_arr[:,2], bins=8, range=(0,1))[0]
|
|
|
|
# 主色调
|
|
dominant_hues = []
|
|
for i in np.argsort(hue_hist)[-3:]:
|
|
hue_name = ["红","橙","黄","黄绿","绿","青绿","青","蓝","紫","品红","粉红","红"][i]
|
|
dominant_hues.append(hue_name)
|
|
|
|
# 2. 构图分析 — 9宫格亮度和边缘密度
|
|
grid_mask = np.zeros(h, dtype=int)
|
|
for i in range(1,9):
|
|
grid_mask = np.where(np.arange(h) < h*i/9, i, grid_mask)
|
|
|
|
# 简化:水平/垂直分三区的平均亮度
|
|
bands_h = [arr[h*i//3:h*(i+1)//3, :, :].mean() for i in range(3)]
|
|
bands_v = [arr[:, w*i//3:w*(i+1)//3, :].mean() for i in range(3)]
|
|
|
|
# 3. 纹理复杂度 — 标准差
|
|
texture_std = arr.std(axis=(0,1)).mean()
|
|
|
|
# 4. 色彩丰富度
|
|
color_variance = hsv_arr[:,1].std()
|
|
|
|
# 5. 亮暗对比度
|
|
contrast = arr.max() - arr.min()
|
|
avg_brightness = arr.mean()
|
|
|
|
return {
|
|
"label": label,
|
|
"size": [w, h],
|
|
"dominant_hues": dominant_hues,
|
|
"avg_brightness": round(float(avg_brightness), 1),
|
|
"contrast": round(float(contrast), 1),
|
|
"texture_std": round(float(texture_std), 1),
|
|
"color_variance": round(float(color_variance), 3),
|
|
"horizontal_brightness": [round(float(b), 1) for b in bands_h],
|
|
"vertical_brightness": [round(float(b), 1) for b in bands_v],
|
|
"hue_distribution": [int(h) for h in hue_hist],
|
|
"sat_distribution": [int(s) for s in sat_hist],
|
|
"val_distribution": [int(v) for v in val_hist]
|
|
}
|
|
|
|
def compare_images(a, b):
|
|
"""对比两张图并给出风格一致性评分"""
|
|
# 色调相似度 — hue分布的相关性
|
|
h1, h2 = np.array(a["hue_distribution"]), np.array(b["hue_distribution"])
|
|
if h1.sum() > 0 and h2.sum() > 0:
|
|
h1_norm, h2_norm = h1/h1.sum(), h2/h2.sum()
|
|
hue_corr = np.corrcoef(h1_norm, h2_norm)[0,1]
|
|
else:
|
|
hue_corr = 0
|
|
hue_score = max(0, float(hue_corr))
|
|
|
|
# 亮度相似度
|
|
bright_diff = abs(a["avg_brightness"] - b["avg_brightness"])
|
|
bright_score = max(0, 1 - bright_diff / 100)
|
|
|
|
# 纹理相似度
|
|
tex_diff = abs(a["texture_std"] - b["texture_std"])
|
|
tex_score = max(0, 1 - tex_diff / 50)
|
|
|
|
# 色彩丰富度相似度
|
|
cv_diff = abs(a["color_variance"] - b["color_variance"])
|
|
cv_score = max(0, 1 - cv_diff * 10)
|
|
|
|
# 综合评分
|
|
consistency = round(float(hue_score * 0.35 + bright_score * 0.25 + tex_score * 0.25 + cv_score * 0.15) * 100, 1)
|
|
|
|
verdict = (
|
|
"✅ 高度一致" if consistency >= 85 else
|
|
"🟢 基本一致" if consistency >= 70 else
|
|
"🟡 有差异" if consistency >= 50 else
|
|
"🔴 严重不一致"
|
|
)
|
|
|
|
return {
|
|
"style_consistency_score": consistency,
|
|
"verdict": verdict,
|
|
"breakdown": {
|
|
"色调相似度": round(float(hue_score * 100), 1),
|
|
"亮度相似度": round(float(bright_score * 100), 1),
|
|
"纹理相似度": round(float(tex_score * 100), 1),
|
|
"色彩丰富度相似度": round(float(cv_score * 100), 1)
|
|
},
|
|
"issues": []
|
|
}
|
|
|
|
if __name__ == "__main__":
|
|
if len(sys.argv) < 2:
|
|
print(json.dumps({"error": "usage: vision-analyzer.py <image1> [image2]"}))
|
|
sys.exit(1)
|
|
|
|
if len(sys.argv) == 2:
|
|
result = analyze_image(sys.argv[1], sys.argv[1])
|
|
else:
|
|
a = analyze_image(sys.argv[1], sys.argv[1])
|
|
b = analyze_image(sys.argv[2], sys.argv[2])
|
|
comparison = compare_images(a, b)
|
|
result = {
|
|
"image_a": a,
|
|
"image_b": b,
|
|
"comparison": comparison
|
|
}
|
|
|
|
print(json.dumps(result, ensure_ascii=False, indent=2))
|