From e6d8bee27b3263bfc3143e883ad32a9499d7a173 Mon Sep 17 00:00:00 2001 From: Ze-Yi LIN <58305964+Zeyi-Lin@users.noreply.github.com> Date: Sun, 15 Sep 2024 02:45:37 +0800 Subject: [PATCH] feat: beauty brightness sharpen contrast (#127) * finish * add contrast * add sharpen --- demo/locals.py | 42 +++++++++ demo/processor.py | 14 ++- demo/ui.py | 45 ++++++++++ hivision/creator/__init__.py | 11 ++- hivision/creator/context.py | 18 ++++ hivision/plugin/beauty/base_adjust.py | 121 ++++++++++++++++++++++++++ hivision/plugin/beauty/brightness.py | 31 ------- hivision/plugin/beauty/handler.py | 38 ++++++-- 8 files changed, 281 insertions(+), 39 deletions(-) create mode 100644 hivision/plugin/beauty/base_adjust.py delete mode 100644 hivision/plugin/beauty/brightness.py diff --git a/demo/locals.py b/demo/locals.py index 84d166c0..665878e1 100644 --- a/demo/locals.py +++ b/demo/locals.py @@ -564,4 +564,46 @@ "label": "미백 강도", }, }, + "brightness_strength": { + "en": { + "label": "brightness strength", + }, + "zh": { + "label": "亮度强度", + }, + "ja": { + "label": "明るさの強さ", + }, + "ko": { + "label": "밝기 강도", + }, + }, + "contrast_strength": { + "en": { + "label": "contrast strength", + }, + "zh": { + "label": "对比度强度", + }, + "ja": { + "label": "コントラスト強度", + }, + "ko": { + "label": "대비 강도", + }, + }, + "sharpen_strength": { + "en": { + "label": "sharpen strength", + }, + "zh": { + "label": "锐化强度", + }, + "ja": { + "label": "シャープ化強度", + }, + "ko": { + "label": "샤ープ 강도", + }, + }, } diff --git a/demo/processor.py b/demo/processor.py index a9ad8d30..2df08941 100644 --- a/demo/processor.py +++ b/demo/processor.py @@ -49,6 +49,9 @@ def process( whitening_strength=0, image_dpi_option=False, custom_image_dpi=None, + brightness_strength=0, + contrast_strength=0, + sharpen_strength=0, ): # 初始化参数 top_distance_min = top_distance_max - 0.02 @@ -103,6 +106,9 @@ def process( top_distance_max, top_distance_min, whitening_strength, + brightness_strength, + contrast_strength, + sharpen_strength, ) except (FaceError, APIError): return self._handle_photo_generation_error(language) @@ -185,7 +191,7 @@ def _process_color_mode( def _generate_id_photo( self, - creator, + creator: IDCreator, input_image, idphoto_json, language, @@ -193,6 +199,9 @@ def _generate_id_photo( top_distance_max, top_distance_min, whitening_strength, + brightness_strength, + contrast_strength, + sharpen_strength, ): """生成证件照""" change_bg_only = ( @@ -205,6 +214,9 @@ def _generate_id_photo( head_measure_ratio=head_measure_ratio, head_top_range=(top_distance_max, top_distance_min), whitening_strength=whitening_strength, + brightness_strength=brightness_strength, + contrast_strength=contrast_strength, + sharpen_strength=sharpen_strength, ) def _handle_photo_generation_error(self, language): diff --git a/demo/ui.py b/demo/ui.py index f74abeb2..fbe5b862 100644 --- a/demo/ui.py +++ b/demo/ui.py @@ -160,6 +160,7 @@ def create_ui( with gr.Tab( LOCALES["beauty_tab"][DEFAULT_LANG]["label"] ) as beauty_parameter_tab: + # 美白组件 whitening_option = gr.Slider( label=LOCALES["whitening_strength"][DEFAULT_LANG]["label"], minimum=0, @@ -169,6 +170,35 @@ def create_ui( interactive=True, ) + with gr.Row(): + # 亮度组件 + brightness_option = gr.Slider( + label=LOCALES["brightness_strength"][DEFAULT_LANG]["label"], + minimum=-5, + maximum=25, + value=0, + step=1, + interactive=True, + ) + # 对比度组件 + contrast_option = gr.Slider( + label=LOCALES["contrast_strength"][DEFAULT_LANG]["label"], + minimum=-10, + maximum=50, + value=0, + step=1, + interactive=True, + ) + # 锐化组件 + sharpen_option = gr.Slider( + label=LOCALES["sharpen_strength"][DEFAULT_LANG]["label"], + minimum=0, + maximum=5, + value=0, + step=1, + interactive=True, + ) + # TAB4 - 水印 with gr.Tab( LOCALES["watermark_tab"][DEFAULT_LANG]["label"] @@ -431,6 +461,15 @@ def change_language(language): custom_image_dpi_size: gr.update( label=LOCALES["image_dpi"][language]["label"] ), + brightness_option: gr.update( + label=LOCALES["brightness_strength"][language]["label"] + ), + contrast_option: gr.update( + label=LOCALES["contrast_strength"][language]["label"] + ), + sharpen_option: gr.update( + label=LOCALES["sharpen_strength"][language]["label"] + ), } def change_color(colors, lang): @@ -507,6 +546,9 @@ def change_image_dpi(image_dpi_option, lang): whitening_option, image_dpi_options, custom_image_dpi_size, + brightness_option, + contrast_option, + sharpen_option, ], ) @@ -564,6 +606,9 @@ def change_image_dpi(image_dpi_option, lang): whitening_option, image_dpi_options, custom_image_dpi_size, + brightness_option, + contrast_option, + sharpen_option, ], outputs=[ img_output_standard, diff --git a/hivision/creator/__init__.py b/hivision/creator/__init__.py index 88468758..8a8c64e1 100644 --- a/hivision/creator/__init__.py +++ b/hivision/creator/__init__.py @@ -45,7 +45,6 @@ def __init__(self): self.matting_handler: ContextHandler = extract_human self.detection_handler: ContextHandler = detect_face_mtcnn self.beauty_handler: ContextHandler = beauty_face - # 上下文 self.ctx = None @@ -60,6 +59,9 @@ def __call__( head_top_range: float = (0.12, 0.1), face: Tuple[int, int, int, int] = None, whitening_strength: int = 0, + brightness_strength: int = 0, + contrast_strength: int = 0, + sharpen_strength: int = 0, ) -> Result: """ 证件照处理函数 @@ -72,7 +74,9 @@ def __call__( :param head_top_range: 头距离顶部的比例(max,min) :param face: 人脸坐标 :param whitening_strength: 美白强度 - + :param brightness_strength: 亮度强度 + :param contrast_strength: 对比度强度 + :param sharpen_strength: 锐化强度 :return: 返回处理后的证件照和一系列参数 """ # 0.初始化上下文 @@ -85,6 +89,9 @@ def __call__( crop_only=crop_only, face=face, whitening_strength=whitening_strength, + brightness_strength=brightness_strength, + contrast_strength=contrast_strength, + sharpen_strength=sharpen_strength, ) self.ctx = Context(params) diff --git a/hivision/creator/context.py b/hivision/creator/context.py index f59cae35..82bb5bb2 100644 --- a/hivision/creator/context.py +++ b/hivision/creator/context.py @@ -22,6 +22,9 @@ def __init__( head_top_range: float = (0.12, 0.1), face: Tuple[int, int, int, int] = None, whitening_strength: int = 0, + brightness_strength: int = 0, + contrast_strength: int = 0, + sharpen_strength: int = 0, ): self.__size = size self.__change_bg_only = change_bg_only @@ -31,6 +34,9 @@ def __init__( self.__head_top_range = head_top_range self.__face = face self.__whitening_strength = whitening_strength + self.__brightness_strength = brightness_strength + self.__contrast_strength = contrast_strength + self.__sharpen_strength = sharpen_strength @property def size(self): @@ -64,6 +70,18 @@ def face(self): def whitening_strength(self): return self.__whitening_strength + @property + def brightness_strength(self): + return self.__brightness_strength + + @property + def contrast_strength(self): + return self.__contrast_strength + + @property + def sharpen_strength(self): + return self.__sharpen_strength + class Result: def __init__( diff --git a/hivision/plugin/beauty/base_adjust.py b/hivision/plugin/beauty/base_adjust.py new file mode 100644 index 00000000..1518e4ea --- /dev/null +++ b/hivision/plugin/beauty/base_adjust.py @@ -0,0 +1,121 @@ +""" +亮度、对比度、锐化调整模块 +""" + +import cv2 +import numpy as np + + +def adjust_brightness_contrast_sharpen( + image, + brightness_factor=0, + contrast_factor=0, + sharpen_strength=0, +): + """ + 调整图像的亮度和对比度。 + + 参数: + image (numpy.ndarray): 输入的图像数组。 + brightness_factor (float): 亮度调整因子。大于0增加亮度,小于0降低亮度。 + contrast_factor (float): 对比度调整因子。大于0增加对比度,小于0降低对比度。 + + 返回: + numpy.ndarray: 调整亮度和对比度后的图像。 + """ + if brightness_factor == 0 and contrast_factor == 0 and sharpen_strength == 0: + return image.copy() + + adjusted_image = image.copy() + + # 将亮度因子转换为调整值 + alpha = 1.0 + (contrast_factor / 100.0) + beta = brightness_factor + + # 使用 cv2.convertScaleAbs 函数调整亮度和对比度 + adjusted_image = cv2.convertScaleAbs(adjusted_image, alpha=alpha, beta=beta) + + # 增强锐化 + adjusted_image = sharpen_image(adjusted_image, sharpen_strength) + + return adjusted_image + + +def sharpen_image(image, strength=0): + """ + 对图像进行锐化处理。 + + 参数: + image (numpy.ndarray): 输入的图像数组。 + strength (float): 锐化强度,范围建议为0-5。0表示不进行锐化。 + + 返回: + numpy.ndarray: 锐化后的图像。 + """ + print(f"Shapen strength: {strength}") + if strength == 0: + return image.copy() + + strength = strength * 20 + # 将强度转换为适合kernel的值,但减小影响 + kernel_strength = 1 + (strength / 500) # 将除数从100改为500,减小锐化效果 + + # 创建更温和的锐化kernel + kernel = ( + np.array([[-0.5, -0.5, -0.5], [-0.5, 5, -0.5], [-0.5, -0.5, -0.5]]) + * kernel_strength + ) + + # 应用锐化kernel + sharpened = cv2.filter2D(image, -1, kernel) + + # 确保结果在0-255范围内 + sharpened = np.clip(sharpened, 0, 255).astype(np.uint8) + + # 混合原图和锐化后的图像,进一步减小锐化效果 + alpha = strength / 200 # 混合比例,最大为0.5 + blended = cv2.addWeighted(image, 1 - alpha, sharpened, alpha, 0) + + return blended + + +# Gradio接口 +def base_adjustment(image, brightness, contrast, sharpen): + adjusted = adjust_brightness_contrast_sharpen(image, brightness, contrast, sharpen) + return adjusted + + +if __name__ == "__main__": + import gradio as gr + + iface = gr.Interface( + fn=base_adjustment, + inputs=[ + gr.Image(label="Input Image", height=400), + gr.Slider( + minimum=-20, + maximum=20, + value=0, # Changed from 'default' to 'value' + step=1, + label="Brightness", + ), + gr.Slider( + minimum=-100, + maximum=100, + value=0, + step=1, + label="Contrast", + ), + gr.Slider( + minimum=0, + maximum=5, + value=0, + step=1, + label="Sharpen", + ), + ], + outputs=gr.Image(label="Adjusted Image"), + title="Image Brightness Adjustment", + description="Adjust the brightness of an image using a slider.", + ) + iface.launch() diff --git a/hivision/plugin/beauty/brightness.py b/hivision/plugin/beauty/brightness.py deleted file mode 100644 index 642af1c6..00000000 --- a/hivision/plugin/beauty/brightness.py +++ /dev/null @@ -1,31 +0,0 @@ -import cv2 -import numpy as np - - -def adjust_brightness(image, brightness_factor): - """ - 调整图像的亮度。 - - 参数: - image (numpy.ndarray): 输入的图像数组。 - brightness_factor (float): 亮度调整因子。大于1增加亮度,小于1降低亮度。 - - 返回: - numpy.ndarray: 调整亮度后的图像。 - """ - # 将图像转换为HSV颜色空间 - hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) - - # 分离HSV通道 - h, s, v = cv2.split(hsv) - - # 调整V通道(亮度) - v = np.clip(v * brightness_factor, 0, 255).astype(np.uint8) - - # 合并通道 - hsv = cv2.merge((h, s, v)) - - # 转换回BGR颜色空间 - adjusted = cv2.cvtColor(hsv, cv2.COLOR_HSV2BGR) - - return adjusted diff --git a/hivision/plugin/beauty/handler.py b/hivision/plugin/beauty/handler.py index 4218bd75..0716b956 100644 --- a/hivision/plugin/beauty/handler.py +++ b/hivision/plugin/beauty/handler.py @@ -1,19 +1,47 @@ import cv2 -import numpy as np from hivision.creator.context import Context from hivision.plugin.beauty.whitening import make_whitening +from hivision.plugin.beauty.base_adjust import adjust_brightness_contrast_sharpen def beauty_face(ctx: Context): """ 对人脸进行美颜处理 + 1. 美白 + 2. 亮度 :param ctx: Context对象,包含处理参数和图像 """ - # 目前只实现了美白功能,可以在这里添加其他美颜处理 + middle_image = ctx.origin_image.copy() + processed = False + + # 如果美白强度大于0,进行美白处理 if ctx.params.whitening_strength > 0: - _, _, _, alpha = cv2.split(ctx.matting_image) - b, g, r = cv2.split( - make_whitening(ctx.origin_image, ctx.params.whitening_strength) + middle_image = make_whitening(middle_image, ctx.params.whitening_strength) + processed = True + + # 如果亮度、对比度、锐化强度不为0,进行亮度、对比度、锐化处理 + if ( + ctx.params.brightness_strength != 0 + or ctx.params.contrast_strength != 0 + or ctx.params.sharpen_strength != 0 + ): + print( + f"Brightness strength: {ctx.params.brightness_strength}, Contrast strength: {ctx.params.contrast_strength}, Sharpen strength: {ctx.params.sharpen_strength}" ) + middle_image = adjust_brightness_contrast_sharpen( + middle_image, + ctx.params.brightness_strength, + ctx.params.contrast_strength, + ctx.params.sharpen_strength, + ) + processed = True + + # 如果进行了美颜处理,更新matting_image + if processed: + # 分离中间图像的BGR通道 + b, g, r = cv2.split(middle_image) + # 从原始matting_image中获取alpha通道 + _, _, _, alpha = cv2.split(ctx.matting_image) + # 合并处理后的BGR通道和原始alpha通道 ctx.matting_image = cv2.merge((b, g, r, alpha))