From 276518f7dec747a407acc486173aa27d1e52e06d Mon Sep 17 00:00:00 2001 From: jinye_huang Date: Tue, 6 May 2025 17:11:29 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8A=A0=E5=85=A5=E9=9A=8F=E6=9C=BA=E9=80=8F?= =?UTF-8?q?=E6=98=8E=E5=BA=95=E5=99=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- utils/poster_notes_creator.py | 174 ++++++++++++++++++++++------------ 1 file changed, 116 insertions(+), 58 deletions(-) diff --git a/utils/poster_notes_creator.py b/utils/poster_notes_creator.py index 6e6ceb9..b2d0423 100644 --- a/utils/poster_notes_creator.py +++ b/utils/poster_notes_creator.py @@ -2,7 +2,7 @@ import os import random import logging import json -from PIL import Image +from PIL import Image, ImageChops import traceback from typing import List, Tuple, Dict, Any, Optional import concurrent.futures @@ -512,63 +512,6 @@ class PosterNotesCreator: logger.error(f"智能裁剪+重缩放时出错: {e}") return image # 出错时返回原图 - def optimize_anti_hash_methods(self, image: Image.Image, strength: str = "medium") -> Image.Image: - """优化后的哈希对抗方法,专注于裁剪缩放和DCT噪声""" - logger.info(f"--- 开始优化抗哈希方法 (强度: {strength}) - 新策略 ---") - original_image_for_logging = image.copy() - - # --- 参数定义 --- - if strength == "low": - phash_intensity = 0.06 # 轻微DCT噪声 - color_hist_strength = 0.02 # 轻微颜色扰动 - apply_crop_resize = True # 应用裁剪缩放 - elif strength == "high": - phash_intensity = 0.20 # 较强DCT噪声 - color_hist_strength = 0.06 # 较强颜色扰动 - apply_crop_resize = True # 应用裁剪缩放 - else: # medium - phash_intensity = 0.12 # 中等DCT噪声 - color_hist_strength = 0.04 # 中等颜色扰动 - apply_crop_resize = True # 应用裁剪缩放 - - logger.debug(f"参数: pHash强度={phash_intensity:.2f}, 颜色强度={color_hist_strength:.2f}, 应用裁剪缩放={apply_crop_resize}") - - processed_image = image # 从原图开始 - - # 1. 智能裁剪 + 重缩放 (策略C) - 作为第一步,改变像素基准 - if apply_crop_resize: - processed_image = self.apply_smart_crop_resize(processed_image, strength) - # 内部已有日志 - - # 2. 强化的pHash对抗方法 (策略A) - logger.debug(f"应用 pHash 对抗 (强化DCT噪声), 强度={phash_intensity:.2f}") - processed_image = self.add_phash_noise(processed_image, intensity=phash_intensity) - # 内部已有日志 - - # 3. 保留轻微的颜色直方图扰动 (可选,影响相对小) - if color_hist_strength > 0: - logger.debug(f"应用颜色直方图扰动, 强度={color_hist_strength:.3f}") - processed_image = self.perturb_color_histogram(processed_image, strength=color_hist_strength) - # 内部已有日志 - - # --- 移除了之前的 aHash块, dHash线, 区域变换, 高斯噪声等 --- - logger.debug("移除了 aHash块, dHash线, 区域变换, 高斯噪声等局部微扰方法。") - - # 对比修改前后 - try: - diff = ImageChops.difference(original_image_for_logging, processed_image).getbbox() - if diff: - logger.info(f"图像已修改。差异区域: {diff}") - else: - logger.warning("!!!优化方法似乎未修改图像!!!") - except ValueError: # 如果图像模式不同(例如灰度vs彩色),会引发ValueError - logger.warning("无法比较图像差异:模式可能不同。") - except Exception as log_e: - logger.warning(f"无法比较图像差异: {log_e}") - - logger.info(f"--- 完成优化抗哈希方法 (强度: {strength}) - 新策略 ---") - return processed_image - def perturb_color_histogram(self, image: Image.Image, strength: float = 0.03) -> Image.Image: """ 扰动图像的颜色直方图,对抗基于颜色统计的图像匹配 @@ -668,6 +611,121 @@ class PosterNotesCreator: logger.error(f"移除元数据时出错: {e}") return image # 出错时返回原图 + def apply_overlay_noise(self, image: Image.Image, alpha: int = 10, noise_type: str = 'uniform') -> Image.Image: + """ + 在图像上叠加一个低透明度的噪声图层 + + Args: + image: 输入图像 + alpha: 叠加噪声图层的 Alpha 值 (0-255) + noise_type: 'gaussian' 或 'uniform' + + Returns: + 叠加噪声后的图像 + """ + try: + logger.debug(f"应用低透明度噪声叠加: alpha={alpha}, type={noise_type}") + # 确保图像是 RGBA 模式以处理透明度 + if image.mode != 'RGBA': + base_image = image.convert('RGBA') + else: + base_image = image.copy() # 操作副本 + + width, height = base_image.size + + # 创建噪声图层 (灰度噪声即可) + if noise_type == 'gaussian': + # 生成范围在 0-255 的高斯噪声,均值128 + noise_array = np.random.normal(loc=128, scale=40, size=(height, width)).clip(0, 255).astype(np.uint8) + else: # uniform + noise_array = np.random.randint(0, 256, size=(height, width), dtype=np.uint8) + + noise_image = Image.fromarray(noise_array, mode='L') + + # 将噪声灰度图转换为 RGBA,并设置 alpha 通道 + noise_rgba = noise_image.convert('RGBA') + # 创建一个全为指定 alpha 值的通道 + alpha_channel = Image.new('L', noise_image.size, alpha) + noise_rgba.putalpha(alpha_channel) + + # 使用 alpha_composite 进行混合叠加 + # alpha_composite 要求两个输入都是 RGBA + combined_image = Image.alpha_composite(base_image, noise_rgba) + + # 通常我们希望最终结果是 RGB,所以转换回去 + # 如果原图就是 RGBA 且需要保留透明度,则省略此步 + final_image = combined_image.convert('RGB') + + logger.debug("低透明度噪声叠加应用成功。") + return final_image + + except Exception as e: + logger.error(f"应用叠加噪声时出错: {e}") + logger.error(traceback.format_exc()) # 打印详细错误 + return image # 出错时返回原图 + + def optimize_anti_hash_methods(self, image: Image.Image, strength: str = "medium") -> Image.Image: + """优化后的哈希对抗方法,策略: 裁剪缩放 + DCT噪声 + 叠加噪声""" + logger.info(f"--- 开始优化抗哈希方法 (强度: {strength}) - 叠加噪声策略 ---") + original_image_for_logging = image.copy() + + # --- 参数定义 --- + if strength == "low": + phash_intensity = 0.06 # 轻微DCT噪声 + color_hist_strength = 0.02 # 轻微颜色扰动 + apply_crop_resize = True # 应用裁剪缩放 + noise_alpha = random.randint(5, 8) # 低透明度噪声 + elif strength == "high": + phash_intensity = 0.20 # 较强DCT噪声 + color_hist_strength = 0.06 # 较强颜色扰动 + apply_crop_resize = True # 应用裁剪缩放 + noise_alpha = random.randint(12, 18) # 较高透明度噪声 + else: # medium + phash_intensity = 0.12 # 中等DCT噪声 + color_hist_strength = 0.04 # 中等颜色扰动 + apply_crop_resize = True # 应用裁剪缩放 + noise_alpha = random.randint(8, 12) # 中等透明度噪声 + + logger.debug(f"参数: pHash强度={phash_intensity:.2f}, 颜色强度={color_hist_strength:.2f}, 应用裁剪缩放={apply_crop_resize}, 噪声Alpha={noise_alpha}") + + processed_image = image # 从原图开始 + + # 1. 智能裁剪 + 重缩放 (策略C) + if apply_crop_resize: + processed_image = self.apply_smart_crop_resize(processed_image, strength) + + # 2. 强化的pHash对抗方法 (策略A) + logger.debug(f"应用 pHash 对抗 (强化DCT噪声), 强度={phash_intensity:.2f}") + processed_image = self.add_phash_noise(processed_image, intensity=phash_intensity) + + # 3. 保留轻微的颜色直方图扰动 + if color_hist_strength > 0: + logger.debug(f"应用颜色直方图扰动, 强度={color_hist_strength:.3f}") + processed_image = self.perturb_color_histogram(processed_image, strength=color_hist_strength) + + # 4. 应用低透明度噪声叠加 (新策略核心) + if noise_alpha > 0: + processed_image = self.apply_overlay_noise(processed_image, alpha=noise_alpha, noise_type='uniform') # 先用 uniform 试试 + # 内部已有日志 + + # --- 移除之前的 aHash块, dHash线, 区域变换, 高斯噪声等 --- + logger.debug("已移除 aHash/dHash特定对抗、区域变换、高斯噪声等。") + + # 对比修改前后 + try: + diff = ImageChops.difference(original_image_for_logging.convert('RGB'), processed_image.convert('RGB')).getbbox() # 确保模式一致 + if diff: + logger.info(f"图像已修改。差异区域: {diff}") + else: + logger.warning("!!!优化方法似乎未修改图像!!!") + except ValueError: + logger.warning("无法比较图像差异:模式可能不同或错误。") + except Exception as log_e: + logger.warning(f"无法比较图像差异: {log_e}") + + logger.info(f"--- 完成优化抗哈希方法 (强度: {strength}) - 叠加噪声策略 ---") + return processed_image + def optimized_process_image( self, image: Image.Image,