File size: 8,323 Bytes
9cca2b0
2e3d76a
69de931
2e3d76a
 
da3ef81
 
2e3d76a
 
 
cc03be5
272f4f6
d4ccb5d
69de931
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5e2e20e
69de931
 
 
 
 
 
 
 
 
 
e8746a9
00db187
f7a6ead
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
00db187
 
2e3d76a
 
 
 
 
 
d4ccb5d
da3ef81
d3e55a2
 
 
 
 
da3ef81
 
cc03be5
d4ccb5d
cc03be5
 
 
 
b6f9430
d4ccb5d
 
2e3d76a
d4ccb5d
9cca2b0
 
 
2e3d76a
0e0423b
 
d4ccb5d
69de931
00db187
d4ccb5d
00db187
2e3d76a
e9c62c9
2e3d76a
d4ccb5d
69de931
2e3d76a
0e0423b
 
00db187
2e3d76a
ba829b6
 
 
 
 
 
 
 
 
 
2e3d76a
ba829b6
 
 
2e3d76a
ba829b6
 
 
2e3d76a
ba829b6
 
 
2e3d76a
00db187
0e0423b
 
e8746a9
d4ccb5d
 
 
 
 
0e0423b
 
d4ccb5d
 
0e0423b
d4ccb5d
f06adfd
9cca2b0
d4ccb5d
69de931
d4ccb5d
69de931
d3e55a2
2e3d76a
d4ccb5d
69de931
 
 
 
0e0423b
69de931
0e0423b
cc03be5
6200397
2e3d76a
 
 
 
 
 
0e0423b
69de931
 
 
0e0423b
2e3d76a
0e0423b
d4ccb5d
 
 
0e0423b
2e3d76a
e8746a9
d4ccb5d
2e3d76a
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
import fal_client
import gradio as gr
import io
import openai
import os
import random
import requests
from PIL import Image
from dotenv import load_dotenv
from fastai.vision.all import *
from pathlib import Path

# Dictionary of plant names and their Wikipedia links
search_terms_wikipedia = {
    "blazing star": "https://en.wikipedia.org/wiki/Mentzelia",
    "bristlecone pine": "https://en.wikipedia.org/wiki/Pinus_longaeva",
    "california bluebell": "https://en.wikipedia.org/wiki/Phacelia_minor",
    "california buckeye": "https://en.wikipedia.org/wiki/Aesculus_californica",
    "california buckwheat": "https://en.wikipedia.org/wiki/Eriogonum_fasciculatum",
    "california fuchsia": "https://en.wikipedia.org/wiki/Epilobium_canum",
    "california checkerbloom": "https://en.wikipedia.org/wiki/Sidalcea_malviflora",
    "california lilac": "https://en.wikipedia.org/wiki/Ceanothus",
    "california poppy": "https://en.wikipedia.org/wiki/Eschscholzia_californica",
    "california sagebrush": "https://en.wikipedia.org/wiki/Artemisia_californica",
    "california wild grape": "https://en.wikipedia.org/wiki/Vitis_californica",
    "california wild rose": "https://en.wikipedia.org/wiki/Rosa_californica",
    "coyote mint": "https://en.wikipedia.org/wiki/Monardella",
    "elegant clarkia": "https://en.wikipedia.org/wiki/Clarkia_unguiculata",
    "baby blue eyes": "https://en.wikipedia.org/wiki/Nemophila_menziesii",
    "hummingbird sage": "https://en.wikipedia.org/wiki/Salvia_spathacea",
    "delphinium": "https://en.wikipedia.org/wiki/Delphinium",
    "matilija poppy": "https://en.wikipedia.org/wiki/Romneya_coulteri",
    "blue-eyed grass": "https://en.wikipedia.org/wiki/Sisyrinchium_bellum",
    "penstemon spectabilis": "https://en.wikipedia.org/wiki/Penstemon_spectabilis",
    "seaside daisy": "https://en.wikipedia.org/wiki/Erigeron_glaucus",
    "sticky monkeyflower": "https://en.wikipedia.org/wiki/Diplacus_aurantiacus",
    "tidy tips": "https://en.wikipedia.org/wiki/Layia_platyglossa",
    "wild cucumber": "https://en.wikipedia.org/wiki/Marah_(plant)",
    "douglas iris": "https://en.wikipedia.org/wiki/Iris_douglasiana",
    "goldfields coreopsis": "https://en.wikipedia.org/wiki/Coreopsis"
}

flowers_endangerment = {
    "blazing star": "Not considered endangered.",
    "bristlecone pine": "Least Concern (stable population).",
    "california bluebell": "Not listed as endangered or threatened.",
    "california buckeye": "Not endangered.",
    "california buckwheat": "Generally secure.",
    "california fuchsia": "Not endangered overall; some subspecies at risk.",
    "california checkerbloom": "Not generally endangered; some subspecies critically imperiled.",
    "california lilac": "Most species not endangered; some species are endangered.",
    "california poppy": "Generally secure; some subspecies face threats.",
    "california sagebrush": "Considered secure (G4-G5).",
    "california wild grape": "Apparently secure (G4).",
    "california wild rose": "Secure (G4).",
    "coyote mint": "Varies by species; some federally listed as endangered.",
    "elegant clarkia": "Secure (G5).",
    "baby blue eyes": "Secure.",
    "hummingbird sage": "Apparently secure (G4).",
    "delphinium": "Varies by species; some are endangered.",
    "matilija poppy": "Not currently endangered.",
    "blue-eyed grass": "Not endangered.",
    "penstemon spectabilis": "Not endangered.",
    "seaside daisy": "Not endangered.",
    "sticky monkeyflower": "Not endangered.",
    "tidy tips": "Generally not endangered; some subspecies may be at risk.",
    "wild cucumber": "Generally not endangered.",
    "douglas iris": "Not endangered.",
    "goldfields coreopsis": "Varies by species; many not endangered."
}


def get_status(flower_name):
    """Return the endangerment status of a given flower name."""
    return flowers_endangerment.get(flower_name, "Flower not found in database.")


# Templates for AI image generation
prompt_templates = [
    "A dreamy watercolor scene of a {flower} on a misty morning trail, with golden sunbeams filtering through towering redwoods, and a curious hummingbird hovering nearby.",
    "A loose, expressive watercolor sketch of a {flower} in a wild meadow, surrounded by dancing butterflies and morning dew drops sparkling like diamonds in the dawn light.",
    "An artist's nature journal page featuring a detailed {flower} study, with delicate ink lines and soft watercolor washes, complete with small sketches of bees and field notes in the margins.",
    "A vibrant plein air painting of a {flower} patch along a coastal hiking trail, with crashing waves and rugged cliffs in the background, painted in bold, energetic brushstrokes.",
    "A whimsical mixed-media scene of a {flower} garden at sunrise, combining loose watercolor washes with detailed botanical illustrations, featuring hidden wildlife and morning fog rolling through the valley."
]

# Example images (using local paths)
example_images = [
    str(Path('example_images/example_1.jpg')),
    str(Path('example_images/example_2.jpg')),
    str(Path('example_images/example_3.jpg')),
    str(Path('example_images/example_4.jpg')),
    str(Path('example_images/example_5.jpg'))
]


# Function to handle AI generation progress updates
def on_queue_update(update):
    if isinstance(update, fal_client.InProgress):
        for log in update.logs:
            print(log["message"])


# Main function to process the uploaded image
def process_image(img):
    print("Starting prediction...")
    predicted_class, _, probs = learn.predict(img)
    print(f"Prediction complete: {predicted_class}")

    classification_results = dict(zip(learn.dls.vocab, map(float, probs)))

    # Get Wikipedia link
    wiki_url = search_terms_wikipedia.get(predicted_class, "No Wikipedia entry found.")

    # Get endangerment status
    endangerment_status = get_status(predicted_class)
    print(f"Status found: {endangerment_status}")

    # Generate artistic interpretation using DALL-E
    print("Sending request to DALL-E...")
    try:
        response = openai.images.generate(
            model="dall-e-3",
            prompt=random.choice(prompt_templates).format(flower=predicted_class),
            size="1024x1024",
            quality="standard",
            n=1,
        )

        # Get the image URL
        image_url = response.data[0].url
        print(f"Image URL: {image_url}")

        # Download the generated image
        response = requests.get(image_url)
        generated_image = Image.open(io.BytesIO(response.content))

    except Exception as e:
        print(f"Error generating image: {e}")
        generated_image = None

    print("Image retrieved and ready to return")
    return classification_results, generated_image, wiki_url, endangerment_status


# Function to clear all outputs
def clear_outputs():
    return {
        label_output: None,
        generated_image: None,
        wiki_output: None,
        status_output: None  # ← NEW
    }


# Load the AI model
learn = load_learner('resnet50_30_categories.pkl')

# Create the web interface
with gr.Blocks() as demo:
    # Input section
    with gr.Row():
        input_image = gr.Image(height=230, width=230, label="Upload Image for Classification", type="pil")

    # Output section
    with gr.Row():
        with gr.Column():
            label_output = gr.Label(label="Classification Results")
            wiki_output = gr.Textbox(label="Wikipedia Article Link", lines=1)
            status_output = gr.Textbox(label="Endangerment Status", lines=1)  # ← NEW
        generated_image = gr.Image(label="AI Generated Interpretation")

    # Add example images using local paths
    gr.Examples(
        examples=example_images,
        inputs=input_image,
        examples_per_page=6,
        fn=process_image,
        outputs=[label_output, generated_image, wiki_output, status_output]  # ← UPDATED
    )

    input_image.change(
        fn=process_image,
        inputs=input_image,
        outputs=[label_output, generated_image, wiki_output, status_output]  # ← UPDATED
    )

    input_image.clear(
        fn=clear_outputs,
        inputs=[],
        outputs=[label_output, generated_image, wiki_output, status_output]  # ← UPDATED
    )

# Start the application
demo.launch(inline=False)