Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -514,7 +514,7 @@ def analyze_clothing_details(image):
|
|
514 |
features["clothing_angle_uniformity"] = float(max_count / max(total_count, 1))
|
515 |
|
516 |
# 分析纹理的一致性
|
517 |
-
|
518 |
block_size = 32
|
519 |
h, w = gray.shape
|
520 |
texture_variations = []
|
@@ -534,7 +534,7 @@ def analyze_clothing_details(image):
|
|
534 |
|
535 |
# 计算纹理变化的熵 - 真实衣物纹理变化的熵更高
|
536 |
features["clothing_texture_entropy"] = float(stats.entropy(texture_variations + 1e-10))
|
537 |
-
# 褶皱分析 - 使用形态学操作提取可能的褶皱
|
538 |
_, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
|
539 |
kernel = np.ones((3,3), np.uint8)
|
540 |
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
|
@@ -654,15 +654,39 @@ def analyze_extremities(image):
|
|
654 |
return features
|
655 |
|
656 |
def check_ai_specific_features(image_features):
|
657 |
-
"""检查AI
|
658 |
ai_score = 0
|
659 |
ai_signs = []
|
660 |
|
661 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
662 |
if "horizontal_symmetry" in image_features and "vertical_symmetry" in image_features:
|
663 |
avg_symmetry = (image_features["horizontal_symmetry"] + image_features["vertical_symmetry"]) / 2
|
664 |
-
if avg_symmetry > 0.8:
|
665 |
-
ai_score += 0.15
|
666 |
ai_signs.append("图像对称性异常高")
|
667 |
elif avg_symmetry > 0.7:
|
668 |
ai_score += 0.1
|
@@ -705,26 +729,6 @@ def check_ai_specific_features(image_features):
|
|
705 |
ai_score += 0.1
|
706 |
ai_signs.append("频率分布不自然")
|
707 |
|
708 |
-
# 检查频率各向异性 - AI生成图像通常频率分布各向异性较低
|
709 |
-
if "freq_anisotropy" in image_features and image_features["freq_anisotropy"] < 0.5:
|
710 |
-
ai_score += 0.15
|
711 |
-
ai_signs.append("频率分布各向异性异常低")
|
712 |
-
|
713 |
-
# 检查局部颜色变化 - 真实照片通常有更多局部颜色变化
|
714 |
-
if "local_color_variation" in image_features and image_features["local_color_variation"] < 5:
|
715 |
-
ai_score += 0.15
|
716 |
-
ai_signs.append("局部颜色变化异常少")
|
717 |
-
|
718 |
-
# 检查边缘变化 - 真实照片的边缘通常更自然
|
719 |
-
if "edge_variance" in image_features and image_features["edge_variance"] < 100:
|
720 |
-
ai_score += 0.15
|
721 |
-
ai_signs.append("边缘变化异常均匀")
|
722 |
-
|
723 |
-
# 检查边缘方向熵 - 真实照片的边缘方向熵通常更高
|
724 |
-
if "edge_direction_entropy" in image_features and image_features["edge_direction_entropy"] < 1.5:
|
725 |
-
ai_score += 0.15
|
726 |
-
ai_signs.append("边缘方向熵异常低")
|
727 |
-
|
728 |
# 检查噪声频谱 - 真实照片的噪声频谱更自然
|
729 |
if "noise_spectrum_std" in image_features and image_features["noise_spectrum_std"] < 1000:
|
730 |
ai_score += 0.15
|
@@ -817,10 +821,13 @@ def check_ai_specific_features(image_features):
|
|
817 |
ai_score += 0.15
|
818 |
ai_signs.append("手部曲率变化异常均匀")
|
819 |
|
820 |
-
#
|
821 |
-
|
822 |
-
|
823 |
-
|
|
|
|
|
|
|
824 |
|
825 |
return min(ai_score, 1.0), ai_signs
|
826 |
|
@@ -954,7 +961,7 @@ def detect_photoshop_signs(image_features):
|
|
954 |
return min(ps_score, 1.0), ps_signs
|
955 |
|
956 |
def get_detailed_analysis(ai_probability, ps_score, beauty_score, ps_signs, ai_signs, beauty_signs, valid_models_count):
|
957 |
-
"""
|
958 |
|
959 |
# 根据有效模型数量调整置信度描述
|
960 |
confidence_prefix = ""
|
@@ -965,46 +972,30 @@ def get_detailed_analysis(ai_probability, ps_score, beauty_score, ps_signs, ai_s
|
|
965 |
elif valid_models_count == 1:
|
966 |
confidence_prefix = "中等置信度:"
|
967 |
|
968 |
-
#
|
969 |
-
if ai_probability > 0.
|
970 |
-
category = confidence_prefix + "
|
971 |
description = "图像很可能是由AI完全生成,几乎没有真人照片的特征。"
|
972 |
-
|
973 |
-
|
974 |
-
|
975 |
-
|
976 |
-
|
977 |
-
|
978 |
-
|
979 |
-
|
980 |
-
|
981 |
-
description = "图像有较多AI生成的特征,但也保留了一些真实照片的特点。"
|
982 |
-
elif ai_probability > 0.3: # 低AI概率
|
983 |
-
if beauty_score > 0.5: # 中高美颜分数
|
984 |
-
category = confidence_prefix + "很可能是美颜处理的真人照片"
|
985 |
-
description = "图像很可能是真人照片经过美颜处理,美颜痕迹明显。"
|
986 |
-
elif ps_score > 0.5: # 高PS分数
|
987 |
-
category = confidence_prefix + "低概率AI生成,高概率PS修图"
|
988 |
-
description = "图像更可能是真人照片经过大量后期处理,PS痕迹明显。"
|
989 |
-
else:
|
990 |
-
category = confidence_prefix + "低概率AI生成"
|
991 |
-
description = "图像更可能是真人照片,但有一些AI生成或修饰的特征。"
|
992 |
-
else: # 很低AI概率
|
993 |
-
if beauty_score > 0.6:
|
994 |
-
category = confidence_prefix + "真人照片,重度美颜处理"
|
995 |
-
description = "图像基本是真人照片,但经过了重度美颜处理。"
|
996 |
-
elif ps_score > 0.6:
|
997 |
-
category = confidence_prefix + "真人照片,重度PS修图"
|
998 |
-
description = "图像基本是真人照片,但经过了大量后期处理,修饰痕迹明显。"
|
999 |
-
elif ps_score > 0.3 or beauty_score > 0.3:
|
1000 |
-
category = confidence_prefix + "真人照片,中度修图或美颜"
|
1001 |
-
description = "图像是真人照片,有明显的后期处理或美颜痕迹。"
|
1002 |
-
elif ps_score > 0.1 or beauty_score > 0.1:
|
1003 |
-
category = confidence_prefix + "真人照片,轻度修图或美颜"
|
1004 |
-
description = "图像是真人照片,有少量后期处理或美颜。"
|
1005 |
else:
|
1006 |
-
category = confidence_prefix + "
|
1007 |
-
description = "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1008 |
|
1009 |
# 添加具体的PS痕迹描述
|
1010 |
if ps_signs:
|
@@ -1024,7 +1015,7 @@ def get_detailed_analysis(ai_probability, ps_score, beauty_score, ps_signs, ai_s
|
|
1024 |
else:
|
1025 |
beauty_details = "未检测到明显的美颜特征。"
|
1026 |
|
1027 |
-
return category, description, ps_details, ai_details, beauty_details
|
1028 |
|
1029 |
def detect_ai_image(image):
|
1030 |
"""主检测函数"""
|
@@ -1073,8 +1064,7 @@ def detect_ai_image(image):
|
|
1073 |
final_ai_probability = weighted_ai_probability / sum(m["weight"] for k, m in models.items() if m["processor"] is not None and m["model"] is not None)
|
1074 |
else:
|
1075 |
return {"error": "所有模型加载失败"}
|
1076 |
-
|
1077 |
-
# 分析图像特征
|
1078 |
image_features = analyze_image_features(image)
|
1079 |
|
1080 |
# 检查AI特定特征
|
@@ -1089,13 +1079,41 @@ def detect_ai_image(image):
|
|
1089 |
# 应用特征权重调整AI概率
|
1090 |
adjusted_probability = final_ai_probability
|
1091 |
|
1092 |
-
#
|
1093 |
-
if ai_feature_score > 0.
|
|
|
|
|
1094 |
adjusted_probability = max(adjusted_probability, 0.7)
|
1095 |
-
elif ai_feature_score > 0.
|
1096 |
adjusted_probability = max(adjusted_probability, 0.6)
|
1097 |
-
|
1098 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1099 |
|
1100 |
# 如果检测到衣物或手部异常,大幅提高AI概率
|
1101 |
if "clothing_angle_uniformity" in image_features and image_features["clothing_angle_uniformity"] > 0.3:
|
@@ -1104,18 +1122,6 @@ def detect_ai_image(image):
|
|
1104 |
if "extremity_perimeter_area_ratio" in image_features and image_features["extremity_perimeter_area_ratio"] < 0.05:
|
1105 |
adjusted_probability = max(adjusted_probability, 0.7)
|
1106 |
|
1107 |
-
# 如果检测到微观纹理异常,提高AI概率
|
1108 |
-
if "lbp_entropy" in image_features and image_features["lbp_entropy"] < 3.0:
|
1109 |
-
adjusted_probability = max(adjusted_probability, 0.6)
|
1110 |
-
|
1111 |
-
# 如果检测到频率分布异常,提高AI概率
|
1112 |
-
if "freq_anisotropy" in image_features and image_features["freq_anisotropy"] < 0.5:
|
1113 |
-
adjusted_probability = max(adjusted_probability, 0.6)
|
1114 |
-
|
1115 |
-
# 如果美颜分数高但AI特征分数不高,降低AI概率
|
1116 |
-
if beauty_score > 0.6 and ai_feature_score < 0.5:
|
1117 |
-
adjusted_probability = min(adjusted_probability, 0.5)
|
1118 |
-
|
1119 |
# 确保概率在0-1范围内
|
1120 |
adjusted_probability = min(1.0, max(0.0, adjusted_probability))
|
1121 |
|
@@ -1127,7 +1133,7 @@ def detect_ai_image(image):
|
|
1127 |
adjusted_probability = (adjusted_probability + ai_detector_prob * 2) / 3
|
1128 |
|
1129 |
# 获取详细分析
|
1130 |
-
category, description, ps_details, ai_details, beauty_details = get_detailed_analysis(
|
1131 |
adjusted_probability, ps_score, beauty_score, ps_signs, ai_signs, beauty_signs, valid_models
|
1132 |
)
|
1133 |
|
@@ -1139,6 +1145,7 @@ def detect_ai_image(image):
|
|
1139 |
"beauty_score": beauty_score,
|
1140 |
"ai_feature_score": ai_feature_score,
|
1141 |
"category": category,
|
|
|
1142 |
"description": description,
|
1143 |
"ps_details": ps_details,
|
1144 |
"ai_details": ai_details,
|
@@ -1153,9 +1160,12 @@ def detect_ai_image(image):
|
|
1153 |
iface = gr.Interface(
|
1154 |
fn=detect_ai_image,
|
1155 |
inputs=gr.Image(type="pil"),
|
1156 |
-
outputs=
|
|
|
|
|
|
|
1157 |
title="增强型AI图像检测API",
|
1158 |
-
description="多模型集成检测图像是否由AI
|
1159 |
examples=None,
|
1160 |
allow_flagging="never"
|
1161 |
)
|
|
|
514 |
features["clothing_angle_uniformity"] = float(max_count / max(total_count, 1))
|
515 |
|
516 |
# 分析纹理的一致性
|
517 |
+
# 将图像分成小块,计算每个块的纹理特征
|
518 |
block_size = 32
|
519 |
h, w = gray.shape
|
520 |
texture_variations = []
|
|
|
534 |
|
535 |
# 计算纹理变化的熵 - 真实衣物纹理变化的熵更高
|
536 |
features["clothing_texture_entropy"] = float(stats.entropy(texture_variations + 1e-10))
|
537 |
+
# 褶皱分析 - 使用形态学操作提取可能的褶皱
|
538 |
_, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
|
539 |
kernel = np.ones((3,3), np.uint8)
|
540 |
opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
|
|
|
654 |
return features
|
655 |
|
656 |
def check_ai_specific_features(image_features):
|
657 |
+
"""检查AI生成图像的典型特征,增强对最新AI模型的检测能力"""
|
658 |
ai_score = 0
|
659 |
ai_signs = []
|
660 |
|
661 |
+
# 增加对微观纹理的分析权重
|
662 |
+
if "lbp_entropy" in image_features:
|
663 |
+
if image_features["lbp_entropy"] < 2.0:
|
664 |
+
ai_score += 0.3 # 提高权重
|
665 |
+
ai_signs.append("微观纹理熵极低,典型AI生成特征")
|
666 |
+
elif image_features["lbp_entropy"] < 3.0:
|
667 |
+
ai_score += 0.2
|
668 |
+
ai_signs.append("微观纹理熵异常低")
|
669 |
+
|
670 |
+
# 增加对频率分布各向异性的分析权重
|
671 |
+
if "freq_anisotropy" in image_features:
|
672 |
+
if image_features["freq_anisotropy"] < 0.05:
|
673 |
+
ai_score += 0.3 # 提高权重
|
674 |
+
ai_signs.append("频率分布各向异性极低,典型AI生成特征")
|
675 |
+
elif image_features["freq_anisotropy"] < 0.5:
|
676 |
+
ai_score += 0.2
|
677 |
+
ai_signs.append("频率分布各向异性异常低")
|
678 |
+
|
679 |
+
# 增加对细节一致性的分析
|
680 |
+
if "detail_scale_consistency" in image_features and "detail_spatial_std" in image_features:
|
681 |
+
if image_features["detail_scale_consistency"] < 0.2 and image_features["detail_spatial_std"] < 5:
|
682 |
+
ai_score += 0.3
|
683 |
+
ai_signs.append("细节一致性异常,典型AI生成特征")
|
684 |
+
|
685 |
+
# 检查对称性 - AI生成图像通常对称性高
|
686 |
if "horizontal_symmetry" in image_features and "vertical_symmetry" in image_features:
|
687 |
avg_symmetry = (image_features["horizontal_symmetry"] + image_features["vertical_symmetry"]) / 2
|
688 |
+
if avg_symmetry > 0.8:
|
689 |
+
ai_score += 0.15
|
690 |
ai_signs.append("图像对称性异常高")
|
691 |
elif avg_symmetry > 0.7:
|
692 |
ai_score += 0.1
|
|
|
729 |
ai_score += 0.1
|
730 |
ai_signs.append("频率分布不自然")
|
731 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
732 |
# 检查噪声频谱 - 真实照片的噪声频谱更自然
|
733 |
if "noise_spectrum_std" in image_features and image_features["noise_spectrum_std"] < 1000:
|
734 |
ai_score += 0.15
|
|
|
821 |
ai_score += 0.15
|
822 |
ai_signs.append("手部曲率变化异常均匀")
|
823 |
|
824 |
+
# 特别关注最新AI模型的特征组合
|
825 |
+
# 当多个特征同时出现时,这是强有力的AI生成证据
|
826 |
+
ai_feature_count = len(ai_signs)
|
827 |
+
if ai_feature_count >= 5: # 如果检测到多个AI特征
|
828 |
+
ai_score = max(ai_score, 0.9) # 确保AI分数很高
|
829 |
+
elif ai_feature_count >= 3:
|
830 |
+
ai_score = max(ai_score, 0.7)
|
831 |
|
832 |
return min(ai_score, 1.0), ai_signs
|
833 |
|
|
|
961 |
return min(ps_score, 1.0), ps_signs
|
962 |
|
963 |
def get_detailed_analysis(ai_probability, ps_score, beauty_score, ps_signs, ai_signs, beauty_signs, valid_models_count):
|
964 |
+
"""提供更详细的分析结果,使用二级分类框架"""
|
965 |
|
966 |
# 根据有效模型数量调整置信度描述
|
967 |
confidence_prefix = ""
|
|
|
972 |
elif valid_models_count == 1:
|
973 |
confidence_prefix = "中等置信度:"
|
974 |
|
975 |
+
# 第一级分类:AI生成 vs 真人照片
|
976 |
+
if ai_probability > 0.6: # 降低AI判定阈值,提高AI检出率
|
977 |
+
category = confidence_prefix + "AI生成图像"
|
978 |
description = "图像很可能是由AI完全生成,几乎没有真人照片的特征。"
|
979 |
+
main_category = "AI生成"
|
980 |
+
else:
|
981 |
+
# 第二级分类:真实素人 vs 修图痕迹明显
|
982 |
+
combined_edit_score = max(ps_score, beauty_score) # 取PS和美颜中的较高分
|
983 |
+
|
984 |
+
if combined_edit_score > 0.5:
|
985 |
+
category = confidence_prefix + "真人照片,修图痕迹明显"
|
986 |
+
description = "图像基本是真人照片,但经过了明显的后期处理或美颜,修饰痕迹明显。"
|
987 |
+
main_category = "真人照片-修图明显"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
988 |
else:
|
989 |
+
category = confidence_prefix + "真实素人照片"
|
990 |
+
description = "图像很可能是未经大量处理的真人照片,保留了自然的细节和特征。"
|
991 |
+
main_category = "真人照片-素人"
|
992 |
+
|
993 |
+
# 处理边界情况 - 当AI概率和修图分数都很高时
|
994 |
+
if ai_probability > 0.45 and combined_edit_score > 0.7:
|
995 |
+
# 这是一个边界情况,可能是高度修图的真人照片,也可能是AI生成的
|
996 |
+
category = confidence_prefix + "真人照片,修图痕迹明显(也可能是AI生成)"
|
997 |
+
description = "图像可能是真人照片经过大量后期处理,也可能是AI生成图像。由于现代AI技术与高度修图效果相似,难以完全区分。"
|
998 |
+
main_category = "真人照片-修图明显"
|
999 |
|
1000 |
# 添加具体的PS痕迹描述
|
1001 |
if ps_signs:
|
|
|
1015 |
else:
|
1016 |
beauty_details = "未检测到明显的美颜特征。"
|
1017 |
|
1018 |
+
return category, description, ps_details, ai_details, beauty_details, main_category
|
1019 |
|
1020 |
def detect_ai_image(image):
|
1021 |
"""主检测函数"""
|
|
|
1064 |
final_ai_probability = weighted_ai_probability / sum(m["weight"] for k, m in models.items() if m["processor"] is not None and m["model"] is not None)
|
1065 |
else:
|
1066 |
return {"error": "所有模型加载失败"}
|
1067 |
+
# 分析图像特征
|
|
|
1068 |
image_features = analyze_image_features(image)
|
1069 |
|
1070 |
# 检查AI特定特征
|
|
|
1079 |
# 应用特征权重调整AI概率
|
1080 |
adjusted_probability = final_ai_probability
|
1081 |
|
1082 |
+
# 提高AI特征分数的权重
|
1083 |
+
if ai_feature_score > 0.8: # 当AI特征非常明显时
|
1084 |
+
adjusted_probability = max(adjusted_probability, 0.8) # 大幅提高AI概率
|
1085 |
+
elif ai_feature_score > 0.6:
|
1086 |
adjusted_probability = max(adjusted_probability, 0.7)
|
1087 |
+
elif ai_feature_score > 0.4:
|
1088 |
adjusted_probability = max(adjusted_probability, 0.6)
|
1089 |
+
|
1090 |
+
# 特别关注关键AI特征
|
1091 |
+
key_ai_features_count = 0
|
1092 |
+
|
1093 |
+
# 检查微观纹理熵 - 这是AI生成的强力指标
|
1094 |
+
if "lbp_entropy" in image_features and image_features["lbp_entropy"] < 2.5:
|
1095 |
+
key_ai_features_count += 1
|
1096 |
+
adjusted_probability += 0.1
|
1097 |
+
|
1098 |
+
# 检查频率分布各向异性 - 这是AI生成的强力指标
|
1099 |
+
if "freq_anisotropy" in image_features and image_features["freq_anisotropy"] < 0.1:
|
1100 |
+
key_ai_features_count += 1
|
1101 |
+
adjusted_probability += 0.1
|
1102 |
+
|
1103 |
+
# 检查细节空间分布 - 这是AI生成的强力指标
|
1104 |
+
if "detail_spatial_std" in image_features and image_features["detail_spatial_std"] < 5:
|
1105 |
+
key_ai_features_count += 1
|
1106 |
+
adjusted_probability += 0.1
|
1107 |
+
|
1108 |
+
# 如果多个关键AI特征同时存在,这是强有力的AI生成证据
|
1109 |
+
if key_ai_features_count >= 2:
|
1110 |
+
adjusted_probability = max(adjusted_probability, 0.7)
|
1111 |
+
|
1112 |
+
# 降低美颜特征对AI判断的影响
|
1113 |
+
# 即使美颜分数高,如果AI特征也明显,仍应判定为AI生成
|
1114 |
+
if beauty_score > 0.6 and ai_feature_score > 0.7:
|
1115 |
+
# 不再降低AI概率,而是保持较高的AI概率
|
1116 |
+
pass
|
1117 |
|
1118 |
# 如果检测到衣物或手部异常,大幅提高AI概率
|
1119 |
if "clothing_angle_uniformity" in image_features and image_features["clothing_angle_uniformity"] > 0.3:
|
|
|
1122 |
if "extremity_perimeter_area_ratio" in image_features and image_features["extremity_perimeter_area_ratio"] < 0.05:
|
1123 |
adjusted_probability = max(adjusted_probability, 0.7)
|
1124 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1125 |
# 确保概率在0-1范围内
|
1126 |
adjusted_probability = min(1.0, max(0.0, adjusted_probability))
|
1127 |
|
|
|
1133 |
adjusted_probability = (adjusted_probability + ai_detector_prob * 2) / 3
|
1134 |
|
1135 |
# 获取详细分析
|
1136 |
+
category, description, ps_details, ai_details, beauty_details, main_category = get_detailed_analysis(
|
1137 |
adjusted_probability, ps_score, beauty_score, ps_signs, ai_signs, beauty_signs, valid_models
|
1138 |
)
|
1139 |
|
|
|
1145 |
"beauty_score": beauty_score,
|
1146 |
"ai_feature_score": ai_feature_score,
|
1147 |
"category": category,
|
1148 |
+
"main_category": main_category, # 添加主要分类
|
1149 |
"description": description,
|
1150 |
"ps_details": ps_details,
|
1151 |
"ai_details": ai_details,
|
|
|
1160 |
iface = gr.Interface(
|
1161 |
fn=detect_ai_image,
|
1162 |
inputs=gr.Image(type="pil"),
|
1163 |
+
outputs=[
|
1164 |
+
gr.JSON(label="详细分析结果"),
|
1165 |
+
gr.Label(label="主要分类", num_top_classes=1)
|
1166 |
+
],
|
1167 |
title="增强型AI图像检测API",
|
1168 |
+
description="多模型集成检测图像是否由AI生成或真人照片(素人/修图)",
|
1169 |
examples=None,
|
1170 |
allow_flagging="never"
|
1171 |
)
|