建模程序 多个定时程序
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

354 lines
11 KiB

import os.path
import shutil
import time
import argparse
import cv2
import numpy as np
from scipy.interpolate import CubicSpline
import sys, os
from PIL import Image, ImageEnhance
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
from ps_image_shadow_up_ag_two_d import photoshop_actions_emulation
def smootherstep(x):
"""五次平滑插值函数:更加平滑过渡"""
return x**3 * (x * (x * 6 - 15) + 10)
def perceptual_smooth_adjustment_color_blend(img, threshold=220, reduction=0.5, margin=10, saturation_sensitivity=0.3, blur_radius=5, color_blend_strength=0.5):
"""
更平滑、颜色融合感知亮度压制
- threshold: 压制起始亮度(V 通道)
- reduction: 压制强度(0-1)
- margin: 阈值过渡区间(像素亮度差)
- saturation_sensitivity: 饱和度高时减弱压制
- blur_radius: 用于颜色融合的模糊半径
- color_blend_strength: 颜色融合程度(0~1)
"""
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
h, s, v = cv2.split(hsv)
v = v.astype(np.float32)
s = s.astype(np.float32)
# 饱和度感知压制减弱
sat_weight = 1.0 - (s / 255.0 * saturation_sensitivity)
sat_weight = np.clip(sat_weight, 0.0, 1.0)
# 平滑压制权重计算
delta = v - threshold
transition = np.zeros_like(v, dtype=np.float32)
in_range = (delta > 0) & (delta < margin)
transition[in_range] = smootherstep(delta[in_range] / margin)
transition[delta >= margin] = 1.0
# 压制权重融合
weight = reduction * transition * sat_weight
# 应用压制
v_new = v - (v - threshold) * weight
v_new = np.clip(v_new, 0, 255).astype(np.uint8)
# 合成压制后的图像
adjusted_hsv = cv2.merge([h, s.astype(np.uint8), v_new])
adjusted = cv2.cvtColor(adjusted_hsv, cv2.COLOR_HSV2BGR)
# -------------------
# 融合原图模糊版 → 减少颜色突兀
# -------------------
blurred = cv2.GaussianBlur(img, (blur_radius | 1, blur_radius | 1), 0)
# 构建融合权重 mask,仅对过渡区域起作用
color_blend_mask = np.clip(weight, 0, 1) * color_blend_strength
color_blend_mask = color_blend_mask[..., None] # 扩展为 (H,W,1) 用于通道融合
# 将融合区域混合模糊
final = adjusted.astype(np.float32) * (1 - color_blend_mask) + blurred.astype(np.float32) * color_blend_mask
final = np.clip(final, 0, 255).astype(np.uint8)
return final
def process_image(input_path, output_path, threshold=210, reduction=0.6):
"""
"""
try:
img = cv2.imread(input_path)
if img is None:
raise ValueError("无法读取图像,请检查路径是否正确")
#result = perceptual_adjustment(img, threshold, reduction)
result = perceptual_smooth_adjustment_color_blend(img, threshold, reduction)
cv2.imwrite(output_path, result)
print(f"处理成功,结果已保存到: {output_path}")
return True
except Exception as e:
print(f"处理失败: {str(e)}")
return False
def sigmoid(x, center=0.0, slope=10.0):
return 1 / (1 + np.exp(-slope * (x - center)))
def reduce_highlights_lab_advanced_hsvmask(
img,
highlight_thresh=220,
strength=30,
sigma=15,
detail_boost=1.0,
preserve_local_contrast=True
):
"""
LAB高光压制 + HSV感知蒙版 + 细节保留
"""
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
V = hsv[:, :, 2].astype(np.float32)
# 1. 生成高光 mask,过渡平滑
mask = sigmoid(V, center=highlight_thresh, slope=0.05)
mask = np.clip(mask, 0, 1)
mask = cv2.GaussianBlur(mask, (0, 0), sigmaX=2)
mask_vis = (mask * 255).astype(np.uint8)
# 2. LAB 空间亮度压制
img_lab = cv2.cvtColor(img, cv2.COLOR_BGR2Lab)
L, a, b = cv2.split(img_lab)
L = L.astype(np.float32)
# 3. 模糊和细节
L_blur = cv2.GaussianBlur(L, (0, 0), sigma)
L_detail = L - L_blur
# 4. 替代方案:压制 L,但融合方式更柔和
L_target = L_blur - strength * mask
L_target = np.clip(L_target, 0, 255)
if preserve_local_contrast:
# 保留细节 + 局部对比度(避免过度平滑)
L_new = L_target + detail_boost * L_detail
else:
# 单纯压制亮度
L_new = L_target
L_new = np.clip(L_new, 0, 255).astype(np.uint8)
# 5. 合成回去
lab_new = cv2.merge([L_new, a, b])
result = cv2.cvtColor(lab_new, cv2.COLOR_Lab2BGR)
return result, mask_vis
def suppress_highlights_keep_texture(image_bgr, v_thresh=225, target_v=215, sigma=1):
""""""
image_hsv = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2HSV)
h, s, v = cv2.split(image_hsv)
v = v.astype(np.float32)
v_blur = cv2.GaussianBlur(v, (0, 0), sigmaX=sigma)
detail = v - v_blur
# 构建 soft mask(0~1),用于动态压制
mask = (v_blur > v_thresh).astype(np.float32)
# weight 越大压得越狠
weight = np.clip((v_blur - v_thresh) / 20.0, 0, 1) * mask # 20 是压制带宽
#weight =weight*1.2
# 将亮度压到 target_v 的线性混合:
v_compress = v_blur * (1 - weight) + target_v * weight
v_new = v_compress + detail
v_new = np.clip(v_new, 0, 255).astype(np.uint8)
hsv_new = cv2.merge([h, s, v_new])
result_bgr = cv2.cvtColor(hsv_new, cv2.COLOR_HSV2BGR)
return result_bgr
def correct_light_again_hsv(image_path):
img = cv2.imread(image_path)
result, mask_vis = reduce_highlights_lab_advanced_hsvmask(
img,
highlight_thresh=225,
strength=15,
sigma=10,
detail_boost=1.2
)
result_bgr= suppress_highlights_keep_texture(result)
output_image_path = image_path.replace(".jpg", "_light02.jpg")
cv2.imwrite(
output_image_path,
result_bgr
)
return output_image_path
def generate_curve_lut(x_points, y_points):
"""
输入采样点,生成 256 长度的查找表(LUT)
"""
cs = CubicSpline(x_points, y_points, bc_type='natural')
x = np.arange(256)
y = cs(x)
y = np.clip(y, 0, 255).astype(np.uint8)
return y
def apply_curve(img, lut):
"""
对图像的每个通道应用曲线 LUT(复合通道)
"""
result = cv2.LUT(img, lut)
return result
def apply_curve_up_image(image_path,image_cache_dir):
"""提亮"""
x_points = [0, 124, 255]
y_points = [0, 131, 255]
lut = generate_curve_lut(x_points, y_points)
#adjusted = apply_curve(img, lut)
image_name_result = image_path.split("/")[-1].replace(".jpg", "_up.jpg")
result_path= os.path.join(image_cache_dir,image_name_result)
image_bgr = cv2.imread(image_path)
image_rgb = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2RGB)
image_hsv = cv2.cvtColor(image_rgb, cv2.COLOR_RGB2HSV).astype(np.float32)
h, s, v = cv2.split(image_hsv)
v_mean = np.mean(v)
print(f"v_mean{v_mean}")
if v_mean < 60:
adjusted = apply_curve(image_bgr, lut)
adjusted2 = apply_curve(adjusted, lut)
cv2.imwrite(result_path, adjusted2)
return result_path
else:
image_name_result = image_path.split("/")[-1].replace(".jpg", "_o.jpg")
result_original_path = os.path.join(image_cache_dir, image_name_result)
shutil.copy(image_path,result_original_path)
return result_original_path
def apply_curve_down_image(image_path,image_cache_dir):
"""压暗"""
x_points = [0, 131, 255]
y_points = [0, 124, 255]
lut = generate_curve_lut(x_points, y_points)
# adjusted = apply_curve(img, lut)
image_name_result = image_path.split("/")[-1].replace(".jpg", "_down.jpg")
result_path= os.path.join(image_cache_dir,image_name_result)
image_bgr = cv2.imread(image_path)
image_rgb = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2RGB)
image_hsv = cv2.cvtColor(image_rgb, cv2.COLOR_RGB2HSV).astype(np.float32)
h, s, v = cv2.split(image_hsv)
v_mean = np.mean(v)
print(f"v_mean{v_mean}")
if v_mean > 110:
adjusted = apply_curve(image_bgr, lut)
adjusted2 = apply_curve(adjusted, lut)
cv2.imwrite(result_path, adjusted2)
return result_path
else:
image_name_result = image_path.split("/")[-1].replace(".jpg", "_o.jpg")
result_original_path = os.path.join(image_cache_dir, image_name_result)
shutil.copy(image_path, result_original_path)
return result_original_path
def sharpen_image(image_path, output_path):
"""
修复颜色问题的锐化处理函数
"""
# 1. 读取图片并确保RGB格式
image = cv2.imread(image_path)
if image is None:
raise ValueError("无法读取图片,请检查路径是否正确")
# 2. 转换为RGB并保持一致性
rgb_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
# 3. 使用PIL处理时不再转换
pil_img = Image.fromarray(rgb_image)
# 3.1 锐化处理
enhancer = ImageEnhance.Sharpness(pil_img)
sharpened = enhancer.enhance(2.0)
# 3.2 对比度增强
contrast_enhancer = ImageEnhance.Contrast(sharpened)
final_image = contrast_enhancer.enhance(1.2)
# 4. 转换回numpy数组
cv_image = np.array(final_image)
# 5. 修复颜色问题的非锐化掩蔽
# 先分离通道,分别处理,再合并
b, g, r = cv2.split(cv_image)
def unsharp_channel(channel):
blurred = cv2.GaussianBlur(channel, (0, 0), 3)
return cv2.addWeighted(channel, 1.5, blurred, -0.5, 0)
b_sharp = unsharp_channel(b)
g_sharp = unsharp_channel(g)
r_sharp = unsharp_channel(r)
# 合并通道
sharpened_cv = cv2.merge([b_sharp, g_sharp, r_sharp])
# 6. 保存结果(保持BGR格式)
cv2.imwrite(output_path, cv2.cvtColor(sharpened_cv, cv2.COLOR_RGB2BGR))
def correct_texture_image(input_path,image_result_dir,output_path):
""""""
image_cache_dir= os.path.join(image_result_dir,"cache")
os.makedirs(image_cache_dir, exist_ok=True)
input_path_cure_up = apply_curve_up_image(input_path,image_cache_dir)
input_path_cure_down_result = apply_curve_down_image(input_path_cure_up,image_cache_dir)
print("input_path_correct", input_path_cure_down_result)
shadow_up_path = input_path_cure_down_result.replace(".jpg", "_shadow_shadow_add_color_white_unsharp.jpg")
photoshop_actions_emulation(input_path_cure_down_result, shadow_up_path)
shutil.copy(shadow_up_path,output_path)
time.sleep(1)
try:
shutil.rmtree(image_cache_dir)
except:
print("删除文件错误")
return shadow_up_path
if __name__ == "__main__":
arg = argparse.ArgumentParser()
arg.add_argument('--input_path', type=str, default=f"")
arg.add_argument('--output_path', type=str, default=f"")
args = arg.parse_args()
image_result_dir=os.path.dirname(args.output_path)
os.makedirs(image_result_dir, exist_ok=True)
start_time= time.time()
correct_texture_image(args.input_path,image_result_dir,args.output_path)
end_time = time.time()
total_time = round(end_time - start_time, 2)
"""
DreamTech,PS动作F7两次+Shift F7一次
F7:::加暗*2
Shift F7 公仔*1
公仔: 加暗,加暗,加饱和度上色,白位加白,锐化
"""