Pash1986 commited on
Commit
4195413
1 Parent(s): 0ed6129

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +71 -55
app.py CHANGED
@@ -7,101 +7,117 @@ import io
7
  import boto3
8
  import json
9
 
10
-
11
  bedrock_runtime = boto3.client('bedrock-runtime',
12
- aws_access_key_id=os.environ.get('AWS_ACCESS_KEY'),
13
- aws_secret_access_key=os.environ.get('AWS_SECRET_KEY'),
14
- region_name="us-east-1"
15
- )
16
 
 
17
  def construct_bedrock_body(base64_string, text):
18
  if text:
19
- return json.dumps(
20
- {
21
- "inputImage": base64_string,
22
- "embeddingConfig": {"outputEmbeddingLength": 1024},
23
- "inputText": text
24
- }
25
- )
26
-
27
- return json.dumps(
28
- {
29
  "inputImage": base64_string,
30
  "embeddingConfig": {"outputEmbeddingLength": 1024},
31
- }
32
- )
33
-
34
-
 
 
 
 
35
  def get_embedding_from_titan_multimodal(body):
36
-
37
-
38
  response = bedrock_runtime.invoke_model(
39
  body=body,
40
  modelId="amazon.titan-embed-image-v1",
41
  accept="application/json",
42
  contentType="application/json",
43
  )
44
-
45
  response_body = json.loads(response.get("body").read())
46
  return response_body["embedding"]
47
 
 
48
  uri = os.environ.get('MONGODB_ATLAS_URI')
49
  client = MongoClient(uri)
50
  db_name = 'celebrity_1000_embeddings'
51
  collection_name = 'celeb_images'
52
-
53
  celeb_images = client[db_name][collection_name]
54
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
  def start_image_search(image, text):
56
  if not image:
57
- ## Alert the user to upload an image
58
  raise gr.Error("Please upload an image first, make sure to press the 'Submit' button after selecting the image.")
59
  buffered = io.BytesIO()
60
  image = image.resize((800, 600))
61
- image.save(buffered, format="JPEG", quality=85)
62
  img_byte = buffered.getvalue()
63
- # Encode this byte array to Base64
64
  img_base64 = base64.b64encode(img_byte)
65
-
66
- # Convert Base64 bytes to string for JSON serialization
67
  img_base64_str = img_base64.decode('utf-8')
68
  body = construct_bedrock_body(img_base64_str, text)
69
  embedding = get_embedding_from_titan_multimodal(body)
70
 
71
- doc = list(celeb_images.aggregate([{
72
- "$vectorSearch": {
73
- "index": "vector_index",
74
- "path" : "embeddings",
75
- "queryVector": embedding,
76
- "numCandidates" : 15,
77
- "limit" : 3
78
- }}, {"$project": {"image":1}}]))
 
 
 
79
 
80
- images = []
81
- for image in doc:
82
- images.append(Image.open(io.BytesIO(base64.b64decode(image['image']))))
83
-
84
- return images
 
 
 
85
 
 
 
 
86
  with gr.Blocks() as demo:
87
- gr.Markdown(
88
- """
89
- # MongoDB's Vector Celeb Image matcher
90
 
91
- Upload an image and find the most similar celeb image from the database.
92
 
93
  💪 Make a great pose to impact the search! 🤯
94
-
95
  """)
96
-
97
- ### Image gradio input
98
- gr.Interface(
99
- fn=start_image_search,
100
- inputs=[gr.Image(type="pil", label="Upload an image"),gr.Textbox(label="Enter an adjusment to the image")],
101
- ## outputs=gr.Image(type="pil")
102
- outputs=gr.Gallery(
103
- label="Located images", show_label=True, elem_id="gallery"
104
- , columns=[3], rows=[1], object_fit="contain", height="auto")
105
  )
106
 
107
  demo.launch()
 
7
  import boto3
8
  import json
9
 
10
+ # AWS Bedrock client setup
11
  bedrock_runtime = boto3.client('bedrock-runtime',
12
+ aws_access_key_id=os.environ.get('AWS_ACCESS_KEY'),
13
+ aws_secret_access_key=os.environ.get('AWS_SECRET_KEY'),
14
+ region_name="us-east-1")
 
15
 
16
+ # Function to construct the request body for Bedrock
17
  def construct_bedrock_body(base64_string, text):
18
  if text:
19
+ return json.dumps({
 
 
 
 
 
 
 
 
 
20
  "inputImage": base64_string,
21
  "embeddingConfig": {"outputEmbeddingLength": 1024},
22
+ "inputText": text
23
+ })
24
+ return json.dumps({
25
+ "inputImage": base64_string,
26
+ "embeddingConfig": {"outputEmbeddingLength": 1024},
27
+ })
28
+
29
+ # Function to get the embedding from Bedrock model
30
  def get_embedding_from_titan_multimodal(body):
 
 
31
  response = bedrock_runtime.invoke_model(
32
  body=body,
33
  modelId="amazon.titan-embed-image-v1",
34
  accept="application/json",
35
  contentType="application/json",
36
  )
 
37
  response_body = json.loads(response.get("body").read())
38
  return response_body["embedding"]
39
 
40
+ # MongoDB setup
41
  uri = os.environ.get('MONGODB_ATLAS_URI')
42
  client = MongoClient(uri)
43
  db_name = 'celebrity_1000_embeddings'
44
  collection_name = 'celeb_images'
 
45
  celeb_images = client[db_name][collection_name]
46
 
47
+ # Function to generate image description using Claude 3 Sonnet
48
+ def generate_image_description_with_claude(image_base64):
49
+ claude_body = json.dumps({
50
+ "anthropic_version": "bedrock-2023-05-31",
51
+ "max_tokens": 1000,
52
+ "system": "Please respond only in Spanish.",
53
+ "messages": [{
54
+ "role": "user",
55
+ "content": [
56
+ {"type": "image", "source": {"type": "base64", "media_type": "image/jpeg", "data": image_base64}},
57
+ {"type": "text", "text": "What's in this image?"}
58
+ ]
59
+ }]
60
+ })
61
+
62
+ claude_response = bedrock_runtime.invoke_model(
63
+ body=claude_body,
64
+ modelId="anthropic.claude-3-sonnet-v1:0",
65
+ accept="application/json",
66
+ contentType="application/json",
67
+ )
68
+ response_body = json.loads(claude_response.get("body").read())
69
+ # Assuming the response contains a field 'content' with the description
70
+ return response_body["messages"][0]["content"][0].get("text", "No description available")
71
+
72
+ # Main function to start image search
73
  def start_image_search(image, text):
74
  if not image:
 
75
  raise gr.Error("Please upload an image first, make sure to press the 'Submit' button after selecting the image.")
76
  buffered = io.BytesIO()
77
  image = image.resize((800, 600))
78
+ image.save(buffered, format="JPEG", quality=85)
79
  img_byte = buffered.getvalue()
 
80
  img_base64 = base64.b64encode(img_byte)
 
 
81
  img_base64_str = img_base64.decode('utf-8')
82
  body = construct_bedrock_body(img_base64_str, text)
83
  embedding = get_embedding_from_titan_multimodal(body)
84
 
85
+ doc = list(celeb_images.aggregate([
86
+ {
87
+ "$vectorSearch": {
88
+ "index": "vector_index",
89
+ "path": "embeddings",
90
+ "queryVector": embedding,
91
+ "numCandidates": 15,
92
+ "limit": 3
93
+ }
94
+ }, {"$project": {"image": 1}}
95
+ ]))
96
 
97
+ images_with_descriptions = []
98
+ for image_doc in doc:
99
+ pil_image = Image.open(io.BytesIO(base64.b64decode(image_doc['image'])))
100
+ img_byte = io.BytesIO()
101
+ pil_image.save(img_byte, format='JPEG')
102
+ img_base64 = base64.b64encode(img_byte.getvalue()).decode('utf-8')
103
+ description = generate_image_description_with_claude(img_base64)
104
+ images_with_descriptions.append((pil_image, description))
105
 
106
+ return images_with_descriptions
107
+
108
+ # Gradio Interface
109
  with gr.Blocks() as demo:
110
+ gr.Markdown("""
111
+ # MongoDB's Vector Celeb Image Matcher
 
112
 
113
+ Upload an image and find the most similar celeb image from the database, along with an AI-generated description.
114
 
115
  💪 Make a great pose to impact the search! 🤯
 
116
  """)
117
+ gr.Interface(fn=start_image_search,
118
+ inputs=[gr.Image(type="pil", label="Upload an image"), gr.Textbox(label="Enter an adjustment to the image")],
119
+ outputs=gr.Gallery(label="Located images with AI-generated descriptions", show_label=True, elem_id="gallery",
120
+ columns=[3], rows=[1], object_fit="contain", height="auto")
 
 
 
 
 
121
  )
122
 
123
  demo.launch()