Files
change_hair/project/hair_service_sd/utils/enhance_hair.py
T
xsl 443cfa298f 初始化:换发型/换发色/训练发型服务
包含:
- hair_service_sd: 主服务(换发型/换发色/生发,端口8801)
- photo_service: LoRA调度+训练(端口32678)
- hair_grow_service: 调试测试页(端口8888,含4个测试页)
- 批量训练脚本(batch_train_hairstyles.py)
- 发际线mask自动识别(hairline_mask.py,4种方案)
- 手绘mask换发型(hair_swap_manual.py)
- 文档:README.md + LARGE_FILES.md + docs/

大文件(模型权重200G、训练数据123G)已排除,见 LARGE_FILES.md
OSS/COS密钥已脱敏为环境变量,原文件备份在本地
2026-07-07 13:53:52 +08:00

79 lines
2.8 KiB
Python

import cv2
import numpy as np
import base64
import requests
from common.logger import config
version = config.get('default', 'version')
if version == "local":
webui_url = 'http://192.168.1.57:57860/'
else:
webui_url = 'http://0.0.0.0:57860/'
def encode_numpy_to_base64(img):
retval, bytes = cv2.imencode('.png', img)
encoded_image = base64.b64encode(bytes).decode('utf-8')
return encoded_image
def webui_img2img(img, mask, prompt='', denoising_strength=0.35):
url = f"{webui_url}sdapi/v1/img2img"
request_dict = {
"prompt": prompt,
"negative_prompt": '(nsfw:1.5), ng_deepnegative_v1_75t, (badhandv4:1.2), (worst quality:2), (low quality:2), (normal quality:2), lowres, bad anatomy, bad hands, ((monochrome)), ((grayscale)) watermark, bad_pictures,easynegative',
"sampler_name": "DPM++ 2M Karras",
"batch_size": 1,
"steps": 30,
"width": img.shape[1],
"height": img.shape[0],
"cfg_scale": 7.0,
"seed": 123456789,
"mask_blur": 5,
"init_images": [
encode_numpy_to_base64(img)
],
"inpaint_full_res": False,
"inpainting_fill": 1,
"inpainting_mask_invert": 0,
"mask": encode_numpy_to_base64(mask),
"denoising_strength": denoising_strength,
"alwayson_scripts": {
}
}
response = requests.post(url=url, json=request_dict)
ret_json = response.json()
result = ret_json['images'][0]
img = cv2.imdecode(np.frombuffer(base64.b64decode(result.split(",", 1)[0]), np.uint8), cv2.IMREAD_COLOR)
return img
def webui_super_res_img(img, ratio):
url = f"{webui_url}sdapi/v1/extra-single-image"
request_dict = {
"resize_mode": 0,
"show_extras_results": False,
"gfpgan_visibility": 0,
"codeformer_visibility": 1,
"codeformer_weight": 1,
"upscaling_resize": ratio,
"upscaler_1": "8x_NMKD-Superscale_150000_G",
"upscale_first": False,
"image": encode_numpy_to_base64(img)
}
response = requests.post(url=url, json=request_dict)
ret_json = response.json()
result = ret_json['image']
img = cv2.imdecode(np.frombuffer(base64.b64decode(result), np.uint8), cv2.IMREAD_COLOR)
return img
def webui_tag_by_clip(img):
url = f"{webui_url}sdapi/v1/interrogate"
request_dict = {
"image": encode_numpy_to_base64(img),
"model": "clip"
}
response = requests.post(url=url, json=request_dict)
ret_json = response.json()
return ret_json['caption']