diff --git a/apps/white_purification_v3.py b/apps/white_purification_v3.py new file mode 100644 index 0000000..7732916 --- /dev/null +++ b/apps/white_purification_v3.py @@ -0,0 +1,157 @@ +import os.path +import shutil +import time +import argparse +import cv2 +import numpy as np +from fix_up_color_two import remove_gray_and_sharpening +from ps_image_shadow_up_ag import photoshop_actions_emulation + +def perceptual_adjustment(img, threshold=220, reduction=0.5): + hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) + h, s, v = cv2.split(hsv) + + saturation_weights = 1 - (s.astype(np.float32) / 255 * 0.01) + + adjusted_v = np.where( + v > threshold, + threshold + (v - threshold) * (1 - reduction * saturation_weights), + v + ) + + return cv2.cvtColor(cv2.merge([h, s, adjusted_v.astype(np.uint8)]), cv2.COLOR_HSV2BGR) + + +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) + 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): + """ + """ + + hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) + V = hsv[:, :, 2].astype(np.float32) + + 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) + + img_lab = cv2.cvtColor(img, cv2.COLOR_BGR2Lab) + L, a, b = cv2.split(img_lab) + L = L.astype(np.float32) + + L_blur = cv2.GaussianBlur(L, (0, 0), sigma) + L_detail = L - L_blur + + L_dark = np.clip(L_blur - strength * mask, 0, 255) + L_new = np.clip(L_dark + L_detail, 0, 255).astype(np.uint8) + + 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=230, + strength=7, + sigma=3 + ) + 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 correct_texture_image(input_path,image_result_dir,output_path): + """""" + #input_path = os.path.join(image_in_dir, image_name) + image_name= input_path.split("/")[-1] + params = { + 'threshold': 220, + 'reduction': 0.6 + } + image_cache_dir= os.path.join(image_result_dir,"cache") + os.makedirs(image_cache_dir, exist_ok=True) + image_light_down_fix_up_path = remove_gray_and_sharpening(input_path, image_cache_dir) + output_light_up_path = image_light_down_fix_up_path.replace(".jpg", "_light_down.jpg") + process_image(image_light_down_fix_up_path, output_light_up_path, **params) + output_result_image_path=correct_light_again_hsv(output_light_up_path) + shutil.copy(output_result_image_path,output_path) + time.sleep(1) + try: + os.remove(image_light_down_fix_up_path) + os.remove(output_light_up_path) + os.remove(output_result_image_path) + except: + print("删除文件错误") + + + +if __name__ == "__main__": + arg = argparse.ArgumentParser() + arg.add_argument("-i","--image_path", type=str, default="") + args = arg.parse_args() + image_result_dir=os.path.dirname(args.image_path) + os.makedirs(image_result_dir, exist_ok=True) + + start_time= time.time() + correct_texture_image(args.image_path,image_result_dir,args.image_path) + end_time = time.time() + total_time = round(end_time - start_time, 2) + print(f"处理成功,耗时 {total_time} 秒,") + """ + 1、暗部提亮->白色提纯(220)->高光压暗->二次亮度调整 + """ +