初始化换发型项目:3个微服务代码 + 部署脚本

包含:
- hair_service_sd: 换发型/换发色算法服务 (端口 8801)
- photo_service: LoRA 训练调度服务 (端口 32678)
- stable-diffusion-webui: SD WebUI 推理服务 (端口 57860)
- kohya_ss_home: 训练环境代码
- meidaojia: 监控测试脚本
- setup.sh: 一键部署脚本 (conda环境恢复 + 配置生成 + 完整性检查)
- start_all_services.sh: 启动3个服务
- configure.ini.template: 路径模板化 (BASE_DIR自动推导)
- conda_envs/py310.yml: py310 环境定义

大文件 (weights/, models/, data/, conda_envs/*.tar.gz 等) 通过 .gitignore 排除,
由网盘单独上传。
This commit is contained in:
colomi
2026-07-11 18:11:49 +08:00
commit 0eb61f3e60
628 changed files with 120882 additions and 0 deletions
+102
View File
@@ -0,0 +1,102 @@
import gradio as gr
import os,re
import numpy as np
import requests
import cv2
import base64
import json
from io import BytesIO
from PIL import Image
# api_service_url = 'http://127.0.0.1:1234'
# api_service_url = 'http://i-2.gpushare.com:53412'
api_service_url = 'http://service.aicloud.fit:7393/api/hairStyle/v1'
class ChangeHairGui():
# def __init__(self):
# a = 1
def change_hair(self, user_img, hair_img):
if user_img is None or user_img is None:
return None
#
# if user_img.shape != hair_img.shape:
# hair_img = cv2.resize(hair_img, (user_img.shape[1], user_img.shape[0]))
#
# alpha = 0.5 # 图像1的权重
# beta = 0.5 # 图像2的权重
# gamma = 0 # 亮度调整常量(通常为0)
#
# result_image = cv2.addWeighted(user_img, alpha, hair_img, beta, gamma)
# 将 Pillow 图像转换为 OpenCV 格式(BGR)
user_img = cv2.cvtColor(np.array(user_img), cv2.COLOR_RGB2BGR)
hair_img = cv2.cvtColor(np.array(hair_img), cv2.COLOR_RGB2BGR)
# 将模板图片转换为base64格式
retval, user_bytes = cv2.imencode('.jpg', user_img)
encoded_user_image = base64.b64encode(user_bytes).decode('utf-8')
retval, hair_bytes = cv2.imencode('.jpg', hair_img)
encoded_hair_image = base64.b64encode(hair_bytes).decode('utf-8')
url = api_service_url
# 请求换发型接口
payload = json.dumps({
"user_img_base64": encoded_user_image,
"hair_ref_img_base64": encoded_hair_image
})
headers = {
'Content-Type': 'application/json'
}
print('请求api_service.py发送请求!!')
response = requests.request("POST", url, headers=headers, data=payload)
print('请求api_service.py发送请求成功!!')
if response.status_code != 200:
raise RuntimeError(f"Failed to send request to API service. Status code: {response.status_code}")
ret_image_b64 = response.json().get('result')
if ret_image_b64 is None:
raise RuntimeError(f"ret image failed!")
image_array = np.frombuffer(base64.b64decode(ret_image_b64), np.uint8)
result_image = cv2.imdecode(image_array, cv2.IMREAD_COLOR)
result_image = cv2.cvtColor(result_image, cv2.COLOR_BGR2RGB)
dst_size = max(result_image.shape[0], result_image.shape[1])
M = cv2.getRotationMatrix2D((result_image.shape[1] / 2, result_image.shape[0] / 2), 0, 1)
M[:, 2] += np.float32([dst_size / 2 - result_image.shape[1] / 2, dst_size / 2 - result_image.shape[0] / 2])
result_image = cv2.warpAffine(result_image, M, (dst_size, dst_size), borderValue=(255, 255, 255))
return result_image
def start_gui(self):
with gr.Blocks() as demo:
with gr.Row():
gr.Markdown("# 数字力场换发型效果展示")
# 换脸
with gr.Tab("换发型"):
with gr.Row():
gr.Markdown("#换发型")
with gr.Row():
with gr.Column():
user_img = gr.Image(label="请上传用户图片", type="numpy", height=384, width=384)
with gr.Column():
hair_img = gr.Image(label="请上传发型图片", type="numpy", height=384, width=384)
with gr.Column():
output_img = gr.Image(label="结果展示", type="numpy", height=384, width=384, format='png')
with gr.Column():
run_button = gr.Button(value="提交")
run_button.click(self.change_hair, inputs=[user_img, hair_img], outputs=[output_img])
demo.launch(server_name='0.0.0.0', server_port=8080)
if __name__ == '__main__':
demo = ChangeHairGui()
demo.start_gui()