jpye00 commited on
Commit
5bd8b08
·
verified ·
1 Parent(s): 05b9ee1

Upload 80 files

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. AdGazer_WebApp.py +209 -0
  2. src/.DS_Store +0 -0
  3. src/Ad_Gaze_Model/.DS_Store +0 -0
  4. src/Ad_Gaze_Model/10_models/Model_1.json +0 -0
  5. src/Ad_Gaze_Model/10_models/Model_10.json +0 -0
  6. src/Ad_Gaze_Model/10_models/Model_2.json +0 -0
  7. src/Ad_Gaze_Model/10_models/Model_3.json +0 -0
  8. src/Ad_Gaze_Model/10_models/Model_4.json +0 -0
  9. src/Ad_Gaze_Model/10_models/Model_5.json +0 -0
  10. src/Ad_Gaze_Model/10_models/Model_6.json +0 -0
  11. src/Ad_Gaze_Model/10_models/Model_7.json +0 -0
  12. src/Ad_Gaze_Model/10_models/Model_8.json +0 -0
  13. src/Ad_Gaze_Model/10_models/Model_9.json +0 -0
  14. src/Ad_Gaze_Model/README.md +1 -0
  15. src/Ad_Gaze_Model/model_XGBoost_best.json +0 -0
  16. src/Ad_Gaze_Model/typicality_train_medoid +0 -0
  17. src/Brand_Gaze_Model/.DS_Store +0 -0
  18. src/Brand_Gaze_Model/10_models/Model_1.json +0 -0
  19. src/Brand_Gaze_Model/10_models/Model_10.json +0 -0
  20. src/Brand_Gaze_Model/10_models/Model_2.json +0 -0
  21. src/Brand_Gaze_Model/10_models/Model_3.json +0 -0
  22. src/Brand_Gaze_Model/10_models/Model_4.json +0 -0
  23. src/Brand_Gaze_Model/10_models/Model_5.json +0 -0
  24. src/Brand_Gaze_Model/10_models/Model_6.json +0 -0
  25. src/Brand_Gaze_Model/10_models/Model_7.json +0 -0
  26. src/Brand_Gaze_Model/10_models/Model_8.json +0 -0
  27. src/Brand_Gaze_Model/10_models/Model_9.json +0 -0
  28. src/Brand_Gaze_Model/README.md +1 -0
  29. src/Brand_Gaze_Model/model_XGBoost_best.json +0 -0
  30. src/Brand_Gaze_Model/typicality_train_medoid +0 -0
  31. src/Brand_Share_Model/.DS_Store +0 -0
  32. src/Brand_Share_Model/10_models/Model_1.json +0 -0
  33. src/Brand_Share_Model/10_models/Model_10.json +0 -0
  34. src/Brand_Share_Model/10_models/Model_2.json +0 -0
  35. src/Brand_Share_Model/10_models/Model_3.json +0 -0
  36. src/Brand_Share_Model/10_models/Model_4.json +0 -0
  37. src/Brand_Share_Model/10_models/Model_5.json +0 -0
  38. src/Brand_Share_Model/10_models/Model_6.json +0 -0
  39. src/Brand_Share_Model/10_models/Model_7.json +0 -0
  40. src/Brand_Share_Model/10_models/Model_8.json +0 -0
  41. src/Brand_Share_Model/10_models/Model_9.json +0 -0
  42. src/Brand_Share_Model/model_XGBoost_best.json +0 -0
  43. src/Brand_Share_Model/typicality_train_medoid +0 -0
  44. src/CNN_Gaze_Model/.DS_Store +0 -0
  45. src/CNN_Gaze_Model/Fine-tune_AG/.DS_Store +0 -0
  46. src/CNN_Gaze_Model/Fine-tune_AG/Model_0.pth +3 -0
  47. src/CNN_Gaze_Model/Fine-tune_BG/.DS_Store +0 -0
  48. src/CNN_Gaze_Model/Fine-tune_BG/Model_0.pth +3 -0
  49. src/CNN_Gaze_Model/Fine-tune_BS/.DS_Store +0 -0
  50. src/CNN_Gaze_Model/Fine-tune_BS/Model_0.pth +3 -0
AdGazer_WebApp.py ADDED
@@ -0,0 +1,209 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import sys
2
+ import os
3
+ new_dir = os.path.join(os.getcwd(), "src")
4
+ sys.path.append(new_dir)
5
+
6
+ import gradio as gr
7
+ from gradio_image_prompter import ImagePrompter
8
+ import Predict
9
+ import XGBoost_utils
10
+ import numpy as np
11
+ import cv2 as cv
12
+ import os
13
+ os.environ["PYTORCH_ENABLE_MPS_FALLBACK"]="1"
14
+ import torch
15
+ from PIL import Image
16
+ from gradio_pdf import PDF
17
+ from pdf2image import convert_from_path
18
+ from pathlib import Path
19
+
20
+ GENERAL_CATEGORY = {'Potatoes / Vegetables / Fruit': 0, 'Chemical products': 1, 'Photo / Film / Optical items': 2, 'Catering industry': 3, 'Industrial products other': 4, 'Media': 5, 'Real estate': 6, 'Government': 7, 'Personnel advertisements': 8, 'Cars / Commercial vehicles': 9, 'Cleaning products': 10, 'Retail': 11, 'Fragrances': 12, 'Footwear / Leather goods': 13, 'Software / Automation': 14, 'Telecommunication equipment': 15, 'Tourism': 16, 'Transport/Communication companies': 17, 'Transport services': 18, 'Insurances': 19, 'Meat / Fish / Poultry': 20, 'Detergents': 21, 'Foods General': 22, 'Other services': 23, 'Banks and Financial Services': 24, 'Office Products': 25, 'Household Items': 26, 'Non-alcoholic beverages': 27, 'Hair, Oral and Personal Care': 28, 'Fashion and Clothing': 29, 'Other products and Services': 30, 'Paper products': 31, 'Alcohol and Other Stimulants': 32, 'Medicines': 33, 'Recreation and Leisure': 34, 'Electronics': 35, 'Home Furnishings': 36, 'Products for Business Use': 37}
21
+ CATEGORIES = list(GENERAL_CATEGORY.keys())
22
+ CATEGORIES.sort()
23
+ LOCATIONS = ['Left', 'Right', 'Full']
24
+ GAZE_TYPE = ['Ad', 'Brand']
25
+
26
+ def calculate_areas(prompts, brand_num, pictorial_num, text_num):
27
+ image_entire = prompts["image"]
28
+ w, h = image_entire.size
29
+ image_entire = np.array(image_entire.convert('RGB'))
30
+ points_all = prompts["points"]
31
+ brand_surf = 0
32
+ for i in range(brand_num):
33
+ x1 = points_all[i][0]; y1 = points_all[i][1]
34
+ x2 = points_all[i][3]; y2 = points_all[i][4]
35
+ brand_surf += np.abs((x1-x2)*(y1-y2))
36
+
37
+ pictorial_surf = 0
38
+ for i in range(brand_num, brand_num+pictorial_num):
39
+ x1 = points_all[i][0]; y1 = points_all[i][1]
40
+ x2 = points_all[i][3]; y2 = points_all[i][4]
41
+ pictorial_surf += np.abs((x1-x2)*(y1-y2))
42
+
43
+ text_surf = 0
44
+ for i in range(brand_num+pictorial_num, brand_num+pictorial_num+text_num):
45
+ x1 = points_all[i][0]; y1 = points_all[i][1]
46
+ x2 = points_all[i][3]; y2 = points_all[i][4]
47
+ text_surf += np.abs((x1-x2)*(y1-y2))
48
+
49
+ ad_size = 0
50
+ x1 = points_all[-1][0]; y1 = points_all[-1][1]
51
+ x2 = points_all[-1][3]; y2 = points_all[-1][4]
52
+ ad_size += np.abs((x1-x2)*(y1-y2))
53
+ ad_image = image_entire[int(y1):int(y2), int(x1):int(x2), :]
54
+ left_margin = x1; right_margin = w-x2
55
+ if left_margin <=100 and right_margin <= 100:
56
+ upper_margin = y1; lower_margin = h-y2
57
+ if upper_margin <= 100 and lower_margin <= 100:
58
+ context_image = None
59
+ else:
60
+ if upper_margin >= lower_margin:
61
+ context_image = image_entire[:int(y1), :, :]
62
+ else:
63
+ context_image = image_entire[int(y2):, :, :]
64
+ else:
65
+ if left_margin >= right_margin:
66
+ context_image = image_entire[:, :int(x1), :]
67
+ else:
68
+ context_image = image_entire[:, int(x2):, :]
69
+
70
+ whole_size = 0
71
+ whole_size += w*h
72
+
73
+ return (brand_surf/whole_size*100, pictorial_surf/whole_size*100, text_surf/whole_size*100, ad_size/whole_size*100, ad_image, context_image)
74
+
75
+ def convert(note, doc):
76
+ print(doc)
77
+ img = convert_from_path(doc)[0]
78
+ img.save(f'pdf_to_imgs/pdf_img.png', 'PNG')
79
+ return 'Done!', gr.DownloadButton(label='Download converted image', value='pdf_to_imgs/pdf_img.png')
80
+
81
+ def attention(note, button1, button2,
82
+ whole_display_prompt,
83
+ brand_num, pictorial_num, text_num, check,
84
+ category, ad_location, gaze_type):
85
+ text_detection_model_path = 'src/EAST-Text-Detection/frozen_east_text_detection.pb'
86
+ LDA_model_pth = 'LDA_Model_trained/lda_model_best_tot.model'
87
+ training_ad_text_dictionary_path = 'LDA_Model_trained/object_word_dictionary'
88
+ training_lang_preposition_path = 'LDA_Model_trained/dutch_preposition'
89
+
90
+ prod_group = np.zeros(38)
91
+ prod_group[GENERAL_CATEGORY[category]] = 1
92
+
93
+ if not check:
94
+ print('No ad bounding box available!!')
95
+ return -1, None
96
+
97
+ if ad_location == 'left':
98
+ ad_loc = 0
99
+ elif ad_location == 'right':
100
+ ad_loc = 1
101
+ else:
102
+ ad_loc = None
103
+
104
+ brand_percent, visual_percent, text_percent, adv_size_percent, ad_image, context_image = calculate_areas(whole_display_prompt, brand_num, pictorial_num, text_num)
105
+ surfaces = [brand_percent, visual_percent, text_percent, adv_size_percent*10/100]
106
+
107
+ #### Note: The following lines are commented out because they require GPU and additional resources to run.
108
+ # caption_ad = XGBoost_utils.Caption_Generation(Image.fromarray(np.uint8(ad_image)))
109
+ # if context_image is not None:
110
+ # caption_context = XGBoost_utils.Caption_Generation(Image.fromarray(np.uint8(context_image)))
111
+ # else:
112
+ # caption_context = ''
113
+ # ad_topic = XGBoost_utils.Topic_emb(caption_ad)
114
+ # ctpg_topic = XGBoost_utils.Topic_emb(caption_context)
115
+ np.random.seed(42)
116
+ ad_topic = np.random.randn(1,768)
117
+ ctpg_topic = np.random.randn(1,768)
118
+
119
+ ad = cv.resize(ad_image, (640, 832))
120
+ print('ad shape: ', ad.shape)
121
+ if context_image is None:
122
+ context = None
123
+ else:
124
+ context = cv.resize(context_image, (640, 832))
125
+
126
+ adv_imgs = torch.permute(torch.tensor(ad), (2,0,1)).unsqueeze(0)
127
+ if context is None:
128
+ ctpg_imgs = torch.zeros_like(adv_imgs)
129
+ else:
130
+ ctpg_imgs = torch.permute(torch.tensor(context), (2,0,1)).unsqueeze(0)
131
+ ad_locations = torch.tensor([1,0]).unsqueeze(0)
132
+ heatmap = Predict.HeatMap_CNN(adv_imgs, ctpg_imgs, ad_locations, Gaze_Type='AG')
133
+
134
+ Gaze = Predict.Ad_Gaze_Prediction(input_ad_path=ad, input_ctpg_path=context, ad_location=ad_loc,
135
+ text_detection_model_path=text_detection_model_path, LDA_model_pth=LDA_model_pth,
136
+ training_ad_text_dictionary_path=training_ad_text_dictionary_path, training_lang_preposition_path=training_lang_preposition_path, training_language='dutch',
137
+ Ad_var=None, Ctpg_var=None,
138
+ flag_full_page_ad=False,
139
+ ad_embeddings=ad_topic, ctpg_embeddings=ctpg_topic,
140
+ surface_sizes=surfaces, Product_Group=prod_group,
141
+ obj_detection_model_pth=None, num_topic=20, Gaze_Time_Type=gaze_type, Ad_Features_Only=False, Info_printing=False)
142
+ return np.round(Gaze[0],2), Image.fromarray(np.flip(heatmap, axis=2))
143
+
144
+ with gr.Blocks() as demo:
145
+ gr.Markdown("""
146
+ <div style='text-align: center; padding: 10px; font-size:40px'>
147
+ <p> <b>Gazer 1.0: Ad Attention Prediction</b> </p>
148
+ </div>
149
+ """)
150
+ gr.Markdown("""
151
+ This app accompanies: "Contextual Advertising with Theory-Informed Machine Learning", manuscript submitted to the Journal of Marketing.
152
+ App Version: 1.0, Date: 10/24/2024.
153
+ Note: Gazer 1.0 does not yet include LLM generated ad topics. Future updates will include this in a GPU environment.
154
+ """)
155
+ gr.Interface(
156
+ fn=convert,
157
+ inputs=[gr.Markdown("""
158
+ <div style='font-size:20px'>
159
+ <p> <b>If you only have a pdf image file, first convert it here to png file and download:</b> </p>
160
+ </div>
161
+
162
+ """),
163
+ PDF(label="PDF Converter")],
164
+ outputs=[gr.Text(label='Progress'), gr.DownloadButton(label='Wait to be downloadable', value=None)]
165
+ )
166
+
167
+ gr.Interface(
168
+ fn=attention,
169
+ inputs=[gr.Markdown("""
170
+ ## Instructions:
171
+ 0. The screen size should remain the same during processing.
172
+ 1. Click to upload or drag the entire image (jpg/jpeg/png file) that contains BOTH ad and its context;
173
+ 2. Draw bounding boxes in the order of: (each element can have more than 1 boxes; remember the number of boxes for each element you draw)
174
+ &nbsp;&nbsp;&nbsp;(a) Brand element(s) (skip if N.A.)
175
+ &nbsp;&nbsp;&nbsp;(b) Pictorial element(s), e.g. Objects, Person etc (skip if N.A.)
176
+ &nbsp;&nbsp;&nbsp;(c) Text element(s) (skip if N.A.)
177
+ &nbsp;&nbsp;&nbsp;(d) The advertisement.
178
+ 3. Put in number of bounding boxes for each element, product category, ad location and attention type.
179
+
180
+ ***NOTE:*** *ResNet50 Heatmap could take around 20-80 seconds under current CPU environment.*
181
+
182
+ Two example ads are avialable for download: """),
183
+ gr.DownloadButton(label="Download Example Image 1 of Ad and Context", value='Demo/Ad_Example1.jpg'),
184
+ gr.DownloadButton(label="Download Example Image 2 of Ad and Context", value='Demo/Ad_Example2.jpg'),
185
+ ImagePrompter(label="Upload Entire (Ad+Context) Image in jpg/jpeg/png format, and Draw Bounding Boxes", sources=['upload'], type="pil"),
186
+ gr.Number(label="Number of brand bounding boxes drawn"),
187
+ gr.Number(label="Number of pictorial bounding boxes drawn"),
188
+ gr.Number(label="Number of text bounding boxes drawn"),
189
+ gr.Checkbox(label="Check if you draw a bounding box for the entire ad (Note: this is a must-do)"),
190
+ gr.Dropdown(CATEGORIES, label="Product Category"),
191
+ gr.Dropdown(LOCATIONS, label='Ad Location'),
192
+ gr.Dropdown(GAZE_TYPE, label='Gaze Type')
193
+ ],
194
+ outputs=[gr.Number(label="Predicted Gaze (sec). If you see a value of -1, it means no ad bounding box is drawn!!"),
195
+ gr.Image(label="ResNet50 Heatmap (Hotter/Redder regions show more pixel contribution.)")],
196
+ title=None,
197
+ description=None,
198
+ theme=gr.themes.Soft()
199
+ )
200
+ gr.Markdown(
201
+ """
202
+ <div style='text-align: center; padding: 1px;'>
203
+ <p>Copyright © 2024 Manuscript Authors. All Rights Reserved.</p>
204
+ <p>Disclaimer: This app is provided for free and for academic use only. The authors take no responsibility for your use of the information contained in or linked from these web pages.</p>
205
+ </div>
206
+ """
207
+ )
208
+
209
+ demo.launch(share=False)
src/.DS_Store ADDED
Binary file (10.2 kB). View file
 
src/Ad_Gaze_Model/.DS_Store ADDED
Binary file (6.15 kB). View file
 
src/Ad_Gaze_Model/10_models/Model_1.json ADDED
The diff for this file is too large to render. See raw diff
 
src/Ad_Gaze_Model/10_models/Model_10.json ADDED
The diff for this file is too large to render. See raw diff
 
src/Ad_Gaze_Model/10_models/Model_2.json ADDED
The diff for this file is too large to render. See raw diff
 
src/Ad_Gaze_Model/10_models/Model_3.json ADDED
The diff for this file is too large to render. See raw diff
 
src/Ad_Gaze_Model/10_models/Model_4.json ADDED
The diff for this file is too large to render. See raw diff
 
src/Ad_Gaze_Model/10_models/Model_5.json ADDED
The diff for this file is too large to render. See raw diff
 
src/Ad_Gaze_Model/10_models/Model_6.json ADDED
The diff for this file is too large to render. See raw diff
 
src/Ad_Gaze_Model/10_models/Model_7.json ADDED
The diff for this file is too large to render. See raw diff
 
src/Ad_Gaze_Model/10_models/Model_8.json ADDED
The diff for this file is too large to render. See raw diff
 
src/Ad_Gaze_Model/10_models/Model_9.json ADDED
The diff for this file is too large to render. See raw diff
 
src/Ad_Gaze_Model/README.md ADDED
@@ -0,0 +1 @@
 
 
1
+ Trained AD-Gaze Model
src/Ad_Gaze_Model/model_XGBoost_best.json ADDED
The diff for this file is too large to render. See raw diff
 
src/Ad_Gaze_Model/typicality_train_medoid ADDED
Binary file (29.4 kB). View file
 
src/Brand_Gaze_Model/.DS_Store ADDED
Binary file (6.15 kB). View file
 
src/Brand_Gaze_Model/10_models/Model_1.json ADDED
The diff for this file is too large to render. See raw diff
 
src/Brand_Gaze_Model/10_models/Model_10.json ADDED
The diff for this file is too large to render. See raw diff
 
src/Brand_Gaze_Model/10_models/Model_2.json ADDED
The diff for this file is too large to render. See raw diff
 
src/Brand_Gaze_Model/10_models/Model_3.json ADDED
The diff for this file is too large to render. See raw diff
 
src/Brand_Gaze_Model/10_models/Model_4.json ADDED
The diff for this file is too large to render. See raw diff
 
src/Brand_Gaze_Model/10_models/Model_5.json ADDED
The diff for this file is too large to render. See raw diff
 
src/Brand_Gaze_Model/10_models/Model_6.json ADDED
The diff for this file is too large to render. See raw diff
 
src/Brand_Gaze_Model/10_models/Model_7.json ADDED
The diff for this file is too large to render. See raw diff
 
src/Brand_Gaze_Model/10_models/Model_8.json ADDED
The diff for this file is too large to render. See raw diff
 
src/Brand_Gaze_Model/10_models/Model_9.json ADDED
The diff for this file is too large to render. See raw diff
 
src/Brand_Gaze_Model/README.md ADDED
@@ -0,0 +1 @@
 
 
1
+ Trained Brand-Gaze Model
src/Brand_Gaze_Model/model_XGBoost_best.json ADDED
The diff for this file is too large to render. See raw diff
 
src/Brand_Gaze_Model/typicality_train_medoid ADDED
Binary file (29.4 kB). View file
 
src/Brand_Share_Model/.DS_Store ADDED
Binary file (6.15 kB). View file
 
src/Brand_Share_Model/10_models/Model_1.json ADDED
The diff for this file is too large to render. See raw diff
 
src/Brand_Share_Model/10_models/Model_10.json ADDED
The diff for this file is too large to render. See raw diff
 
src/Brand_Share_Model/10_models/Model_2.json ADDED
The diff for this file is too large to render. See raw diff
 
src/Brand_Share_Model/10_models/Model_3.json ADDED
The diff for this file is too large to render. See raw diff
 
src/Brand_Share_Model/10_models/Model_4.json ADDED
The diff for this file is too large to render. See raw diff
 
src/Brand_Share_Model/10_models/Model_5.json ADDED
The diff for this file is too large to render. See raw diff
 
src/Brand_Share_Model/10_models/Model_6.json ADDED
The diff for this file is too large to render. See raw diff
 
src/Brand_Share_Model/10_models/Model_7.json ADDED
The diff for this file is too large to render. See raw diff
 
src/Brand_Share_Model/10_models/Model_8.json ADDED
The diff for this file is too large to render. See raw diff
 
src/Brand_Share_Model/10_models/Model_9.json ADDED
The diff for this file is too large to render. See raw diff
 
src/Brand_Share_Model/model_XGBoost_best.json ADDED
The diff for this file is too large to render. See raw diff
 
src/Brand_Share_Model/typicality_train_medoid ADDED
Binary file (29.4 kB). View file
 
src/CNN_Gaze_Model/.DS_Store ADDED
Binary file (8.2 kB). View file
 
src/CNN_Gaze_Model/Fine-tune_AG/.DS_Store ADDED
Binary file (6.15 kB). View file
 
src/CNN_Gaze_Model/Fine-tune_AG/Model_0.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:524c2d86af030d61cd1314eb67c895969d43084067bddac23269afcea04069f7
3
+ size 98547310
src/CNN_Gaze_Model/Fine-tune_BG/.DS_Store ADDED
Binary file (6.15 kB). View file
 
src/CNN_Gaze_Model/Fine-tune_BG/Model_0.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0ec71b7beb8c2f873e2d70faddff1011fb9a7a7558cdf205577d4a4e617b65db
3
+ size 98547310
src/CNN_Gaze_Model/Fine-tune_BS/.DS_Store ADDED
Binary file (6.15 kB). View file
 
src/CNN_Gaze_Model/Fine-tune_BS/Model_0.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:1ebd11825d7049aaad74203040301122c1589abaa06e6c1563c5ad16fac32bdc
3
+ size 98547310