import streamlit as st import numpy as np import cv2 import matplotlib.pyplot as plt # ----------------------------------------------------------------- # Utility functions # ----------------------------------------------------------------- def generate_colorful_image(height=256, width=256, p_blue=0.5): """ Generates a synthetic image (height x width) with: - 'p_blue' fraction of blueish pixels - (1 - p_blue) fraction of near-white/grey Includes near-blue shades for more realistic challenge. """ img = np.zeros((height, width, 3), dtype=np.uint8) for i in range(height): for j in range(width): if np.random.rand() < p_blue: # Random shade of blue b = np.random.randint(100, 256) g = np.random.randint(0, 121) r = np.random.randint(0, 121) if np.random.rand() < 0.3: # shift to near-blue g += np.random.randint(0, 30) r += np.random.randint(0, 30) b = min(b, 255) g = min(g, 255) r = min(r, 255) img[i, j] = [b, g, r] else: # White/grey region base = np.random.randint(180, 256) diff_r = np.random.randint(-20, 20) diff_g = np.random.randint(-20, 20) diff_b = np.random.randint(-20, 20) b = np.clip(base + diff_b, 0, 255) g = np.clip(base + diff_g, 0, 255) r = np.clip(base + diff_r, 0, 255) img[i, j] = [b, g, r] return img def simple_threshold_blue(image_bgr): """ Simple approach: 1) Convert to HSV 2) Single broad threshold for blue 3) Count ratio of blue pixels """ hsv = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2HSV) # Broad range for 'blue' lower_blue = np.array([90, 50, 50], dtype=np.uint8) upper_blue = np.array([130, 255, 255], dtype=np.uint8) mask = cv2.inRange(hsv, lower_blue, upper_blue) blue_pixels = cv2.countNonZero(mask) total_pixels = image_bgr.shape[0] * image_bgr.shape[1] perc_blue = (blue_pixels / total_pixels) * 100 return perc_blue, mask def advanced_threshold_blue(image_bgr): """ Advanced approach: 1) Multiple color ranges for deep & light blues 2) Morphological cleaning 3) Count ratio of blue pixels """ hsv = cv2.cvtColor(image_bgr, cv2.COLOR_BGR2HSV) # Range 1: Deeper/darker blues lower_blue1 = np.array([90, 50, 50], dtype=np.uint8) upper_blue1 = np.array([130, 255, 255], dtype=np.uint8) mask1 = cv2.inRange(hsv, lower_blue1, upper_blue1) # Range 2: Lighter or near-cyan lower_blue2 = np.array([80, 30, 50], dtype=np.uint8) upper_blue2 = np.array([100, 255, 255], dtype=np.uint8) mask2 = cv2.inRange(hsv, lower_blue2, upper_blue2) combined_mask = cv2.bitwise_or(mask1, mask2) # Morphological cleaning kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3)) cleaned_mask = cv2.morphologyEx(combined_mask, cv2.MORPH_OPEN, kernel) cleaned_mask = cv2.morphologyEx(cleaned_mask, cv2.MORPH_CLOSE, kernel) blue_pixels = cv2.countNonZero(cleaned_mask) total_pixels = image_bgr.shape[0] * image_bgr.shape[1] perc_blue = (blue_pixels / total_pixels) * 100 return perc_blue, cleaned_mask def plot_color_histogram(image_bgr): """ Creates a matplotlib figure of B, G, and R channel histograms. """ color = ('b','g','r') fig, ax = plt.subplots(figsize=(4,3)) for i,col in enumerate(color): hist = cv2.calcHist([image_bgr],[i],None,[256],[0,256]) ax.plot(hist, color=col) ax.set_xlim([0,256]) ax.set_title("Color Channel Histogram") ax.set_xlabel("Pixel Intensity") ax.set_ylabel("Frequency") fig.tight_layout() return fig # ----------------------------------------------------------------- # Streamlit App # ----------------------------------------------------------------- # Page config st.set_page_config(page_title="ITC PSPD - Blue Area Detection Demo", layout="centered") st.title("Color Detection Demo for ITC PSPD") st.markdown(""" **This assignment showcases an Industry 4.0 approach** to **color segmentation**, demonstrating how tools like Python, OpenCV, and Streamlit can automate **quality checks** (similar to checking the quality of paperboards, packaging prints, or other color-critical products). --- **Why It Matters for ITC PSPD**: - ITC Paperboards & Specialty Papers Division (PSPD) is a leader in paper, packaging, and specialty solutions. - Precise color detection ensures **consistent brand identity**, reduces **defects**, and aligns with ITC's **sustainability** and **innovation** ethos. Below, you can: 1. **Generate** a synthetic image with random shades of **blue** and **near-white** regions. 2. **Analyze** the image using both **Simple** and **Advanced** thresholding. 3. **Visualize** color histograms and masks. 4. See how this **digital transformation** approach can benefit large-scale production lines. --- """) st.sidebar.header("Generation Controls") p_blue = st.sidebar.slider("Fraction of Blue-ish Pixels", 0.0, 1.0, 0.5, 0.05) img_size = st.sidebar.selectbox("Image Size (px)", [128, 192, 256, 320], index=2) if "random_image" not in st.session_state: st.session_state["random_image"] = None st.sidebar.markdown("---") if st.sidebar.button("Generate New Random Image"): img_bgr = generate_colorful_image(height=img_size, width=img_size, p_blue=p_blue) st.session_state["random_image"] = img_bgr # Check if we have an image if st.session_state["random_image"] is None: st.warning("Use the sidebar to generate a new image.") else: st.subheader("1) Randomly Generated Image & Color Analysis") # Convert BGR->RGB for display img_bgr = st.session_state["random_image"] img_rgb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB) col1, col2 = st.columns(2) with col1: st.image(img_rgb, caption="Synthesized Image (RGB)", width=250) with col2: # Show color histogram hist_fig = plot_color_histogram(img_bgr) st.pyplot(hist_fig) st.markdown("---") # Simple Threshold st.subheader("2) Simple Threshold Approach") simple_perc_blue, simple_mask = simple_threshold_blue(img_bgr) col3, col4 = st.columns(2) with col3: st.write(f"**Blue Percentage (Simple):** {simple_perc_blue:.2f}%") st.progress(min(simple_perc_blue/100, 1.0)) with col4: st.image(simple_mask, caption="Simple Mask (white=detected blue)", width=250) st.markdown("---") # Advanced Threshold st.subheader("3) Advanced Threshold Approach") adv_perc_blue, adv_mask = advanced_threshold_blue(img_bgr) col5, col6 = st.columns(2) with col5: st.write(f"**Blue Percentage (Advanced):** {adv_perc_blue:.2f}%") st.progress(min(adv_perc_blue/100, 1.0)) with col6: st.image(adv_mask, caption="Advanced Mask (white=detected blue)", width=250) st.markdown(""" --- ## Relevance to ITC PSPD: - **Digital Quality Control**: A color detection system like this can **validate printed matter** (cartons, labels) in real time. - **Big Data Integration**: Results could be uploaded to a **data lake**, enabling historical trend analysis and continuous improvement. - **Sustainability**: **Accurate color checks** reduce material wastage, aligning with ITC’s triple bottom line (economic, social, environmental) philosophy. - **Industry 4.0**: Coupling this solution with **IoT** sensors, real-time dashboards, and advanced analytics ensures **agile and data-driven** paperboard manufacturing. ## Made By: **Kaustubh Raykar** - +91 7020524609 - [raykarkaustubh@gmail.com](mailto:raykarkaustubh@gmail.com) - [kaustubh.raykar.btech2021@sitpune.edu.in](mailto:kaustubh.raykar.btech2021@sitpune.edu.in) --- **Thank you for exploring this demonstration!** """) # ----------------------------------------------------------------- # How the Code Works - Explanation # ----------------------------------------------------------------- st.header("How This Code Works") st.markdown(""" 1. **Utility Functions** - **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. - **simple_threshold_blue**: Uses basic HSV thresholding to identify blue pixels. Provides a quick, broad detection method. - **advanced_threshold_blue**: Combines multiple ranges for different shades of blue and applies morphological operations for noise reduction, giving more robust results. - **plot_color_histogram**: Plots separate color channel (B, G, R) histograms to visualize the distribution of pixel intensities. 2. **Streamlit Layout** - **Sidebar**: Controls to adjust the fraction of blueish pixels and the image size. A button to generate a new random image is also included. - **Main Page**: - Displays the generated image and its color histogram side by side. - Shows the simple vs. advanced detection masks with the calculated percentage of blue. - Progress bars indicate the proportion of blue visually. 3. **Industry 4.0 Context** - 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. 4. **Execution Flow** 1. When the user clicks "Generate New Random Image," it calls `generate_colorful_image()` to create a fresh synthetic image. 2. The image is converted to RGB for display. Meanwhile, `plot_color_histogram()` renders a histogram for deeper insight into color distribution. 3. The **simple_threshold_blue** and **advanced_threshold_blue** functions each produce their own masks and calculations, displayed in the main interface. 4. By comparing the results of both methods, users can see the differences in detection accuracy and how morphological operations can refine the result. 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**. """)