Spaces:
Sleeping
Sleeping
File size: 2,728 Bytes
1b7bc37 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
import cv2
import numpy as np
import os
class ColorDetector:
def __init__(self, color: str = None):
self.mask = None
self.result = None
self._hsv_color = None # Initialize internal hsv storage
# Set a default HSV range (full range)
self._hsv_color = np.array([[0, 0, 0], [179, 255, 255]], dtype=np.uint8)
@property
def hsv_color(self):
if self._hsv_color is None:
# Return a default wide range to avoid errors initially
return np.array([[0, 0, 0], [179, 255, 255]], dtype=np.uint8)
return self._hsv_color
@hsv_color.setter
def hsv_color(self, values):
try:
# Ensure input is a numpy array for consistency and clipping
values_np = np.array(values, dtype=np.uint8)
if values_np.shape != (2, 3):
raise ValueError("HSV values must be a 2x3 array [[h,s,v], [h,s,v]]")
# Verify and adjust HSV value limits using numpy clipping
values_np[0] = np.clip(values_np[0], [0, 0, 0], [179, 255, 255])
values_np[1] = np.clip(values_np[1], [0, 0, 0], [179, 255, 255])
# Ensure min <= max for each channel
for i in range(3):
if values_np[0, i] > values_np[1, i]:
values_np[0, i], values_np[1, i] = (
values_np[1, i],
values_np[0, i],
) # Swap if min > max
self._hsv_color = values_np
except (ValueError, TypeError) as e:
print(f"Error setting HSV values: {e}. Expected format [[h,s,v],[h,s,v]].")
def filterColor(self, img):
"""
Apply the HSV filter to an image.
Args:
img (numpy.ndarray): Input image in BGR format.
Returns:
tuple: (mask, filtered_result) - The binary mask and color-filtered result
"""
imgHsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
lower_bound = self.hsv_color[0]
upper_bound = self.hsv_color[1]
# Filter the desired color
mask = cv2.inRange(imgHsv, lower_bound, upper_bound)
# Remove noise
mask = cv2.dilate(mask, np.ones((11, 11), np.uint8), iterations=1)
mask = cv2.erode(mask, np.ones((7, 7), np.uint8), iterations=1)
# Morphological operations for further noise removal and closing gaps
mask = cv2.morphologyEx(mask, cv2.MORPH_DILATE, np.ones((8, 8), np.uint8))
# Apply the mask to the original image to get the filtered result
result = cv2.bitwise_and(img, img, mask=mask)
# Store the results
self.mask = mask
self.result = result
return mask, result
|