包含: - 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 排除, 由网盘单独上传。
326 lines
12 KiB
Python
326 lines
12 KiB
Python
import pickle
|
|
import sys
|
|
|
|
import cv2
|
|
from PIL import Image
|
|
from OpenGL.GL import *
|
|
from OpenGL.GLU import *
|
|
from OpenGL.GLUT import *
|
|
import numpy as np
|
|
|
|
# define shader code
|
|
vertex_code='''
|
|
uniform float scale;
|
|
attribute vec2 position;
|
|
attribute vec4 color;
|
|
varying vec4 v_color;
|
|
attribute vec2 TexCoordIn;
|
|
varying vec2 TexCoordOut;
|
|
|
|
void main()
|
|
{
|
|
gl_Position = vec4(position*scale, 0.0, 1.0);
|
|
v_color = color;
|
|
TexCoordOut = TexCoordIn;
|
|
|
|
}'''
|
|
|
|
fragment_code='''
|
|
varying vec4 v_color;
|
|
varying vec2 TexCoordOut;
|
|
uniform sampler2D Texture;
|
|
uniform vec2 originPosition;
|
|
uniform vec2 targetPosition;
|
|
vec2 curveWarp(vec2 textureCoord, vec2 originPosition, vec2 targetPosition, float radius)
|
|
{
|
|
vec2 offset = vec2(0.0);
|
|
vec2 result = vec2(0.0);
|
|
|
|
vec2 direction = targetPosition - originPosition;
|
|
|
|
float infect = distance(textureCoord, originPosition)/radius;
|
|
|
|
infect = 1.0 - infect;
|
|
infect = clamp(infect, 0.0, 1.0);
|
|
offset = direction * infect;
|
|
|
|
result = textureCoord - offset;
|
|
return result;
|
|
}
|
|
|
|
void main()
|
|
{
|
|
vec2 coordinate = vec2(0.0);
|
|
float radius = 0.5;
|
|
coordinate = curveWarp(TexCoordOut,originPosition,targetPosition,radius);
|
|
gl_FragColor = v_color*0.000000000001 + texture2D(Texture, coordinate);
|
|
|
|
}'''
|
|
|
|
|
|
|
|
#define useful function
|
|
def display():
|
|
glClear(GL_COLOR_BUFFER_BIT)
|
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)
|
|
|
|
glutSwapBuffers()
|
|
|
|
def reshape(width,height):
|
|
glViewport(0, 0, width, height)
|
|
|
|
#step1 init the context
|
|
def init(img_path):
|
|
image = Image.open(img_path)
|
|
glutInit()
|
|
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB)
|
|
glutCreateWindow('Hello world!')
|
|
glutReshapeWindow(image.width,image.height)
|
|
glutReshapeFunc(reshape)
|
|
glutDisplayFunc(display)
|
|
return image
|
|
|
|
#step 2
|
|
def initShaderProgram():
|
|
program = glCreateProgram()
|
|
vertex = glCreateShader(GL_VERTEX_SHADER)
|
|
fragment = glCreateShader(GL_FRAGMENT_SHADER)
|
|
|
|
# Set shaders source
|
|
glShaderSource(vertex, vertex_code)
|
|
glShaderSource(fragment, fragment_code)
|
|
|
|
# Compile shaders
|
|
glCompileShader(vertex)
|
|
glCompileShader(fragment)
|
|
|
|
fragSuccess = glGetShaderiv(fragment, GL_COMPILE_STATUS)
|
|
vertSuccess = glGetShaderiv(vertex, GL_COMPILE_STATUS)
|
|
print("vertext shader compile success [%s]" % (vertSuccess,))
|
|
print("fragment shader compile success [%s]" % (fragSuccess,))
|
|
|
|
if vertSuccess == 0:
|
|
print(glGetShaderInfoLog(vertex))
|
|
sys.exit(0)
|
|
|
|
if fragSuccess == 0:
|
|
print(glGetShaderInfoLog(fragment))
|
|
sys.exit(0)
|
|
|
|
|
|
glAttachShader(program, vertex)
|
|
glAttachShader(program, fragment)
|
|
glLinkProgram(program)
|
|
linksucc=glGetProgramiv(program, GL_LINK_STATUS)
|
|
print("link program success [%s]" % (linksucc,))
|
|
glUseProgram(program)
|
|
|
|
return program
|
|
|
|
#step 3.1 optional setup texture
|
|
def getTextureFromFile(image_file):
|
|
#convert file to bytes
|
|
image = image_file.transpose(Image.FLIP_TOP_BOTTOM)
|
|
image = image.convert("RGBA")
|
|
byteImage =np.array(list(image.getdata()), np.uint8)
|
|
|
|
#setup texture
|
|
texIndex=glGenTextures(1)
|
|
glEnable( GL_TEXTURE_2D )
|
|
glBindTexture(GL_TEXTURE_2D,texIndex)
|
|
|
|
glPixelStorei(GL_UNPACK_ALIGNMENT,1)
|
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP)
|
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP)
|
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
|
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
|
|
#make the texture the default
|
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texIndex, 0)
|
|
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,image.width,image.height,0,GL_RGBA,GL_UNSIGNED_BYTE,byteImage)
|
|
|
|
return texIndex
|
|
|
|
|
|
#step 4.1 optional get the image from BufferFrame
|
|
def saveImageFromFBO(width, height, output_img_path):
|
|
glReadBuffer(GL_COLOR_ATTACHMENT0)
|
|
glPixelStorei(GL_PACK_ALIGNMENT, 1)
|
|
data = glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE)
|
|
image = Image.new("RGB", (width, height), (0, 0, 0))
|
|
image.frombytes(data)
|
|
image = image.transpose(Image.FLIP_TOP_BOTTOM)
|
|
image.save(output_img_path)
|
|
|
|
|
|
#step 4 optional if need to OSR generate a BufferFrame
|
|
def setupSelfDefineFBO(program, image, data, output_img_path):
|
|
fbWidth, fbHeight = image.width, image.height
|
|
|
|
# Setup framebuffer
|
|
framebuffer = glGenFramebuffers(1)
|
|
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer)
|
|
|
|
# # Setup colorbuffer
|
|
# colorbuffer = glGenRenderbuffers(1)
|
|
# glBindRenderbuffer(GL_RENDERBUFFER, colorbuffer)
|
|
# glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA, fbWidth, fbHeight)
|
|
# glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorbuffer)
|
|
|
|
# Setup depthbuffer
|
|
depthbuffer = glGenRenderbuffers (1)
|
|
glBindRenderbuffer (GL_RENDERBUFFER,depthbuffer)
|
|
glRenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH_COMPONENT, image.width, image.height)
|
|
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthbuffer)
|
|
|
|
#first init VBO, then other parameters
|
|
buffer = glGenBuffers(1) # Request a buffer slot from GPU
|
|
glBindBuffer(GL_ARRAY_BUFFER, buffer) # Make this buffer the default one
|
|
glBufferData(GL_ARRAY_BUFFER, data.nbytes, data, GL_DYNAMIC_DRAW) # Upload data
|
|
|
|
# Create texture to render to
|
|
# glBufferData(GL_FRAMEBUFFER, data.nbytes, data, GL_DYNAMIC_DRAW)
|
|
loc = glGetAttribLocation(program, "position") #get the index of the attribute in program
|
|
glEnableVertexAttribArray(loc) #allow this attribute decide by index can be use
|
|
stride = data.strides[0] #define how to read buffer
|
|
offset = ctypes.c_void_p(0) #define the offset where the data begin in buffer
|
|
glVertexAttribPointer(loc, 2, GL_FLOAT, False, stride, offset)
|
|
offset = ctypes.c_void_p(data.dtype["position"].itemsize)
|
|
loc = glGetAttribLocation(program, "color")
|
|
glEnableVertexAttribArray(loc)
|
|
glVertexAttribPointer(loc, 4, GL_FLOAT, False, stride, offset)
|
|
|
|
#setup other parameters
|
|
loc = glGetUniformLocation(program, "scale")
|
|
glUniform1f(loc, 1.0)
|
|
|
|
# originPosition = glGetUniformLocation(program, "originPosition")
|
|
# glUniform2f(originPosition, 0.5, 0.5)
|
|
#
|
|
# targetPosition = glGetUniformLocation(program, "targetPosition")
|
|
# glUniform2f(targetPosition, 0.47, 0.47)
|
|
# # glUniform2f(targetPosition, 0.5, 0.5)
|
|
|
|
# following code to bind uniform texture if needed
|
|
aTexture = getTextureFromFile(image)
|
|
|
|
glViewport(0, 0, fbWidth, fbHeight)
|
|
|
|
glActiveTexture(GL_TEXTURE0)
|
|
glBindTexture(GL_TEXTURE_2D, aTexture)
|
|
loc = glGetUniformLocation(program, "Texture")
|
|
glUniform1i(loc, 0)
|
|
|
|
loc = glGetAttribLocation(program, "TexCoordIn")
|
|
glEnableVertexAttribArray(loc)
|
|
offset=ctypes.c_void_p(data.dtype["color"].itemsize+8)
|
|
glVertexAttribPointer(loc, 2, GL_FLOAT, False, stride, offset)
|
|
|
|
status = glCheckFramebufferStatus (GL_FRAMEBUFFER)
|
|
if status != GL_FRAMEBUFFER_COMPLETE:
|
|
print( "Error in framebuffer activation")
|
|
|
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4)
|
|
saveImageFromFBO(fbWidth, fbHeight, output_img_path)
|
|
|
|
glBindFramebuffer(GL_FRAMEBUFFER, GL_NONE)
|
|
glDeleteTextures([aTexture])
|
|
glDeleteFramebuffers(1, [framebuffer])
|
|
|
|
print('save image from FBO success')
|
|
|
|
def pt_in_img(pt, img_w, img_h):
|
|
|
|
if pt[0] < 0 or pt[1] < 0 or pt[0] >= img_w or pt[1] >= img_h:
|
|
return False
|
|
else:
|
|
return True
|
|
|
|
def demo_test():
|
|
input_img_path = "../test_data/pics/female003.jpg"
|
|
output_img_path = "../tmp.png"
|
|
|
|
###### define vertex and color array
|
|
|
|
# data = np.zeros(4, dtype=[("position", np.float32, 2), ("color", np.float32, 4), ("textureCoord", np.float32, 2)])
|
|
# data['color'] = [(1, 1, 0, 1), (1, 1, 0, 1), (1, 1, 0, 1), (1, 1, 0, 1)]
|
|
# # data['position'] = [(-1, -1), (-1, 1), (1, -1), (1, 1)]
|
|
# data['position'] = [(-1, -1), (-1, 1), (0, -1), (0, 1)]
|
|
# # data['textureCoord'] = [(0, 0), (0, 1), (1, 0), (1, 1)]
|
|
# data['textureCoord'] = [(0, 0), (0, 1), (1, 0), (0.5, 1)]
|
|
|
|
data = np.zeros(8, dtype=[("position", np.float32, 2), ("color", np.float32, 4), ("textureCoord", np.float32, 2)])
|
|
data['color'] = [(1, 1, 0, 1), (1, 1, 0, 1), (1, 1, 0, 1), (1, 1, 0, 1), (1, 1, 0, 1), (1, 1, 0, 1), (1, 1, 0, 1), (1, 1, 0, 1)]
|
|
data['position'] = [(-1, -1), (-1, +1), (0, -1), (0, +1), (0, -1), (0, +1), (+1, -1), (+1, +1)]
|
|
# data['textureCoord'] = [(0, 0), (0, 1), (0.5, 0), (0.5, 1), (0.5, 0), (0.5, 1), (1, 0), (1, 1)]
|
|
mid_x = 0.6
|
|
data['textureCoord'] = [(0, 0), (0, 1), (mid_x, 0), (mid_x, 1), (mid_x, 0), (mid_x, 1), (1, 0), (1, 1)]
|
|
|
|
# data = np.zeros(3, dtype=[("position", np.float32, 2), ("color", np.float32, 4), ("textureCoord", np.float32, 2)])
|
|
# data['color'] = [(1, 1, 0, 1), (1, 1, 0, 1), (1, 1, 0, 1)]
|
|
# data['position'] = [(-1, -1), (-1, +1), (1, -1)]
|
|
# # data['position'] = [(-1, -1), (1, 1), (1, -1)]
|
|
# data['textureCoord'] = [(0, 0), (0, 1), (0.5, 0)]
|
|
# # data['textureCoord'] = [(0, 0), (1, 1), (1, 0)]
|
|
|
|
# data = np.zeros(6, dtype=[("position", np.float32, 2), ("color", np.float32, 4), ("textureCoord", np.float32, 2)])
|
|
# data['color'] = [(1, 1, 0, 1), (1, 1, 0, 1), (1, 1, 0, 1), (1, 1, 0, 1), (1, 1, 0, 1), (1, 1, 0, 1)]
|
|
# data['position'] = [(-1, -1), (-1, +1), (0, -1), (0, +1), (1, -1), (1, 1)]
|
|
# # data['textureCoord'] = [(0, 0), (0, 1), (0.5, 0), (0.5, 1), (1, 0), (1, 1)]
|
|
# data['textureCoord'] = [(0, 0), (0, 1), (0.5, 0), (0.5, 1), (1, 0), (1, 1)]
|
|
# mid_x = 0.4
|
|
# data['textureCoord'] = [(0, 0), (0, 1), (mid_x, 0), (mid_x, 1), (1, 0), (1, 1)]
|
|
|
|
|
|
image = init(input_img_path)
|
|
program = initShaderProgram()
|
|
setupSelfDefineFBO(program, image, data, output_img_path)
|
|
|
|
def demo_warp_pt137():
|
|
input_img_path = "../test_data/pics/female003.jpg"
|
|
output_img_path = "../tmp.png"
|
|
|
|
import pickle
|
|
with open("../test_render.pkl", "rb") as fp:
|
|
info = pickle.load(fp)
|
|
vertice = info["vertice"]
|
|
dst_vertice = info["dst_vertice"]
|
|
faces = info["faces"]
|
|
color_list = []
|
|
position_list = []
|
|
textureCoord_list = []
|
|
img = cv2.imread(input_img_path)
|
|
img_h, img_w, _ = img.shape
|
|
for i in range(len(faces)):
|
|
# print("index: ", faces[i])
|
|
pt1 = vertice[faces[i][0]]
|
|
pt2 = vertice[faces[i][1]]
|
|
pt3 = vertice[faces[i][2]]
|
|
dst_pt1 = dst_vertice[faces[i][0]]
|
|
dst_pt2 = dst_vertice[faces[i][1]]
|
|
dst_pt3 = dst_vertice[faces[i][2]]
|
|
# if pt1[0] != dst_pt1[0]:
|
|
# print("use warp!")
|
|
if pt_in_img(pt1, img_w, img_h) and pt_in_img(pt2, img_w, img_h) and pt_in_img(pt3, img_w, img_h):
|
|
color_list.append((1, 1, 0, 1))
|
|
color_list.append((1, 1, 0, 1))
|
|
color_list.append((1, 1, 0, 1))
|
|
position_list.append((dst_pt1[0] * 2 / img_w - 1, dst_pt1[1] * 2 / img_h - 1))
|
|
position_list.append((dst_pt2[0] * 2 / img_w - 1, dst_pt2[1] * 2 / img_h - 1))
|
|
position_list.append((dst_pt3[0] * 2 / img_w - 1, dst_pt3[1] * 2 / img_h - 1))
|
|
textureCoord_list.append((pt1[0] / img_w, pt1[1] / img_h))
|
|
textureCoord_list.append((pt2[0] / img_w, pt2[1] / img_h))
|
|
textureCoord_list.append((pt3[0] / img_w, pt3[1] / img_h))
|
|
|
|
data = np.zeros(len(color_list),
|
|
dtype=[("position", np.float32, 2), ("color", np.float32, 4), ("textureCoord", np.float32, 2)])
|
|
data['color'] = color_list
|
|
data['position'] = position_list
|
|
data['textureCoord'] = textureCoord_list
|
|
|
|
image = init(input_img_path)
|
|
program = initShaderProgram()
|
|
setupSelfDefineFBO(program, image, data, output_img_path)
|
|
|
|
if __name__ == '__main__':
|
|
demo_test()
|
|
# demo_warp_pt137() |