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