Skip to content

Commit 22c4c01

Browse files
authored
HSV Filter Tool
allows users to interactively select an HSV color range from an image using trackbars and outputs the selected HSV values. Useful for finding thresholds for basic color filtration when trying to detect an object in an image
1 parent 634532c commit 22c4c01

File tree

1 file changed

+135
-0
lines changed

1 file changed

+135
-0
lines changed

computer_vision/hsv_threshold

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
"""
2+
HSV Filter Tool
3+
4+
This module allows the user to interactively select an HSV color range
5+
from an image using trackbars and outputs the selected HSV values.
6+
7+
Dependencies:
8+
- OpenCV (cv2)
9+
- NumPy
10+
11+
Usage:
12+
1. Set `IMAGE_PATH` to your image file.
13+
2. Run the script.
14+
3. Adjust the trackbars to select the desired HSV range.
15+
4. Press Enter to print the HSV lower and upper bounds.
16+
"""
17+
18+
import cv2
19+
import numpy as np
20+
21+
IMAGE_PATH = r"C:\Users\username\New folder\your_image.png"
22+
23+
24+
def load_image(path: str) -> np.ndarray:
25+
"""
26+
Load an image from the specified path.
27+
28+
Parameters
29+
----------
30+
path : str
31+
Path to the image file.
32+
33+
Returns
34+
-------
35+
np.ndarray
36+
Loaded BGR image.
37+
38+
Raises
39+
------
40+
FileNotFoundError
41+
If the image cannot be loaded.
42+
"""
43+
image = cv2.imread(path)
44+
if image is None:
45+
raise FileNotFoundError(f"Failed to load image at path: {path}")
46+
return image
47+
48+
49+
def create_hsv_trackbars(window_name: str) -> None:
50+
"""
51+
Create HSV trackbars for filtering.
52+
53+
Parameters
54+
----------
55+
window_name : str
56+
Name of the OpenCV window.
57+
"""
58+
cv2.createTrackbar("H Lower", window_name, 0, 179, lambda x: None)
59+
cv2.createTrackbar("S Lower", window_name, 0, 255, lambda x: None)
60+
cv2.createTrackbar("V Lower", window_name, 0, 255, lambda x: None)
61+
cv2.createTrackbar("H Upper", window_name, 179, 179, lambda x: None)
62+
cv2.createTrackbar("S Upper", window_name, 255, 255, lambda x: None)
63+
cv2.createTrackbar("V Upper", window_name, 255, 255, lambda x: None)
64+
65+
66+
def get_hsv_bounds(window_name: str) -> tuple[np.ndarray, np.ndarray]:
67+
"""
68+
Read the HSV lower and upper bounds from the trackbars.
69+
70+
Parameters
71+
----------
72+
window_name : str
73+
Name of the OpenCV window.
74+
75+
Returns
76+
-------
77+
tuple[np.ndarray, np.ndarray]
78+
Lower and upper HSV bounds as NumPy arrays.
79+
"""
80+
lower_bound = np.array([
81+
cv2.getTrackbarPos("H Lower", window_name),
82+
cv2.getTrackbarPos("S Lower", window_name),
83+
cv2.getTrackbarPos("V Lower", window_name),
84+
])
85+
upper_bound = np.array([
86+
cv2.getTrackbarPos("H Upper", window_name),
87+
cv2.getTrackbarPos("S Upper", window_name),
88+
cv2.getTrackbarPos("V Upper", window_name),
89+
])
90+
return lower_bound, upper_bound
91+
92+
93+
def main() -> None:
94+
"""
95+
Main function to run the HSV filter tool.
96+
97+
Opens the image, creates trackbars, shows filtered results,
98+
and prints the final HSV bounds when Enter is pressed.
99+
"""
100+
try:
101+
image = load_image(IMAGE_PATH)
102+
except FileNotFoundError as e:
103+
print(e)
104+
return
105+
106+
window_name = "HSV Filter"
107+
cv2.namedWindow(window_name)
108+
create_hsv_trackbars(window_name)
109+
110+
while True:
111+
hsv_image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
112+
113+
lower, upper = get_hsv_bounds(window_name)
114+
115+
mask = cv2.inRange(hsv_image, lower, upper)
116+
filtered_result = cv2.bitwise_and(image, image, mask=mask)
117+
118+
cv2.imshow("Original", image)
119+
cv2.imshow("Filtered", filtered_result)
120+
121+
key = cv2.waitKey(1) & 0xFF
122+
if key == 13: # Enter key
123+
print(f"HSV Range (Lower): {lower}")
124+
print(f"HSV Range (Upper): {upper}")
125+
print(
126+
f"CSV Format: {lower[0]},{lower[1]},{lower[2]},"
127+
f"{upper[0]},{upper[1]},{upper[2]}"
128+
)
129+
break
130+
131+
cv2.destroyAllWindows()
132+
133+
134+
if __name__ == "__main__":
135+
main()

0 commit comments

Comments
 (0)