Spaces:
Sleeping
Sleeping
Initial HF Commit
Browse files- app.py +27 -0
- requirements.txt +5 -0
- utils.py +114 -0
app.py
ADDED
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
from utils import process_hsv_image
|
3 |
+
|
4 |
+
with gr.Blocks() as app:
|
5 |
+
gr.Markdown("# Color Segmentation Tool using HSV Colorspace")
|
6 |
+
gr.Markdown("Upload an image see the HSV histogram and adjust the Hue bounds to obtain segmented Image based on the range.")
|
7 |
+
|
8 |
+
with gr.Row():
|
9 |
+
with gr.Column():
|
10 |
+
gr.Markdown("### Input Controls")
|
11 |
+
image_input = gr.Image(type="numpy", label="Upload Image")
|
12 |
+
lower = gr.Slider(minimum=0, maximum=180, label="Lower Bound Hue Value", value=0)
|
13 |
+
upper = gr.Slider(minimum=0, maximum=180, label="Upper Bound Hue Value", value=180)
|
14 |
+
update_button = gr.Button("Update", variant="primary")
|
15 |
+
|
16 |
+
with gr.Column():
|
17 |
+
gr.Markdown("### Output Visualizations")
|
18 |
+
hsv_histogram_display = gr.Image(label='HSV Histogram')
|
19 |
+
binary_mask_display = gr.Image(label="Segmentation Output")
|
20 |
+
|
21 |
+
update_button.click(
|
22 |
+
process_hsv_image,
|
23 |
+
inputs=[image_input, lower, upper],
|
24 |
+
outputs=[hsv_histogram_display, binary_mask_display]
|
25 |
+
)
|
26 |
+
|
27 |
+
app.launch()
|
requirements.txt
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
opencv-contrib-python
|
2 |
+
opencv-python
|
3 |
+
matplotlib
|
4 |
+
pillow
|
5 |
+
numpy
|
utils.py
ADDED
@@ -0,0 +1,114 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import cv2
|
2 |
+
import numpy as np
|
3 |
+
import os
|
4 |
+
import matplotlib.pyplot as plt
|
5 |
+
import io
|
6 |
+
from PIL import Image
|
7 |
+
import numpy as np
|
8 |
+
|
9 |
+
def process_bgr_image(img, lb, ub, channel):
|
10 |
+
|
11 |
+
# Define the lower and upperbounds based on the image channel.
|
12 |
+
if channel == 'Blue':
|
13 |
+
lb = np.array([lb, 0, 0], np.uint8)
|
14 |
+
ub = np.array([ub, 255, 255], np.uint8)
|
15 |
+
elif channel == 'Green':
|
16 |
+
lb = np.array([0, lb, 0], np.uint8)
|
17 |
+
ub = np.array([255, ub, 255], np.uint8)
|
18 |
+
elif channel == 'Red':
|
19 |
+
lb = np.array([0, 0, lb], np.uint8)
|
20 |
+
ub = np.array([255, 255, ub], np.uint8)
|
21 |
+
|
22 |
+
# Calculate the histograms for the BGR color space and the Hue channel in the HSV image.
|
23 |
+
hist_b, hist_g, hist_r = calculateHistogram(img, mode='BGR')
|
24 |
+
|
25 |
+
# Plot the histograms
|
26 |
+
hist_bgr = plotHistogram((hist_b, hist_g, hist_r), mode='BGR')
|
27 |
+
|
28 |
+
# Calculate the mask for the given bounds from hsv image
|
29 |
+
op = calculateMask(img, lb, ub, mode='BGR')
|
30 |
+
|
31 |
+
return hist_bgr, op
|
32 |
+
|
33 |
+
def process_hsv_image(img, lb, ub):
|
34 |
+
|
35 |
+
# Conver the image to the HSV color space
|
36 |
+
img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
|
37 |
+
|
38 |
+
# Define the lower and upperbounds for Hue
|
39 |
+
lb = np.array([lb, 0, 0], np.uint8)
|
40 |
+
ub = np.array([ub, 255, 255], np.uint8)
|
41 |
+
|
42 |
+
# Calculate the histograms for the BGR color space and the Hue channel in the HSV image.
|
43 |
+
hist_hue = calculateHistogram(img_hsv, mode='HSV')
|
44 |
+
|
45 |
+
# Plot the histogram.
|
46 |
+
hist_hsv = plotHistogram(hist_hue, mode='HSV')
|
47 |
+
|
48 |
+
# Calculate the mask for the given bounds from hsv image
|
49 |
+
op = calculateMask((img_hsv, img), lb, ub, mode='HSV')
|
50 |
+
|
51 |
+
return hist_hsv, op
|
52 |
+
|
53 |
+
|
54 |
+
def calculateHistogram(img, mode):
|
55 |
+
|
56 |
+
if mode == 'BGR':
|
57 |
+
hist_b = cv2.calcHist([img], [0], None, [256], [0,255])
|
58 |
+
hist_g = cv2.calcHist([img], [1], None, [256], [0,255])
|
59 |
+
hist_r = cv2.calcHist([img], [2], None, [256], [0,255])
|
60 |
+
|
61 |
+
return hist_b, hist_g, hist_r
|
62 |
+
|
63 |
+
elif mode == 'HSV':
|
64 |
+
|
65 |
+
hist_hue = cv2.calcHist([img], [0], None, [180], [0,180])
|
66 |
+
return hist_hue
|
67 |
+
|
68 |
+
def plotHistogram(hists, mode):
|
69 |
+
|
70 |
+
if mode == 'BGR':
|
71 |
+
hist_b, hist_g, hist_r = hists
|
72 |
+
plt.figure(figsize=(10,2))
|
73 |
+
plt.plot(hist_b, color='b', label='Blue')
|
74 |
+
plt.plot(hist_g, color='g', label='Green')
|
75 |
+
plt.plot(hist_r, color='r', label='Red')
|
76 |
+
plt.xlim([0, 255])
|
77 |
+
plt.legend()
|
78 |
+
buf_bgr= io.BytesIO()
|
79 |
+
plt.savefig(buf_bgr, format='png')
|
80 |
+
buf_bgr.seek(0)
|
81 |
+
hist_bgr = Image.open(buf_bgr)
|
82 |
+
plt.close()
|
83 |
+
return hist_bgr
|
84 |
+
|
85 |
+
if mode == 'HSV':
|
86 |
+
|
87 |
+
hist_hue = hists
|
88 |
+
plt.figure(figsize=(10,2))
|
89 |
+
plt.plot(hist_hue, color='black', label='Black')
|
90 |
+
plt.xlim([0, 180])
|
91 |
+
buf_hsv = io.BytesIO()
|
92 |
+
plt.savefig(buf_hsv, format='png')
|
93 |
+
buf_hsv.seek(0)
|
94 |
+
hist_hsv = Image.open(buf_hsv)
|
95 |
+
plt.close()
|
96 |
+
return hist_hsv
|
97 |
+
|
98 |
+
def calculateMask(imgs, lb, ub, mode):
|
99 |
+
|
100 |
+
op = None
|
101 |
+
|
102 |
+
if mode == 'BGR':
|
103 |
+
img = imgs
|
104 |
+
mask_1d = cv2.inRange(img, lb, ub)
|
105 |
+
mask_3d = cv2.merge([mask_1d, mask_1d, mask_1d])
|
106 |
+
op = cv2.bitwise_and(img, mask_3d)
|
107 |
+
|
108 |
+
if mode == 'HSV':
|
109 |
+
img_hsv, img = imgs
|
110 |
+
mask_1d = cv2.inRange(img_hsv, lb, ub)
|
111 |
+
mask_3d = cv2.merge([mask_1d, mask_1d, mask_1d])
|
112 |
+
op = cv2.bitwise_and(img, mask_3d)
|
113 |
+
|
114 |
+
return op
|