reinformator commited on
Commit
7fa0187
Β·
verified Β·
1 Parent(s): 31e6174

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +177 -97
app.py CHANGED
@@ -1,119 +1,199 @@
1
- # IMPORTANT: These environment variables must be set before any other imports
2
  import os
3
  os.environ["PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION"] = "python"
4
  os.environ["PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION_VERSION"] = "2"
5
 
6
  import streamlit as st
7
- import cv2
8
- import numpy as np
9
  from PIL import Image
10
- from mtcnn import MTCNN
11
- from deepface import DeepFace
12
- from transformers import BlipProcessor, BlipForConditionalGeneration
13
-
14
- # Initialize MTCNN for face detection
15
- detector = MTCNN()
16
-
17
- # Load BLIP model for scene description
 
 
 
 
 
18
  @st.cache_resource
19
- def load_blip_model():
20
- processor = BlipProcessor.from_pretrained("Salesforce/blip-image-captioning-base")
21
- model = BlipForConditionalGeneration.from_pretrained("Salesforce/blip-image-captioning-base")
22
- return processor, model
23
-
24
- processor, blip_model = load_blip_model()
25
-
26
- # Function for face analysis using DeepFace
27
- def analyze_face(face_image):
28
- face_array = np.array(face_image)
29
- try:
30
- result = DeepFace.analyze(face_array, actions=['emotion', 'gender', 'age', 'race'], enforce_detection=False)
31
- return result
32
- except Exception as e:
33
- return {"error": str(e)}
34
-
35
- # Function for glasses detection using Haar Cascade
36
- def detect_glasses(face_image):
37
- # Path to Haar Cascade in the main folder
38
- haar_cascade_path = os.path.join(os.getcwd(), 'haarcascade_frontalface_default.xml')
39
 
40
- # Load Haar Cascade for glasses detection
41
- glasses_cascade = cv2.CascadeClassifier(haar_cascade_path)
 
42
 
43
- # Convert to grayscale
44
- face_array = np.array(face_image.convert("L"))
 
45
 
46
- # Perform detection
47
- detected_glasses = glasses_cascade.detectMultiScale(face_array, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30))
 
48
 
49
- return "Yes" if len(detected_glasses) > 0 else "No"
 
 
 
 
 
50
 
51
- # Function for scene description using BLIP
52
  @st.cache_data
53
- def describe_scene(image):
54
- inputs = processor(image, return_tensors="pt")
55
- outputs = blip_model.generate(**inputs)
 
 
 
 
 
 
 
 
56
  caption = processor.decode(outputs[0], skip_special_tokens=True)
57
  return caption
58
 
59
- # Main Streamlit application
60
- def main():
61
- st.title("Comprehensive Image Analysis")
62
- st.write("Upload an image to analyze faces, detect glasses, and provide scene descriptions.")
63
-
64
- uploaded_image = st.file_uploader("Upload an image...", type=["jpg", "jpeg", "png"])
65
-
66
- if uploaded_image is not None:
67
- image = Image.open(uploaded_image).convert("RGB")
68
- st.image(image, caption="Uploaded Image", use_container_width=True)
69
-
70
- if st.button("Analyze"):
71
- with st.spinner("Analyzing..."):
72
- # Scene description using BLIP
73
- scene_caption = describe_scene(image)
74
- st.subheader("Scene Description")
75
- st.write(scene_caption)
76
-
77
- # Detect faces using MTCNN
78
- faces = detector.detect_faces(np.array(image))
79
-
80
- if faces:
81
- st.write(f"**Number of Faces Detected:** {len(faces)}")
82
-
83
- for i, face in enumerate(faces):
84
- x, y, width, height = face['box']
85
- face_crop = image.crop((x, y, x + width, y + height))
86
- face_crop_resized = face_crop.resize((150, 150))
87
-
88
- st.subheader(f"Analysis for Face {i + 1}")
89
- st.image(face_crop_resized, caption=f"Face {i + 1}", width=150)
90
-
91
- # Analyze face with DeepFace
92
- result = analyze_face(face_crop)
93
- if "error" in result:
94
- st.error(f"Face Analysis Error: {result['error']}")
95
- else:
96
- single_result = result[0] if isinstance(result, list) else result
97
- gender = single_result.get('gender', 'N/A')
98
- age = single_result.get('age', 'N/A')
99
- race = single_result.get('dominant_race', 'N/A')
100
- emotions = single_result.get('emotion', {})
101
 
102
- st.write(f"**Gender:** {gender}")
103
- st.write(f"**Age:** {age}")
104
- st.write(f"**Race:** {race}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
 
106
- # Display emotions as text with percentages
107
- if emotions:
108
- sorted_emotions = sorted(emotions.items(), key=lambda x: x[1], reverse=True)
109
- emotion_text = ", ".join([f"{emotion}: {prob:.2f}%" for emotion, prob in sorted_emotions])
110
- st.write(f"**Emotions:** {emotion_text}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111
 
112
- # Glasses detection
113
- glasses = detect_glasses(face_crop)
114
- st.write(f"**Glasses:** {glasses}")
115
- else:
116
- st.write("No faces detected.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
117
 
118
  if __name__ == "__main__":
119
  main()
 
 
1
  import os
2
  os.environ["PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION"] = "python"
3
  os.environ["PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION_VERSION"] = "2"
4
 
5
  import streamlit as st
6
+ import torch
 
7
  from PIL import Image
8
+ import numpy as np
9
+ from transformers import (
10
+ BlipProcessor,
11
+ BlipForConditionalGeneration,
12
+ AutoProcessor,
13
+ AutoModelForObjectDetection,
14
+ CLIPProcessor,
15
+ CLIPModel,
16
+ ViTImageProcessor,
17
+ ViTForImageClassification
18
+ )
19
+
20
+ # Initialize models with caching
21
  @st.cache_resource
22
+ def load_models():
23
+ """Load and cache all required models"""
24
+
25
+ # BLIP for detailed image captioning
26
+ blip_processor = BlipProcessor.from_pretrained("Salesforce/blip-image-captioning-large")
27
+ blip_model = BlipForConditionalGeneration.from_pretrained("Salesforce/blip-image-captioning-large")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
 
29
+ # DETR for object detection
30
+ detr_processor = AutoProcessor.from_pretrained("facebook/detr-resnet-50")
31
+ detr_model = AutoModelForObjectDetection.from_pretrained("facebook/detr-resnet-50")
32
 
33
+ # CLIP for visual attributes and concepts
34
+ clip_processor = CLIPProcessor.from_pretrained("openai/clip-vit-base-patch32")
35
+ clip_model = CLIPModel.from_pretrained("openai/clip-vit-base-patch32")
36
 
37
+ # ViT for scene classification
38
+ vit_processor = ViTImageProcessor.from_pretrained('google/vit-base-patch16-224')
39
+ vit_model = ViTForImageClassification.from_pretrained('google/vit-base-patch16-224')
40
 
41
+ return (
42
+ blip_processor, blip_model,
43
+ detr_processor, detr_model,
44
+ clip_processor, clip_model,
45
+ vit_processor, vit_model
46
+ )
47
 
 
48
  @st.cache_data
49
+ def generate_caption(_image, processor, model):
50
+ """Generate detailed image caption using BLIP"""
51
+ inputs = processor(_image, return_tensors="pt")
52
+ outputs = model.generate(
53
+ **inputs,
54
+ max_length=100,
55
+ num_beams=5,
56
+ temperature=1.0,
57
+ top_p=0.9,
58
+ repetition_penalty=1.5
59
+ )
60
  caption = processor.decode(outputs[0], skip_special_tokens=True)
61
  return caption
62
 
63
+ @st.cache_data
64
+ def detect_objects(_image, processor, model):
65
+ """Detect objects in the image using DETR"""
66
+ inputs = processor(_image, return_tensors="pt")
67
+ outputs = model(**inputs)
68
+
69
+ # Post-process object detection results
70
+ target_sizes = torch.tensor([_image.size[::-1]])
71
+ results = processor.post_process_object_detection(
72
+ outputs,
73
+ target_sizes=target_sizes,
74
+ threshold=0.7
75
+ )[0]
76
+
77
+ objects = []
78
+ for score, label, box in zip(results["scores"], results["labels"], results["boxes"]):
79
+ objects.append({
80
+ 'label': model.config.id2label[label.item()],
81
+ 'confidence': score.item(),
82
+ 'box': box.tolist()
83
+ })
84
+
85
+ return objects
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
 
87
+ @st.cache_data
88
+ def analyze_visual_attributes(_image, processor, model):
89
+ """Analyze visual attributes using CLIP"""
90
+ # Define candidate attributes to check
91
+ attributes = [
92
+ "bright", "dark", "colorful", "monochrome",
93
+ "natural", "artificial", "indoor", "outdoor",
94
+ "modern", "vintage", "abstract", "realistic",
95
+ "simple", "complex", "symmetrical", "asymmetrical",
96
+ "high contrast", "low contrast", "textured", "smooth"
97
+ ]
98
+
99
+ inputs = processor(
100
+ images=_image,
101
+ text=attributes,
102
+ return_tensors="pt",
103
+ padding=True
104
+ )
105
+
106
+ outputs = model(**inputs)
107
+ probs = outputs.logits_per_image.softmax(dim=1)[0]
108
+
109
+ return [(attr, prob.item()) for attr, prob in zip(attributes, probs)]
110
 
111
+ @st.cache_data
112
+ def classify_scene(_image, processor, model):
113
+ """Classify the scene type using ViT"""
114
+ inputs = processor(_image, return_tensors="pt")
115
+ outputs = model(**inputs)
116
+ probs = outputs.logits.softmax(dim=-1)[0]
117
+
118
+ # Get top 5 predictions
119
+ top_probs, top_indices = torch.topk(probs, 5)
120
+ predictions = [
121
+ (model.config.id2label[idx.item()], prob.item())
122
+ for idx, prob in zip(top_indices, top_probs)
123
+ ]
124
+
125
+ return predictions
126
+
127
+ def format_attributes(attributes):
128
+ """Format visual attributes for display"""
129
+ significant_attrs = [(attr, score) for attr, score in attributes if score > 0.7]
130
+ if significant_attrs:
131
+ return ", ".join([
132
+ f"{attr} ({score:.1%})"
133
+ for attr, score in sorted(significant_attrs, key=lambda x: x[1], reverse=True)
134
+ ])
135
+ return "No strong visual attributes detected"
136
 
137
+ def main():
138
+ st.set_page_config(page_title="Image Description System", layout="wide")
139
+ st.title("πŸ–ΌοΈ Comprehensive Image Description System")
140
+ st.write("Upload an image to get a detailed analysis of its content and characteristics.")
141
+
142
+ # Load all models
143
+ with st.spinner("Loading models..."):
144
+ (
145
+ blip_processor, blip_model,
146
+ detr_processor, detr_model,
147
+ clip_processor, clip_model,
148
+ vit_processor, vit_model
149
+ ) = load_models()
150
+
151
+ # File uploader
152
+ uploaded_file = st.file_uploader(
153
+ "Choose an image...",
154
+ type=['jpg', 'jpeg', 'png'],
155
+ help="Upload a clear image for the best analysis results"
156
+ )
157
+
158
+ if uploaded_file:
159
+ # Load and display image
160
+ image = Image.open(uploaded_file).convert('RGB')
161
+ st.image(image, caption="Uploaded Image", use_column_width=True)
162
+
163
+ if st.button("πŸ” Analyze Image"):
164
+ with st.spinner("Analyzing image..."):
165
+ # 1. Generate detailed caption
166
+ caption = generate_caption(image, blip_processor, blip_model)
167
+ st.subheader("πŸ“ Detailed Description")
168
+ st.write(caption)
169
+
170
+ # Create two columns for remaining analysis
171
+ col1, col2 = st.columns(2)
172
+
173
+ with col1:
174
+ # 2. Detect and list objects
175
+ st.subheader("🎯 Detected Objects")
176
+ objects = detect_objects(image, detr_processor, detr_model)
177
+ if objects:
178
+ for obj in sorted(objects, key=lambda x: x['confidence'], reverse=True):
179
+ st.write(f"β€’ {obj['label']} ({obj['confidence']:.1%} confidence)")
180
+ else:
181
+ st.write("No objects detected with high confidence.")
182
+
183
+ # 3. Scene classification
184
+ st.subheader("🏞️ Scene Classification")
185
+ scenes = classify_scene(image, vit_processor, vit_model)
186
+ for scene, prob in scenes:
187
+ st.write(f"β€’ {scene} ({prob:.1%} confidence)")
188
+
189
+ with col2:
190
+ # 4. Visual attributes
191
+ st.subheader("🎨 Visual Attributes")
192
+ attributes = analyze_visual_attributes(image, clip_processor, clip_model)
193
+ formatted_attrs = format_attributes(attributes)
194
+ st.write(formatted_attrs)
195
+
196
+ st.success("Analysis complete! ✨")
197
 
198
  if __name__ == "__main__":
199
  main()