Spaces:
Running
Running
Update suggestion.py
Browse files- suggestion.py +209 -209
suggestion.py
CHANGED
@@ -1,209 +1,209 @@
|
|
1 |
-
import _thread as thread
|
2 |
-
import base64
|
3 |
-
import datetime
|
4 |
-
import hashlib
|
5 |
-
import hmac
|
6 |
-
import json
|
7 |
-
from urllib.parse import urlparse
|
8 |
-
import ssl
|
9 |
-
from datetime import datetime
|
10 |
-
from time import mktime
|
11 |
-
from urllib.parse import urlencode
|
12 |
-
from wsgiref.handlers import format_date_time
|
13 |
-
import websocket # 使用websocket_client
|
14 |
-
from PIL import Image
|
15 |
-
import io
|
16 |
-
import gradio as gr
|
17 |
-
|
18 |
-
appid = "11ce2152" #填写控制台中获取的 APPID 信息
|
19 |
-
api_secret = "N2ExOTc3MDc1OWZjMTkyNzFlYjA3ZTAz" #填写控制台中获取的 APISecret 信息
|
20 |
-
api_key = "4f6313fa6c05dea06e4e18b46e63b20f" #填写控制台中获取的 APIKey 信息
|
21 |
-
|
22 |
-
imageunderstanding_url = "wss://spark-api.cn-huabei-1.xf-yun.com/v2.1/image" #云端环境的服务地址
|
23 |
-
answer = ""
|
24 |
-
|
25 |
-
class Ws_Param(object):
|
26 |
-
# 初始化
|
27 |
-
def __init__(self, APPID, APIKey, APISecret, imageunderstanding_url):
|
28 |
-
self.APPID = APPID
|
29 |
-
self.APIKey = APIKey
|
30 |
-
self.APISecret = APISecret
|
31 |
-
self.host = urlparse(imageunderstanding_url).netloc
|
32 |
-
self.path = urlparse(imageunderstanding_url).path
|
33 |
-
self.ImageUnderstanding_url = imageunderstanding_url
|
34 |
-
|
35 |
-
# 生成url
|
36 |
-
def create_url(self):
|
37 |
-
# 生成RFC1123格式的时间戳
|
38 |
-
now = datetime.now()
|
39 |
-
date = format_date_time(mktime(now.timetuple()))
|
40 |
-
|
41 |
-
# 拼接字符串
|
42 |
-
signature_origin = "host: " + self.host + "\n"
|
43 |
-
signature_origin += "date: " + date + "\n"
|
44 |
-
signature_origin += "GET " + self.path + " HTTP/1.1"
|
45 |
-
|
46 |
-
# 进行hmac-sha256进行加密
|
47 |
-
signature_sha = hmac.new(self.APISecret.encode('utf-8'), signature_origin.encode('utf-8'),
|
48 |
-
digestmod=hashlib.sha256).digest()
|
49 |
-
|
50 |
-
signature_sha_base64 = base64.b64encode(signature_sha).decode(encoding='utf-8')
|
51 |
-
|
52 |
-
authorization_origin = f'api_key="{self.APIKey}", algorithm="hmac-sha256", headers="host date request-line", signature="{signature_sha_base64}"'
|
53 |
-
|
54 |
-
authorization = base64.b64encode(authorization_origin.encode('utf-8')).decode(encoding='utf-8')
|
55 |
-
|
56 |
-
# 将请求的鉴权参数组合为字典
|
57 |
-
v = {
|
58 |
-
"authorization": authorization,
|
59 |
-
"date": date,
|
60 |
-
"host": self.host
|
61 |
-
}
|
62 |
-
# 拼接鉴权参数,生成url
|
63 |
-
url = self.ImageUnderstanding_url + '?' + urlencode(v)
|
64 |
-
#print(url)
|
65 |
-
# 此处打印出建立连接时候的url,参考本demo的时候可取消上方打印的注释,比对相同参数时生成的url与自己代码生成的url是否一致
|
66 |
-
return url
|
67 |
-
|
68 |
-
|
69 |
-
# 收到websocket错误的处理
|
70 |
-
def on_error(ws, error):
|
71 |
-
print("### error:", error)
|
72 |
-
|
73 |
-
|
74 |
-
# 收到websocket关闭的处理
|
75 |
-
def on_close(ws, one, two):
|
76 |
-
print(" ")
|
77 |
-
|
78 |
-
|
79 |
-
# 收到websocket连接建立的处理
|
80 |
-
def on_open(ws):
|
81 |
-
thread.start_new_thread(run, (ws,))
|
82 |
-
|
83 |
-
|
84 |
-
def run(ws, *args):
|
85 |
-
data = json.dumps(gen_params(appid=ws.appid, question=ws.question))
|
86 |
-
ws.send(data)
|
87 |
-
|
88 |
-
|
89 |
-
# 收到websocket消息的处理
|
90 |
-
def on_message(ws, message):
|
91 |
-
#print(message)
|
92 |
-
data = json.loads(message)
|
93 |
-
code = data['header']['code']
|
94 |
-
if code != 0:
|
95 |
-
print(f'请求错误: {code}, {data}')
|
96 |
-
ws.close()
|
97 |
-
else:
|
98 |
-
choices = data["payload"]["choices"]
|
99 |
-
status = choices["status"]
|
100 |
-
content = choices["text"][0]["content"]
|
101 |
-
print(content, end="")
|
102 |
-
global answer
|
103 |
-
answer += content
|
104 |
-
# print(1)
|
105 |
-
if status == 2:
|
106 |
-
ws.close()
|
107 |
-
|
108 |
-
|
109 |
-
def gen_params(appid, question):
|
110 |
-
"""
|
111 |
-
通过appid和用户的提问来生成请参数
|
112 |
-
"""
|
113 |
-
|
114 |
-
data = {
|
115 |
-
"header": {
|
116 |
-
"app_id": appid
|
117 |
-
},
|
118 |
-
"parameter": {
|
119 |
-
"chat": {
|
120 |
-
"domain": "image",
|
121 |
-
"temperature": 0.5,
|
122 |
-
"top_k": 4,
|
123 |
-
"max_tokens": 2028,
|
124 |
-
"auditing": "default"
|
125 |
-
}
|
126 |
-
},
|
127 |
-
"payload": {
|
128 |
-
"message": {
|
129 |
-
"text": question
|
130 |
-
}
|
131 |
-
}
|
132 |
-
}
|
133 |
-
|
134 |
-
return data
|
135 |
-
|
136 |
-
|
137 |
-
def main(appid, api_key, api_secret, imageunderstanding_url, question):
|
138 |
-
wsParam = Ws_Param(appid, api_key, api_secret, imageunderstanding_url)
|
139 |
-
websocket.enableTrace(False)
|
140 |
-
wsUrl = wsParam.create_url()
|
141 |
-
ws = websocket.WebSocketApp(wsUrl, on_message=on_message, on_error=on_error, on_close=on_close, on_open=on_open)
|
142 |
-
ws.appid = appid
|
143 |
-
#ws.imagedata = imagedata
|
144 |
-
ws.question = question
|
145 |
-
ws.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE})
|
146 |
-
|
147 |
-
|
148 |
-
def getText(role, content, picture):
|
149 |
-
jsoncon = {}
|
150 |
-
jsoncon["role"] = role
|
151 |
-
jsoncon["content"] = content
|
152 |
-
image = Image.fromarray(picture)
|
153 |
-
byte_io = io.BytesIO()
|
154 |
-
image.save(byte_io, format='PNG')
|
155 |
-
image_bytes = byte_io.getvalue()
|
156 |
-
# 进行 Base64 编码
|
157 |
-
encoded_image = base64.b64encode(image_bytes).decode('utf-8')
|
158 |
-
text = [{"role": "user", "content": encoded_image, "content_type": "image"}, jsoncon]
|
159 |
-
return text
|
160 |
-
|
161 |
-
|
162 |
-
def getlength(text):
|
163 |
-
length = 0
|
164 |
-
for content in text:
|
165 |
-
temp = content["content"]
|
166 |
-
leng = len(temp)
|
167 |
-
length += leng
|
168 |
-
return length
|
169 |
-
|
170 |
-
|
171 |
-
def checklen(text):
|
172 |
-
#print("text-content-tokens:", getlength(text[1:]))
|
173 |
-
while (getlength(text[1:]) > 8000):
|
174 |
-
del text[1]
|
175 |
-
return text
|
176 |
-
|
177 |
-
|
178 |
-
def generate_outfit_advice(user_name, height, weight, waist, chest, hip, shoulder_width, leg_length, arm_length, gender,
|
179 |
-
body_type, skin_color, style_preference, lifestyle_requirements, special_requirements,
|
180 |
-
user_pic):
|
181 |
-
content = (f"""
|
182 |
-
你是一位专业的民族服饰搭配大师,你需要充分了解中华民族的所有民族服饰的相关知识,包括不同民族服饰适合什么样的人群等。
|
183 |
-
你需要对用户的照片和他们的输入信息作出评价,需要分析的因素包括以下内容:
|
184 |
-
1、用户上传的照片,分析种族、民族、脸型、五官比例、身材比例、肤色肤质。
|
185 |
-
2、用户基本信息:性别,年龄,身高,体重;
|
186 |
-
3、身体数据:胸围,腰围,臀围,肩宽,腿长,臂长;
|
187 |
-
4、体型与身材特征:体型分类:如苹果型、梨型、矩形、沙漏型等;身材特征:如长腿、短腿、宽肩、窄肩等。
|
188 |
-
5、肤色与发色:肤色分类:如冷色调、暖色调、中性色调等;发色与发型:目前的发色和发型。
|
189 |
-
6、穿衣风格偏好:日常偏好的风格(例如休闲、正式、运动、复古等),喜欢的颜色和不喜欢的颜色,喜爱的服装品牌,特别喜欢的服装单品(例如裙子、裤子、衬衫等)
|
190 |
-
7、生活方式和场合需求:工作环境(例如:办公室、户外、创意行业等),主要的社交活动类型(例如:商务会议、派对、休闲聚会等),平常的活动类型和频率(例如:健身、旅行、家庭活动等)
|
191 |
-
8、季节和气候:所在地的气候情况(例如:四季分明、热带、寒冷地区等),需要的季节性服装(例如:冬季大衣、夏季连衣裙等)
|
192 |
-
9、个人偏好和特殊需求:对于面料的偏好(例如:棉、麻、丝、羊毛等);是否有过敏或不适宜穿戴的材质;是否有特定的宗教或文化穿衣要求;是否有特殊身体条件需要考虑(例如:孕妇、残障人士等)
|
193 |
-
输出要求:
|
194 |
-
一、要求输出一段用户的人物画像,包含具体的服饰穿搭建议。 每种体型的合适服装和不合适服装都具有一定的潜在服装特征。例如,草莓形的人更适合穿
|
195 |
-
宽领或深领的衣服,而梨形的人则更适合穿伞形下摆的衣服而不是紧身的衣服。
|
196 |
-
二、将穿搭建议转化为具体的服饰特征,建立用户特征与服饰提示词的对应。 例如场合对应衣服的干练程度,更喜欢通勤场合的会倾向于推荐小袖口的民族服饰;
|
197 |
-
根据体型推荐相关服饰,略显肥胖的人会推荐汉服齐腰儒裙等; 男性按身高与袖口来分辨哪种服饰。
|
198 |
-
根据用户信息,用户名为{user_name},身高为{height},体重为{weight},腰围为{waist},胸围为{chest},臀围为{hip},
|
199 |
-
肩宽为{shoulder_width},腿长为{leg_length},臂长为{arm_length},性别为{gender},体型分类为{body_type},肤色为{skin_color},
|
200 |
-
穿衣风格偏好为{style_preference},生活方式和场景需求为{lifestyle_requirements},其他特殊需求为{special_requirements}。
|
201 |
-
请给出穿搭建议。
|
202 |
-
""")
|
203 |
-
global answer
|
204 |
-
answer = ""
|
205 |
-
question = checklen(getText("user", content, user_pic))
|
206 |
-
main(appid, api_key, api_secret, imageunderstanding_url, question)
|
207 |
-
getText("assistant", answer, user_pic)
|
208 |
-
return gr.Markdown(answer)
|
209 |
-
|
|
|
1 |
+
import _thread as thread
|
2 |
+
import base64
|
3 |
+
import datetime
|
4 |
+
import hashlib
|
5 |
+
import hmac
|
6 |
+
import json
|
7 |
+
from urllib.parse import urlparse
|
8 |
+
import ssl
|
9 |
+
from datetime import datetime
|
10 |
+
from time import mktime
|
11 |
+
from urllib.parse import urlencode
|
12 |
+
from wsgiref.handlers import format_date_time
|
13 |
+
import websocket # 使用websocket_client
|
14 |
+
from PIL import Image
|
15 |
+
import io
|
16 |
+
import gradio as gr
|
17 |
+
|
18 |
+
appid = "11ce2152" #填写控制台中获取的 APPID 信息
|
19 |
+
api_secret = "N2ExOTc3MDc1OWZjMTkyNzFlYjA3ZTAz" #填写控制台中获取的 APISecret 信息
|
20 |
+
api_key = "4f6313fa6c05dea06e4e18b46e63b20f" #填写控制台中获取的 APIKey 信息
|
21 |
+
|
22 |
+
imageunderstanding_url = "wss://spark-api.cn-huabei-1.xf-yun.com/v2.1/image" #云端环境的服务地址
|
23 |
+
answer = ""
|
24 |
+
|
25 |
+
class Ws_Param(object):
|
26 |
+
# 初始化
|
27 |
+
def __init__(self, APPID, APIKey, APISecret, imageunderstanding_url):
|
28 |
+
self.APPID = APPID
|
29 |
+
self.APIKey = APIKey
|
30 |
+
self.APISecret = APISecret
|
31 |
+
self.host = urlparse(imageunderstanding_url).netloc
|
32 |
+
self.path = urlparse(imageunderstanding_url).path
|
33 |
+
self.ImageUnderstanding_url = imageunderstanding_url
|
34 |
+
|
35 |
+
# 生成url
|
36 |
+
def create_url(self):
|
37 |
+
# 生成RFC1123格式的时间戳
|
38 |
+
now = datetime.now()
|
39 |
+
date = format_date_time(mktime(now.timetuple()))
|
40 |
+
|
41 |
+
# 拼接字符串
|
42 |
+
signature_origin = "host: " + self.host + "\n"
|
43 |
+
signature_origin += "date: " + date + "\n"
|
44 |
+
signature_origin += "GET " + self.path + " HTTP/1.1"
|
45 |
+
|
46 |
+
# 进行hmac-sha256进行加密
|
47 |
+
signature_sha = hmac.new(self.APISecret.encode('utf-8'), signature_origin.encode('utf-8'),
|
48 |
+
digestmod=hashlib.sha256).digest()
|
49 |
+
|
50 |
+
signature_sha_base64 = base64.b64encode(signature_sha).decode(encoding='utf-8')
|
51 |
+
|
52 |
+
authorization_origin = f'api_key="{self.APIKey}", algorithm="hmac-sha256", headers="host date request-line", signature="{signature_sha_base64}"'
|
53 |
+
|
54 |
+
authorization = base64.b64encode(authorization_origin.encode('utf-8')).decode(encoding='utf-8')
|
55 |
+
|
56 |
+
# 将请求的鉴权参数组合为字典
|
57 |
+
v = {
|
58 |
+
"authorization": authorization,
|
59 |
+
"date": date,
|
60 |
+
"host": self.host
|
61 |
+
}
|
62 |
+
# 拼接鉴权参数,生成url
|
63 |
+
url = self.ImageUnderstanding_url + '?' + urlencode(v)
|
64 |
+
#print(url)
|
65 |
+
# 此处打印出建立连接时候的url,参考本demo的时候可取消上方打印的注释,比对相同参数时生成的url与自己代码生成的url是否一致
|
66 |
+
return url
|
67 |
+
|
68 |
+
|
69 |
+
# 收到websocket错误的处理
|
70 |
+
def on_error(ws, error):
|
71 |
+
print("### error:", error)
|
72 |
+
|
73 |
+
|
74 |
+
# 收到websocket关闭的处理
|
75 |
+
def on_close(ws, one, two):
|
76 |
+
print(" ")
|
77 |
+
|
78 |
+
|
79 |
+
# 收到websocket连接建立的处理
|
80 |
+
def on_open(ws):
|
81 |
+
thread.start_new_thread(run, (ws,))
|
82 |
+
|
83 |
+
|
84 |
+
def run(ws, *args):
|
85 |
+
data = json.dumps(gen_params(appid=ws.appid, question=ws.question))
|
86 |
+
ws.send(data)
|
87 |
+
|
88 |
+
|
89 |
+
# 收到websocket消息的处理
|
90 |
+
def on_message(ws, message):
|
91 |
+
#print(message)
|
92 |
+
data = json.loads(message)
|
93 |
+
code = data['header']['code']
|
94 |
+
if code != 0:
|
95 |
+
print(f'请求错误: {code}, {data}')
|
96 |
+
ws.close()
|
97 |
+
else:
|
98 |
+
choices = data["payload"]["choices"]
|
99 |
+
status = choices["status"]
|
100 |
+
content = choices["text"][0]["content"]
|
101 |
+
print(content, end="")
|
102 |
+
global answer
|
103 |
+
answer += content
|
104 |
+
# print(1)
|
105 |
+
if status == 2:
|
106 |
+
ws.close()
|
107 |
+
|
108 |
+
|
109 |
+
def gen_params(appid, question):
|
110 |
+
"""
|
111 |
+
通过appid和用户的提问来生成请参数
|
112 |
+
"""
|
113 |
+
|
114 |
+
data = {
|
115 |
+
"header": {
|
116 |
+
"app_id": appid
|
117 |
+
},
|
118 |
+
"parameter": {
|
119 |
+
"chat": {
|
120 |
+
"domain": "image",
|
121 |
+
"temperature": 0.5,
|
122 |
+
"top_k": 4,
|
123 |
+
"max_tokens": 2028,
|
124 |
+
"auditing": "default"
|
125 |
+
}
|
126 |
+
},
|
127 |
+
"payload": {
|
128 |
+
"message": {
|
129 |
+
"text": question
|
130 |
+
}
|
131 |
+
}
|
132 |
+
}
|
133 |
+
|
134 |
+
return data
|
135 |
+
|
136 |
+
|
137 |
+
def main(appid, api_key, api_secret, imageunderstanding_url, question):
|
138 |
+
wsParam = Ws_Param(appid, api_key, api_secret, imageunderstanding_url)
|
139 |
+
websocket.enableTrace(False)
|
140 |
+
wsUrl = wsParam.create_url()
|
141 |
+
ws = websocket.WebSocketApp(wsUrl, on_message=on_message, on_error=on_error, on_close=on_close, on_open=on_open)
|
142 |
+
ws.appid = appid
|
143 |
+
#ws.imagedata = imagedata
|
144 |
+
ws.question = question
|
145 |
+
ws.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE})
|
146 |
+
|
147 |
+
|
148 |
+
def getText(role, content, picture):
|
149 |
+
jsoncon = {}
|
150 |
+
jsoncon["role"] = role
|
151 |
+
jsoncon["content"] = content
|
152 |
+
image = Image.fromarray(picture)
|
153 |
+
byte_io = io.BytesIO()
|
154 |
+
image.save(byte_io, format='PNG')
|
155 |
+
image_bytes = byte_io.getvalue()
|
156 |
+
# 进行 Base64 编码
|
157 |
+
encoded_image = base64.b64encode(image_bytes).decode('utf-8')
|
158 |
+
text = [{"role": "user", "content": encoded_image, "content_type": "image"}, jsoncon]
|
159 |
+
return text
|
160 |
+
|
161 |
+
|
162 |
+
def getlength(text):
|
163 |
+
length = 0
|
164 |
+
for content in text:
|
165 |
+
temp = content["content"]
|
166 |
+
leng = len(temp)
|
167 |
+
length += leng
|
168 |
+
return length
|
169 |
+
|
170 |
+
|
171 |
+
def checklen(text):
|
172 |
+
#print("text-content-tokens:", getlength(text[1:]))
|
173 |
+
while (getlength(text[1:]) > 8000):
|
174 |
+
del text[1]
|
175 |
+
return text
|
176 |
+
|
177 |
+
|
178 |
+
def generate_outfit_advice(user_name, height, weight, waist, chest, hip, shoulder_width, leg_length, arm_length, gender,
|
179 |
+
body_type, skin_color, style_preference, lifestyle_requirements, special_requirements,
|
180 |
+
feedback, user_pic):
|
181 |
+
content = (f"""
|
182 |
+
你是一位专业的民族服饰搭配大师,你需要充分了解中华民族的所有民族服饰的相关知识,包括不同民族服饰适合什么样的人群等。
|
183 |
+
你需要对用户的照片和他们的输入信息作出评价,需要分析的因素包括以下内容:
|
184 |
+
1、用户上传的照片,分析种族、民族、脸型、五官比例、身材比例、肤色肤质。
|
185 |
+
2、用户基本信息:性别,年龄,身高,体重;
|
186 |
+
3、身体数据:胸围,腰围,臀围,肩宽,腿长,臂长;
|
187 |
+
4、体型与身材特征:体型分类:如苹果型、梨型、矩形、沙漏型等;身材特征:如长腿、短腿、宽肩、窄肩等。
|
188 |
+
5、肤色与发色:肤色分类:如冷色调、暖色调、中性色调等;发色与发型:目前的发色和发型。
|
189 |
+
6、穿衣风格偏好:日常偏好的风格(例如休闲、正式、运动、复古等),喜欢的颜色和不喜欢的颜色,喜爱的服装品牌,特别喜欢的服装单品(例如裙子、裤子、衬衫等)
|
190 |
+
7、生活方式和场合需求:工作环境(例如:办公室、户外、创意行业等),主要的社交活动类型(例如:商务会议、派对、休闲聚会等),平常的活动类型和频率(例如:健身、旅行、家庭活动等)
|
191 |
+
8、季节和气候:所在地的气候情况(例如:四季分明、热带、寒冷地区等),需要的季节性服装(例如:冬季大衣、夏季连衣裙等)
|
192 |
+
9、个人偏好和特殊需求:对于面料的偏好(例如:棉、麻、丝、羊毛等);是否有过敏或不适宜穿戴的材质;是否有特定的宗教或文化穿衣要求;是否有特殊身体条件需要考虑(例如:孕妇、残障人士等)
|
193 |
+
输出要求:
|
194 |
+
一、要求输出一段用户的人物画像,包含具体的服饰穿搭建议。 每种体型的合适服装和不合适服装都具有一定的潜在服装特征。例如,草莓形的人更适合穿
|
195 |
+
宽领或深领的衣服,而梨形的人则更适合穿伞形下摆的衣服而不是紧身的衣服。
|
196 |
+
二、将穿搭建议转化为具体的服饰特征,建立用户特征与服饰提示词的对应。 例如场合对应衣服的干练程度,更喜欢通勤场合的会倾向于推荐小袖口的民族服饰;
|
197 |
+
根据体型推荐相关服饰,略显肥胖的人会推荐汉服齐腰儒裙等; 男性按身高与袖口来分辨哪种服饰。
|
198 |
+
根据用户信息,用户名为{user_name},身高为{height},体重为{weight},腰围为{waist},胸围为{chest},臀围为{hip},
|
199 |
+
肩宽为{shoulder_width},腿长为{leg_length},臂长为{arm_length},性别为{gender},体型分类为{body_type},肤色为{skin_color},
|
200 |
+
穿衣风格偏好为{style_preference},生活方式和场景需求为{lifestyle_requirements},其他特殊需求为{special_requirements},{feedback}。
|
201 |
+
请给出穿搭建议。
|
202 |
+
""")
|
203 |
+
global answer
|
204 |
+
answer = ""
|
205 |
+
question = checklen(getText("user", content, user_pic))
|
206 |
+
main(appid, api_key, api_secret, imageunderstanding_url, question)
|
207 |
+
getText("assistant", answer, user_pic)
|
208 |
+
return gr.Markdown(answer)
|
209 |
+
|