File size: 4,582 Bytes
9c70ea5
 
 
 
 
 
327b650
9c70ea5
48e56e3
 
 
 
 
 
 
9c70ea5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96278cf
9c70ea5
 
327b650
 
 
 
9c70ea5
 
25eb719
 
05a6cef
 
 
3dcde94
 
 
05a6cef
 
 
 
25eb719
9c70ea5
 
327b650
ff6f56c
 
60110bd
ff6f56c
60110bd
 
 
48e56e3
9c70ea5
48e56e3
 
9c70ea5
 
 
 
 
 
 
 
 
 
 
e2c8383
 
40b98cd
 
 
e2c8383
 
9c70ea5
 
 
 
 
 
96278cf
9c70ea5
96278cf
25eb719
5b5988d
 
 
 
 
25eb719
becba63
 
5b5988d
9c70ea5
60110bd
 
 
 
 
9c70ea5
327b650
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import streamlit as st
import tensorflow as tf
import numpy as np
from PIL import Image
import requests
from io import BytesIO
from bs4 import BeautifulSoup
import pandas as pd
import os

def download_model(model_url, model_path):
    if not os.path.exists(model_path):
        response = requests.get(model_url)
        with open(model_path, 'wb') as f:
            f.write(response.content)

def load_model(model_path):
    interpreter = tf.lite.Interpreter(model_path=model_path)
    interpreter.allocate_tensors()
    return interpreter

def preprocess_image(image, input_size):
    image = image.convert('RGB')
    image = image.resize((input_size, input_size))
    image_np = np.array(image, dtype=np.float32)
    image_np = np.expand_dims(image_np, axis=0)
    image_np = image_np / 255.0  # Normalize to [0, 1]
    return image_np

def run_inference(interpreter, input_data):
    input_details = interpreter.get_input_details()
    output_details = interpreter.get_output_details()
    
    interpreter.set_tensor(input_details[0]['index'], input_data)
    interpreter.invoke()
    
    output_data_shopping_intent = interpreter.get_tensor(output_details[0]['index'])
    
    return output_data_shopping_intent

def fetch_images_from_url(url):
    response = requests.get(url)
    soup = BeautifulSoup(response.content, 'html.parser')
    img_tags = soup.find_all('img')
    img_urls = [img['src'] for img in img_tags if 'src' in img.attrs]
    return img_urls

def render_intent_bars(labels, percentages):
    for label, percentage in zip(labels, percentages):
        bar_html = f"""
        <div style='display: flex; align-items: center;'>
            <div style='width: 30%; text-align: right; padding-right: 10px;'>{label}</div>
            <div style='width: 70%; display: flex; align-items: center;'>
                <div style='background-color: #007BFF; height: 10px; width: {percentage}%;'></div>
                <div style='padding-left: 10px;'>{percentage:.2f}%</div>
            </div>
        </div>
        """
        st.markdown(bar_html, unsafe_allow_html=True)

def main():
    st.set_page_config(layout="wide")
    st.title("Shopping Intent Classification - SEO by DEJAN")
    
    st.markdown("""
    Multi-label image classification model [extracted from Chrome](https://dejanmarketing.com/product-image-optimisation-with-chromes-convolutional-neural-network/). The model can be deployed in an automated pipeline capable of classifying product images in bulk. Javascript-based website scraping currently unsupported.
    """)
    
    st.write("Enter a URL to fetch and classify all images on the page:")
    
    model_url = "https://huggingface.co/dejanseo/shopping-intent/resolve/main/model.tflite"
    model_path = "model.tflite"
    download_model(model_url, model_path)

    url = st.text_input("Enter URL")

    if url:
        img_urls = fetch_images_from_url(url)
        if img_urls:
            st.write(f"Found {len(img_urls)} images")
            interpreter = load_model(model_path)
            input_details = interpreter.get_input_details()
            input_shape = input_details[0]['shape']
            input_size = input_shape[1]  # assuming square input

            categories = [
                "No Shopping Intent",
                "Apparel",
                "Home Decor",
                "Other"
            ]

            for img_url in img_urls:
                try:
                    response = requests.get(img_url)
                    image = Image.open(BytesIO(response.content))

                    input_data = preprocess_image(image, input_size)
                    output_data_shopping_intent = run_inference(interpreter, input_data)

                    shopping_intent_percentages = (output_data_shopping_intent.flatten() * 100).tolist()
                    
                    col1, col2 = st.columns([1, 3])
                    with col1:
                        st.image(image.resize((224, 224)), width=224)
                    with col2:
                        st.write(f"[URL]({img_url})")
                        render_intent_bars(categories, shopping_intent_percentages)
                    st.write("---")
                except Exception as e:
                    st.write(f"Could not process image {img_url}: {e}")

            st.markdown("""
            Interested in using this in an automated pipeline for bulk image classification?
            Please [book an appointment](https://dejanmarketing.com/conference/) to discuss your needs.
            """)

if __name__ == "__main__":
    main()