Raykarr commited on
Commit
da05eff
·
verified ·
1 Parent(s): f989fc1

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +242 -0
app.py ADDED
@@ -0,0 +1,242 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import numpy as np
3
+ import cv2
4
+ import matplotlib.pyplot as plt
5
+
6
+ # -----------------------------------------------------------------
7
+ # Utility functions
8
+ # -----------------------------------------------------------------
9
+
10
+ def generate_colorful_image(height=256, width=256, p_blue=0.5):
11
+ """
12
+ Generates a synthetic image (height x width) with:
13
+ - 'p_blue' fraction of blueish pixels
14
+ - (1 - p_blue) fraction of near-white/grey
15
+ Includes near-blue shades for more realistic challenge.
16
+ """
17
+ img = np.zeros((height, width, 3), dtype=np.uint8)
18
+ for i in range(height):
19
+ for j in range(width):
20
+ if np.random.rand() < p_blue:
21
+ # Random shade of blue
22
+ b = np.random.randint(100, 256)
23
+ g = np.random.randint(0, 121)
24
+ r = np.random.randint(0, 121)
25
+ if np.random.rand() < 0.3: # shift to near-blue
26
+ g += np.random.randint(0, 30)
27
+ r += np.random.randint(0, 30)
28
+ b = min(b, 255)
29
+ g = min(g, 255)
30
+ r = min(r, 255)
31
+ img[i, j] = [b, g, r]
32
+ else:
33
+ # White/grey region
34
+ base = np.random.randint(180, 256)
35
+ diff_r = np.random.randint(-20, 20)
36
+ diff_g = np.random.randint(-20, 20)
37
+ diff_b = np.random.randint(-20, 20)
38
+ b = np.clip(base + diff_b, 0, 255)
39
+ g = np.clip(base + diff_g, 0, 255)
40
+ r = np.clip(base + diff_r, 0, 255)
41
+ img[i, j] = [b, g, r]
42
+ return img
43
+
44
+ def simple_threshold_blue(image_bgr):
45
+ """
46
+ Simple approach:
47
+ 1) Convert to HSV
48
+ 2) Single broad threshold for blue
49
+ 3) Count ratio of blue pixels
50
+ """
51
+ hsv = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2HSV)
52
+ # Broad range for 'blue'
53
+ lower_blue = np.array([90, 50, 50], dtype=np.uint8)
54
+ upper_blue = np.array([130, 255, 255], dtype=np.uint8)
55
+ mask = cv2.inRange(hsv, lower_blue, upper_blue)
56
+
57
+ blue_pixels = cv2.countNonZero(mask)
58
+ total_pixels = image_bgr.shape[0] * image_bgr.shape[1]
59
+ perc_blue = (blue_pixels / total_pixels) * 100
60
+ return perc_blue, mask
61
+
62
+ def advanced_threshold_blue(image_bgr):
63
+ """
64
+ Advanced approach:
65
+ 1) Multiple color ranges for deep & light blues
66
+ 2) Morphological cleaning
67
+ 3) Count ratio of blue pixels
68
+ """
69
+ hsv = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2HSV)
70
+
71
+ # Range 1: Deeper/darker blues
72
+ lower_blue1 = np.array([90, 50, 50], dtype=np.uint8)
73
+ upper_blue1 = np.array([130, 255, 255], dtype=np.uint8)
74
+ mask1 = cv2.inRange(hsv, lower_blue1, upper_blue1)
75
+
76
+ # Range 2: Lighter or near-cyan
77
+ lower_blue2 = np.array([80, 30, 50], dtype=np.uint8)
78
+ upper_blue2 = np.array([100, 255, 255], dtype=np.uint8)
79
+ mask2 = cv2.inRange(hsv, lower_blue2, upper_blue2)
80
+
81
+ combined_mask = cv2.bitwise_or(mask1, mask2)
82
+
83
+ # Morphological cleaning
84
+ kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3))
85
+ cleaned_mask = cv2.morphologyEx(combined_mask, cv2.MORPH_OPEN, kernel)
86
+ cleaned_mask = cv2.morphologyEx(cleaned_mask, cv2.MORPH_CLOSE, kernel)
87
+
88
+ blue_pixels = cv2.countNonZero(cleaned_mask)
89
+ total_pixels = image_bgr.shape[0] * image_bgr.shape[1]
90
+ perc_blue = (blue_pixels / total_pixels) * 100
91
+ return perc_blue, cleaned_mask
92
+
93
+ def plot_color_histogram(image_bgr):
94
+ """
95
+ Creates a matplotlib figure of B, G, and R channel histograms.
96
+ """
97
+ color = ('b','g','r')
98
+ fig, ax = plt.subplots(figsize=(4,3))
99
+ for i,col in enumerate(color):
100
+ hist = cv2.calcHist([image_bgr],[i],None,[256],[0,256])
101
+ ax.plot(hist, color=col)
102
+ ax.set_xlim([0,256])
103
+ ax.set_title("Color Channel Histogram")
104
+ ax.set_xlabel("Pixel Intensity")
105
+ ax.set_ylabel("Frequency")
106
+ fig.tight_layout()
107
+ return fig
108
+
109
+ # -----------------------------------------------------------------
110
+ # Streamlit App
111
+ # -----------------------------------------------------------------
112
+
113
+ # Page config
114
+ st.set_page_config(page_title="ITC PSPD - Blue Area Detection Demo", layout="centered")
115
+
116
+ st.title("Color Detection Demo for ITC PSPD")
117
+ st.markdown("""
118
+ **This assignment showcases an Industry 4.0 approach** to **color segmentation**,
119
+ demonstrating how tools like Python, OpenCV, and Streamlit can automate **quality checks**
120
+ (similar to checking the quality of paperboards, packaging prints, or other color-critical products).
121
+
122
+ ---
123
+
124
+ **Why It Matters for ITC PSPD**:
125
+ - ITC Paperboards & Specialty Papers Division (PSPD) is a leader in paper, packaging, and specialty solutions.
126
+ - Precise color detection ensures **consistent brand identity**, reduces **defects**, and aligns with ITC's
127
+ **sustainability** and **innovation** ethos.
128
+
129
+ Below, you can:
130
+ 1. **Generate** a synthetic image with random shades of **blue** and **near-white** regions.
131
+ 2. **Analyze** the image using both **Simple** and **Advanced** thresholding.
132
+ 3. **Visualize** color histograms and masks.
133
+ 4. See how this **digital transformation** approach can benefit large-scale production lines.
134
+
135
+ ---
136
+ """)
137
+
138
+ st.sidebar.header("Generation Controls")
139
+ p_blue = st.sidebar.slider("Fraction of Blue-ish Pixels", 0.0, 1.0, 0.5, 0.05)
140
+ img_size = st.sidebar.selectbox("Image Size (px)", [128, 192, 256, 320], index=2)
141
+
142
+ if "random_image" not in st.session_state:
143
+ st.session_state["random_image"] = None
144
+
145
+ st.sidebar.markdown("---")
146
+ if st.sidebar.button("Generate New Random Image"):
147
+ img_bgr = generate_colorful_image(height=img_size, width=img_size, p_blue=p_blue)
148
+ st.session_state["random_image"] = img_bgr
149
+
150
+ # Check if we have an image
151
+ if st.session_state["random_image"] is None:
152
+ st.warning("Use the sidebar to generate a new image.")
153
+ else:
154
+ st.subheader("1) Randomly Generated Image & Color Analysis")
155
+
156
+ # Convert BGR->RGB for display
157
+ img_bgr = st.session_state["random_image"]
158
+ img_rgb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB)
159
+
160
+ col1, col2 = st.columns(2)
161
+ with col1:
162
+ st.image(img_rgb, caption="Synthesized Image (RGB)", width=250)
163
+
164
+ with col2:
165
+ # Show color histogram
166
+ hist_fig = plot_color_histogram(img_bgr)
167
+ st.pyplot(hist_fig)
168
+
169
+ st.markdown("---")
170
+
171
+ # Simple Threshold
172
+ st.subheader("2) Simple Threshold Approach")
173
+ simple_perc_blue, simple_mask = simple_threshold_blue(img_bgr)
174
+
175
+ col3, col4 = st.columns(2)
176
+ with col3:
177
+ st.write(f"**Blue Percentage (Simple):** {simple_perc_blue:.2f}%")
178
+ st.progress(min(simple_perc_blue/100, 1.0))
179
+ with col4:
180
+ st.image(simple_mask, caption="Simple Mask (white=detected blue)", width=250)
181
+
182
+ st.markdown("---")
183
+
184
+ # Advanced Threshold
185
+ st.subheader("3) Advanced Threshold Approach")
186
+ adv_perc_blue, adv_mask = advanced_threshold_blue(img_bgr)
187
+
188
+ col5, col6 = st.columns(2)
189
+ with col5:
190
+ st.write(f"**Blue Percentage (Advanced):** {adv_perc_blue:.2f}%")
191
+ st.progress(min(adv_perc_blue/100, 1.0))
192
+ with col6:
193
+ st.image(adv_mask, caption="Advanced Mask (white=detected blue)", width=250)
194
+
195
+ st.markdown("""
196
+ ---
197
+ ## Relevance to ITC PSPD:
198
+ - **Digital Quality Control**: A color detection system like this can **validate printed matter** (cartons, labels) in real time.
199
+ - **Big Data Integration**: Results could be uploaded to a **data lake**, enabling historical trend analysis and continuous improvement.
200
+ - **Sustainability**: **Accurate color checks** reduce material wastage, aligning with ITC’s triple bottom line (economic, social, environmental) philosophy.
201
+ - **Industry 4.0**: Coupling this solution with **IoT** sensors, real-time dashboards, and advanced analytics ensures **agile and data-driven** paperboard manufacturing.
202
+
203
+ ## Made By:
204
+ **Kaustubh Raykar**
205
+ - +91 7020524609
206
207
208
+
209
+ ---
210
+
211
+ **Thank you for exploring this demonstration!**
212
+ """)
213
+
214
+ # -----------------------------------------------------------------
215
+ # How the Code Works - Explanation
216
+ # -----------------------------------------------------------------
217
+ st.header("How This Code Works")
218
+ st.markdown("""
219
+ 1. **Utility Functions**
220
+ - **generate_colorful_image**: Creates a synthetic image with a customizable proportion of blue pixels. This simulates different real-world scenarios, such as varying amounts of a brand color on packaging.
221
+ - **simple_threshold_blue**: Uses basic HSV thresholding to identify blue pixels. Provides a quick, broad detection method.
222
+ - **advanced_threshold_blue**: Combines multiple ranges for different shades of blue and applies morphological operations for noise reduction, giving more robust results.
223
+ - **plot_color_histogram**: Plots separate color channel (B, G, R) histograms to visualize the distribution of pixel intensities.
224
+
225
+ 2. **Streamlit Layout**
226
+ - **Sidebar**: Controls to adjust the fraction of blueish pixels and the image size. A button to generate a new random image is also included.
227
+ - **Main Page**:
228
+ - Displays the generated image and its color histogram side by side.
229
+ - Shows the simple vs. advanced detection masks with the calculated percentage of blue.
230
+ - Progress bars indicate the proportion of blue visually.
231
+
232
+ 3. **Industry 4.0 Context**
233
+ - By integrating this approach with IoT devices, large-scale manufacturing lines can automate color checks. The masks and percentage calculations serve as a foundation for real-time QA alerts, data logging, and future analytics.
234
+
235
+ 4. **Execution Flow**
236
+ 1. When the user clicks "Generate New Random Image," it calls `generate_colorful_image()` to create a fresh synthetic image.
237
+ 2. The image is converted to RGB for display. Meanwhile, `plot_color_histogram()` renders a histogram for deeper insight into color distribution.
238
+ 3. The **simple_threshold_blue** and **advanced_threshold_blue** functions each produce their own masks and calculations, displayed in the main interface.
239
+ 4. By comparing the results of both methods, users can see the differences in detection accuracy and how morphological operations can refine the result.
240
+
241
+ This cohesive setup ensures a **user-friendly**, **real-time** demonstration of how color segmentation can be applied to industrial use cases—especially relevant for ITC PSPD's commitments to **quality** and **innovation**.
242
+ """)