对选图模块增加了模糊匹配的功能
This commit is contained in:
parent
543cbe3152
commit
5a3c638a3f
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -6,11 +6,14 @@ import math
|
||||
from pathlib import Path
|
||||
from PIL import Image, ImageDraw, ImageEnhance, ImageFilter, ImageOps
|
||||
import logging # Import logging module
|
||||
import re
|
||||
|
||||
class ImageCollageCreator:
|
||||
def __init__(self, ):
|
||||
"""初始化拼图创建器"""
|
||||
|
||||
self.collage_style = None
|
||||
self.created_collages = []
|
||||
|
||||
# 定义可用拼接样式
|
||||
self.collage_styles = [
|
||||
"grid_2x2", # 标准2x2网格
|
||||
@ -133,33 +136,121 @@ class ImageCollageCreator:
|
||||
print(f"增强图片效果时出错: {str(e)}")
|
||||
return img
|
||||
|
||||
def create_collage_with_style(self, input_dir, style=None, target_size=None):
|
||||
"""创建指定样式的拼接画布
|
||||
|
||||
参数:
|
||||
input_dir: 输入图片目录路径
|
||||
style: 拼贴样式,如不指定则随机选择
|
||||
target_size: 目标尺寸,默认为(900, 1200)
|
||||
|
||||
返回:
|
||||
tuple: (拼贴图, 选择的图片名称列表),如果创建失败则返回(None, [])
|
||||
def find_directory_fuzzy_match(self, base_dir, target_name):
|
||||
"""
|
||||
logging.info(f"--- Starting Collage Creation for Directory: {input_dir} ---") # Start Log
|
||||
对图片目录进行模糊匹配,查找最匹配目标名称的目录
|
||||
|
||||
Args:
|
||||
base_dir: 基础目录路径
|
||||
target_name: 目标对象名称
|
||||
|
||||
Returns:
|
||||
tuple: (最佳匹配目录路径, 匹配分数) 如果没有匹配则返回 (None, 0)
|
||||
"""
|
||||
logging.info(f"尝试对图片目录进行模糊匹配: {target_name}")
|
||||
|
||||
try:
|
||||
# 设置默认尺寸为3:4比例
|
||||
if target_size is None:
|
||||
target_size = (900, 1200) # 3:4比例
|
||||
# 1. 获取base_dir下的所有目录
|
||||
all_dirs = [d for d in os.listdir(base_dir)
|
||||
if os.path.isdir(os.path.join(base_dir, d))]
|
||||
logging.info(f"找到 {len(all_dirs)} 个图片目录可用于模糊匹配")
|
||||
|
||||
if not all_dirs:
|
||||
logging.warning(f"基础目录 {base_dir} 下没有可用于匹配的子目录")
|
||||
return None, 0
|
||||
|
||||
# 2. 提取对象名称中的关键词
|
||||
# 首先通过常见分隔符分割(+、空格、_、-等)
|
||||
parts = re.split(r'[+\s_\-]', target_name)
|
||||
keywords = []
|
||||
for part in parts:
|
||||
# 只保留长度大于1的有意义关键词
|
||||
if len(part) > 1:
|
||||
keywords.append(part)
|
||||
|
||||
# 尝试匹配更短的语义单元(例如中文的2-3个字的词语)
|
||||
for i in range(len(target_name) - 1):
|
||||
keyword = target_name[i:i+2] # 提取2个字符
|
||||
if len(keyword) == 2 and all('\u4e00' <= c <= '\u9fff' for c in keyword):
|
||||
keywords.append(keyword)
|
||||
|
||||
logging.info(f"用于目录模糊匹配的关键词: {keywords}")
|
||||
|
||||
# 3. 对每个目录进行评分
|
||||
dir_scores = {}
|
||||
for directory in all_dirs:
|
||||
score = 0
|
||||
dir_lower = directory.lower()
|
||||
# 为每个匹配的关键词增加分数
|
||||
for keyword in keywords:
|
||||
if keyword.lower() in dir_lower:
|
||||
score += 1
|
||||
|
||||
# 如果没有指定样式,随机选择一种
|
||||
if style is None or style not in self.collage_styles:
|
||||
style = random.choice(self.collage_styles)
|
||||
# 如果得分大于0(至少匹配一个关键词),记录该目录
|
||||
if score > 0:
|
||||
dir_scores[directory] = score
|
||||
|
||||
# 4. 选择得分最高的目录
|
||||
if dir_scores:
|
||||
best_match = max(dir_scores.items(), key=lambda x: x[1])
|
||||
found_dir = best_match[0]
|
||||
score = best_match[1]
|
||||
logging.info(f"模糊匹配成功!匹配目录: {found_dir},匹配分数: {score}")
|
||||
return os.path.join(base_dir, found_dir), score
|
||||
else:
|
||||
logging.warning(f"模糊匹配未找到任何包含关键词的目录")
|
||||
return None, 0
|
||||
|
||||
except Exception as e:
|
||||
logging.exception(f"目录模糊匹配过程中出错: {e}")
|
||||
return None, 0
|
||||
|
||||
def create_collage_with_style(self, input_dir, style=None, target_size=None):
|
||||
"""
|
||||
创建特定样式的照片拼贴。
|
||||
如果input_dir不存在,会尝试进行模糊匹配。
|
||||
|
||||
Args:
|
||||
input_dir: 包含图片的目录路径或目标对象名称
|
||||
style: 拼贴画样式,例如"grid_2x2", "overlap"等
|
||||
target_size: 拼贴画目标尺寸,例如(900, 1200)
|
||||
|
||||
Returns:
|
||||
tuple: (PIL.Image 拼贴画对象, 使用的图片文件列表)
|
||||
"""
|
||||
try:
|
||||
# 使用默认样式如果未指定
|
||||
if style is None:
|
||||
if self.collage_style is None:
|
||||
style = "grid_2x2"
|
||||
else:
|
||||
style = self.collage_style
|
||||
logging.info(f"Using collage style: {style}")
|
||||
|
||||
# 使用默认尺寸如果未指定
|
||||
if target_size is None:
|
||||
target_size = (900, 1200) # 默认尺寸
|
||||
logging.info(f"Using collage style: {style} with target size: {target_size}")
|
||||
|
||||
# 检查目录是否存在
|
||||
if not os.path.exists(input_dir):
|
||||
logging.error(f"Input directory does not exist: {input_dir}")
|
||||
return None, []
|
||||
|
||||
# 检查输入目录是否存在
|
||||
if not os.path.exists(input_dir) or not os.path.isdir(input_dir):
|
||||
# 尝试从输入路径获取基础目录和对象名称
|
||||
base_dir = os.path.dirname(input_dir)
|
||||
object_name = os.path.basename(input_dir)
|
||||
|
||||
# 如果基础目录存在,尝试模糊匹配
|
||||
if os.path.exists(base_dir) and os.path.isdir(base_dir):
|
||||
matched_dir, score = self.find_directory_fuzzy_match(base_dir, object_name)
|
||||
if matched_dir and score > 0:
|
||||
logging.info(f"使用模糊匹配的图片目录: {matched_dir}")
|
||||
input_dir = matched_dir
|
||||
else:
|
||||
logging.error(f"无法找到匹配的图片目录: {input_dir}")
|
||||
return None, []
|
||||
else:
|
||||
logging.error(f"输入目录不存在且无法进行模糊匹配: {input_dir}")
|
||||
return None, []
|
||||
|
||||
# 支持的图片格式
|
||||
image_extensions = ('.jpg', '.jpeg', '.png', '.bmp')
|
||||
|
||||
@ -690,74 +781,82 @@ class ImageCollageCreator:
|
||||
|
||||
def process_directory(directory_path, style=None, target_size=(900, 1200), output_count=1):
|
||||
"""
|
||||
处理指定目录中的图片,创建指定数量的拼贴图。
|
||||
处理目录中的图片并创建指定数量的拼贴图
|
||||
|
||||
参数:
|
||||
directory_path: 包含图片的目录路径
|
||||
target_size: 拼贴图目标尺寸,默认为 (900, 1200)
|
||||
output_count: 需要生成的拼贴图数量,默认为 1
|
||||
|
||||
返回:
|
||||
tuple: (拼贴图列表, 使用的图片名称列表的列表),如果生成失败,返回 ([], [])
|
||||
拼贴图列表是PIL.Image对象列表
|
||||
图片名称列表是一个列表的列表,每个子列表包含一张拼贴图使用的图片文件名
|
||||
如果给定的目录不存在,会尝试进行模糊匹配。
|
||||
|
||||
Args:
|
||||
directory_path: 图片目录路径或目标对象名称
|
||||
style: 拼贴画样式,例如"grid_2x2",如果为None则随机选择
|
||||
target_size: 拼贴画尺寸,默认为(900, 1200)
|
||||
output_count: 要生成的拼贴画数量
|
||||
|
||||
Returns:
|
||||
list: 成功创建的拼贴图列表 (PIL Image对象)
|
||||
"""
|
||||
logging.info(f"处理目录中的图片并创建 {output_count} 个拼贴图: {directory_path}")
|
||||
|
||||
# 创建 ImageCollageCreator 实例
|
||||
# 创建拼贴图实例
|
||||
collage_creator = ImageCollageCreator()
|
||||
collage_images = []
|
||||
used_image_names = [] # 存储每个拼贴图使用的图片文件名
|
||||
|
||||
# 检查目录是否存在
|
||||
if not os.path.exists(directory_path):
|
||||
logging.error(f"目录不存在: {directory_path}")
|
||||
return [], []
|
||||
# 如果指定了样式,设置样式
|
||||
if style:
|
||||
collage_creator.set_collage_style(style)
|
||||
|
||||
# 支持的图片格式
|
||||
image_extensions = ('.jpg', '.jpeg', '.png', '.bmp')
|
||||
# 检查目录是否存在
|
||||
if not os.path.exists(directory_path) or not os.path.isdir(directory_path):
|
||||
# 尝试从路径获取基础目录和对象名称
|
||||
base_dir = os.path.dirname(directory_path)
|
||||
object_name = os.path.basename(directory_path)
|
||||
|
||||
# 如果基础目录存在,尝试模糊匹配
|
||||
if os.path.exists(base_dir) and os.path.isdir(base_dir):
|
||||
matched_dir, score = collage_creator.find_directory_fuzzy_match(base_dir, object_name)
|
||||
if matched_dir and score > 0:
|
||||
logging.info(f"使用模糊匹配的图片目录: {matched_dir}")
|
||||
directory_path = matched_dir
|
||||
else:
|
||||
logging.error(f"无法找到匹配的图片目录: {directory_path}")
|
||||
return []
|
||||
else:
|
||||
logging.error(f"输入目录不存在且无法进行模糊匹配: {directory_path}")
|
||||
return []
|
||||
|
||||
# 获取目录中的所有有效图片文件
|
||||
# 获取有效图片文件列表
|
||||
image_extensions = ('.jpg', '.jpeg', '.png', '.webp', '.bmp', '.gif')
|
||||
try:
|
||||
all_files = os.listdir(directory_path)
|
||||
all_images_names = [f for f in all_files
|
||||
if f.lower().endswith(image_extensions) and os.path.isfile(os.path.join(directory_path, f))]
|
||||
|
||||
if not all_images_names:
|
||||
logging.error(f"目录中没有有效的图片文件: {directory_path}")
|
||||
return [], []
|
||||
|
||||
logging.info(f"目录中找到 {len(all_images_names)} 个有效图片文件")
|
||||
except Exception as e:
|
||||
logging.exception(f"列出目录内容时出错: {e}")
|
||||
return [], []
|
||||
image_files = [f for f in all_files
|
||||
if f.lower().endswith(image_extensions) and os.path.isfile(os.path.join(directory_path, f))]
|
||||
logging.info(f"目录中找到 {len(image_files)} 个有效图片文件")
|
||||
|
||||
# 尝试创建请求数量的拼贴图
|
||||
if not image_files:
|
||||
logging.warning(f"目录中未找到有效图片: {directory_path}")
|
||||
return []
|
||||
except Exception as e:
|
||||
logging.exception(f"无法读取目录 {directory_path}: {e}")
|
||||
return []
|
||||
|
||||
# 创建指定数量的拼贴图
|
||||
created_collages = []
|
||||
for i in range(output_count):
|
||||
try:
|
||||
# 创建拼贴图,使用指定样式
|
||||
collage, selected_images_names = collage_creator.create_collage_with_style(
|
||||
directory_path,
|
||||
style=style,
|
||||
target_size=target_size
|
||||
)
|
||||
# 如果指定了样式,则使用指定样式;否则让create_collage_with_style自行选择
|
||||
if style:
|
||||
collage, used_images = collage_creator.create_collage_with_style(directory_path, style=style, target_size=target_size)
|
||||
else:
|
||||
# 随机选择一种样式
|
||||
available_styles = collage_creator.collage_styles
|
||||
random_style = random.choice(available_styles)
|
||||
collage, used_images = collage_creator.create_collage_with_style(directory_path, style=random_style, target_size=target_size)
|
||||
|
||||
if collage:
|
||||
collage_images.append(collage)
|
||||
|
||||
# 从输出日志中解析出使用的图片名称
|
||||
# 由于我们修改了create_collage_with_style来打印选择的图片
|
||||
# 可能需要进一步修改为直接返回选择的图片
|
||||
used_image_names.append(selected_images_names)
|
||||
|
||||
logging.info(f"成功创建拼贴图 {i+1}/{output_count}")
|
||||
else:
|
||||
logging.error(f"无法创建拼贴图 {i+1}/{output_count}")
|
||||
except Exception as e:
|
||||
logging.exception(f"创建拼贴图 {i+1}/{output_count} 时发生异常: {e}")
|
||||
|
||||
logging.info(f"已处理目录 {directory_path},成功创建 {len(collage_images)}/{output_count} 个拼贴图")
|
||||
return collage_images, used_image_names
|
||||
if collage:
|
||||
created_collages.append(collage)
|
||||
logging.info(f"成功创建拼贴图 {len(created_collages)}/{output_count}")
|
||||
else:
|
||||
logging.warning(f"创建拼贴图 {i+1}/{output_count} 失败")
|
||||
|
||||
logging.info(f"已处理目录 {directory_path},成功创建 {len(created_collages)}/{output_count} 个拼贴图")
|
||||
return created_collages
|
||||
|
||||
def find_main_subject(image):
|
||||
# ... (keep the existing implementation) ...
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"date": "4月29日,4月30日, 4月28日, 5月1日",
|
||||
"num": 10,
|
||||
"variants": 5,
|
||||
"num": 15,
|
||||
"variants": 15,
|
||||
"topic_temperature": 0.2,
|
||||
"topic_top_p": 0.3,
|
||||
"topic_presence_penalty": 1.5,
|
||||
@ -42,13 +42,13 @@
|
||||
{
|
||||
"type": "Object",
|
||||
"file_path": [
|
||||
"./resource/Object/安吉银润锦江城堡酒店.txt"
|
||||
"./resource/Object/美的鹭湖鹭栖台酒店.txt"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "Description",
|
||||
"file_path": [
|
||||
"./resource/Object/安吉银润锦江城堡酒店.txt"
|
||||
"./resource/Object/美的鹭湖鹭栖台酒店.txt"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user