当前位置:首页|资讯|Stable Diffusion

超简使用API控制ControlNet

作者:北大BIM老龙发布时间:2023-10-24

Stable Diffusion使用WEB UI虽然可以通过交互界面生成图像,但是,如果遇到批量处理以及自动化处理图像的情形,使用交互界面的模式就不适用了。

这里,主要讨论如何使用API的方式自动调用ControlNet插件,并实现Stable Diffusion自动出图。

首先,确保Stable Diffusion和ControlNet已经安装好,并且其在WEB UI状态下可以正常出图。打开命令行工具,在sd文件夹下输入.\webui.bat --medvram --xformers --nowebui,以无界面方式运行sd。

然后,打开PyCharm新建一个项目,在项目根目录下新建一个名newAPIControlNet.py的文件。该脚本的主要方法是get Image2Image,通过这个方法来完成图生图操作。

下面我们来解析一下这个脚本,首先将导入需要的库类和方法,图片裁切和图片格式转换方法,以及英文翻译方法,可自行编写,这里就不做赘述了。

然后,定义四个在图生图转换过程中会用到的方法,分别是encode_pil_to_base64()方法,用于将图片转换成64位的编码,方便SD读取;submit_post()方法,用于向SD提请API请求;save_encoded_image()方法,用于保存图片;joinLoraList()方法,用于控制lora列表。

接下来,让我们解析getImage2Image()这个方法,第一步,预处理原始图片,先定义原始图片的地址以及裁切后图片的地址和保存png图片的地址,再将原始图片进行编辑并保存为64位的编码;第二步,将数据带入API进行运算,这里着重要讲ControlNet的数据格式。controlnet的数据被放在alwayson_scripts条目下,可以同时支持三个controlnet的模型,这里使用了openpose,tile和inpaint三个模型,同时每个模型都指定了权重,并且它们的目标图像与图生图原始图像保持一致。最后一步,发起API请求后,保存图片到指定的地址。

下面我们将相关提示词和lora补全,这里使用了一个泰国衣服风格的lora。开始进行图片生成,等待后台运算,打开原始图片,检查生成后的图片,可以看到生成的图片保持了原图片的姿势,衣服在原有的基础上做了风格上的调整。如果要输出更多变化的结果,可以调低tile和inpaint的权重。

调高权重后,我们再次输出试试,可以看到衣服变化的幅度加大了,是不是很神奇?

这就是使用API调用controlnet的方法,你学会了吗?


相关代码newAPIControlNet.py的内容:

from imageCrop import cropImage2Video

from pythonJpgToPng import image2png

from translateFromCh2EnYoudao import translateYouDao

from PIL import Image

import io

import os

import json

import base64

import random

import requests


def encode_pil_to_base64(image):

with io.BytesIO() as output_bytes:

image.save(output_bytes, format="png")

bytes_data = output_bytes.getvalue()

return base64.b64encode(bytes_data).decode("utf-8")


def submit_post(url: str, data: dict):

return requests.post(url, data=json.dumps(data))


def save_encoded_image(b64_image: str, output_path: str):

with open(output_path, "wb") as image_file:

image_file.write(base64.b64decode(b64_image))


def joinLoraList(loraName01,weight01,loraName02,weight02,loraName03,weight03):


if loraName01 == "" :

loraPart01 = ""

else:

loraPart01 = "<lora:%s:%2.1f>"%(loraName01,weight01)


if loraName02 == "":

loraPart02 = ""

else:

loraPart02 = "<lora:%s:%2.1f>"%(loraName02,weight02)


if loraName03 == "":

loraPart03 = ""

else:

loraPart03 = "<lora:%s:%2.1f>"%(loraName03,weight03)

loraList = loraPart01 + loraPart02 + loraPart03

print(loraList)

return loraList


def getImage2Image(text_prompt,loraList,denoisingStrength,localPythonExePath,gifImageNum,seed,tileweight,inpaintweight):

localFilePath = "D:\SDM\sendReq2DB\Frames\%d.jpg"%gifImageNum #原始图片地址

localCroppedFilePath = localPythonExePath + "\image\i2i\croppedimage\croppedpromptimage.jpg"

cropImage2Video(localFilePath,localCroppedFilePath) #对图片进行尺寸转换,如果图片尺寸已经裁切好,可省略此步骤

promptImageFilePath = localPythonExePath + "\image\i2i\croppedimage"

image2png(promptImageFilePath,"png") #将裁剪后的jpg图片保存为png格式,如果原始图片就是png,可省略此步骤

promptimage_temp = Image.open(localPythonExePath + "\prompt_image\croppedpromptimage.png")

promptimage_temp_code = encode_pil_to_base64(promptimage_temp) #调用save_encoded_image方法,将图片转换成64位编码

os.remove("%s\prompt_image\croppedpromptimage.png"%localPythonExePath) # 将转换到本地的png文件删除

image2Image_url = 'http://127.0.0.1:7861/sdapi/v1/img2img'

data = {

"init_images": [promptimage_temp_code],

# "mask":mask_temp_code,

"prompt": text_prompt+loraList,

'brach_size': 1,

# "sampler_name":"DPM++ 2m Karras",

"steps": 20,

"denoising_strength": denoisingStrength,

"cfg_scale": 7,

"width": 512,

"height": 910,

"seed": seed,

"restore_faces": "true",

"negative_prompt": "nsfw,blurry,bad anatomy,low quality,worst quality,normal quality",

"alwayson_scripts": {

"ControlNet": {

"args": [{

"enabled": "true",

"pixel_perfect": "true",

"module": "none",

"model": "control_v11p_sd15_openpose",

"weight": 1,

"image": promptimage_temp_code

},{

"enabled": "true",

"pixel_perfect": "true",

"module": "none",

"model": "control_v11f1e_sd15_tile",

"weight": tileweight,

"image": promptimage_temp_code

},{

"enabled": "true",

"pixel_perfect": "true",

"module": "none",

"model": "control_v11p_sd15_inpaint",

"weight": inpaintweight,

"image": promptimage_temp_code

}]

}

}

}

response = submit_post(image2Image_url, data)

save_encoded_image(response.json()['images'][0], 'FramesNew\%d.png'%(gifImageNum)) #保存生成的图片到指定地址

print("图片已经生成,并保存在image目录中")


if __name__ == '__main__':

text_prompt = "美女,黑色腰带,短裙子,mahalaiuniform,站立姿势,正常手部" # mahalaiuniform-000001泰国风格

text_prompt = translateYouDao(text_prompt) #将提示词翻译成英文

loraList = joinLoraList("mahalaiuniform-000001", 1.0, '', 1.0, '', 1.0)

denoisingStrength = 0.8 #重绘强度

seed = random.randint(1, 10000000)

localPythonExePath = "D:\SDM\sendReq2DB"

gifImageNum = 0

getImage2Image(text_prompt, loraList, denoisingStrength, localPythonExePath, gifImageNum, seed,0.1,0.1)



Copyright © 2024 aigcdaily.cn  北京智识时代科技有限公司  版权所有  京ICP备2023006237号-1