예제 #1
0
class ColorThreshold(Filter):

    """Apply a binary threshold on the three channels of the images
        Each channel have a minimum and a maximum value.
        Everything within this threshold is white (255, 255, 255)
        Everything else is black (0, 0, 0)"""

    def __init__(self):
        Filter.__init__(self)
        self.blue = Param("Blue", 20, min_v=1, max_v=256, thres_h=256)
        self.green = Param("Green", 20, min_v=1, max_v=256, thres_h=256)
        self.red = Param("Red", 20, min_v=1, max_v=256, thres_h=256)
        self._barray = None
        self._garray = None
        self._rarray = None
        self.configure()

    def configure(self):
        min_v, max_v = self.blue.get()
        self._barray = np.array([1.0 * (min_v <= x <= max_v)
                                 for x in range(0, 256)], dtype=np.float32)
        min_v, max_v = self.green.get()
        self._garray = np.array([1.0 * (min_v <= x <= max_v)
                                 for x in range(0, 256)], dtype=np.float32)
        min_v, max_v = self.red.get()
        self._rarray = np.array([1.0 * (min_v <= x <= max_v)
                                 for x in range(0, 256)], dtype=np.float32)

    def execute(self, image):
        image[:, :, 0] = image[:, :, 1] = image[:, :, 2] = (
            255 * self._barray[image[:, :, 0]] *
            self._garray[image[:, :, 1]] *
            self._rarray[image[:, :, 2]])
        return image
예제 #2
0
class Morphology(Filter):
    def __init__(self):
        Filter.__init__(self)
        self.kernel_width = Param("Kernel Width", 3, min_v=1, max_v=256)
        self.kernel_height = Param("Kernel Height", 3, min_v=1, max_v=256)
        self.anchor_x = Param("Anchor X", -1)
        self.anchor_y = Param("Anchor Y", -1)
        self.iterations = Param("Iteration,", 1, min_v=1)
        self.configure()

    def configure(self):
        self._kernel = cv2.getStructuringElement(
            cv2.MORPH_RECT,
            (self.kernel_width.get(), self.kernel_height.get()),
            (self.anchor_x.get(), self.anchor_y.get()))

    def execute(self, image):
        morph = cv2.cvtColor(image, cv.CV_BGR2GRAY)
        cv2.morphologyEx(morph,
                         cv2.MORPH_CLOSE,
                         self._kernel,
                         dst=morph,
                         iterations=self.iterations.get())
        cv2.merge((morph, morph, morph), image)

        return image
예제 #3
0
class Morphology(Filter):

    def __init__(self):
        Filter.__init__(self)
        self.kernel_width = Param("Kernel Width", 3, min_v=1, max_v=256)
        self.kernel_height = Param("Kernel Height", 3, min_v=1, max_v=256)
        self.anchor_x = Param("Anchor X", -1)
        self.anchor_y = Param("Anchor Y", -1)
        self.iterations = Param("Iteration,", 1, min_v=1)
        self.configure()

    def configure(self):
        self._kernel = cv2.getStructuringElement(cv2.MORPH_RECT,
                                                 (self.kernel_width.get(),
                                                  self.kernel_height.get()),
                                                 (self.anchor_x.get(),
                                                  self.anchor_y.get()))

    def execute(self, image):
        morph = cv2.cvtColor(image, cv.CV_BGR2GRAY)
        cv2.morphologyEx(
            morph,
            cv2.MORPH_CLOSE,
            self._kernel,
            dst=morph,
            iterations=self.iterations.get())
        cv2.merge((morph, morph, morph), image)

        return image
예제 #4
0
class ParticleFilter(Filter):
    """Remove small particles from the image.
        The image is first converted to grayscale and is then eroded and
        the remaining blobs are filtered according to the area of the blobs."""
    def __init__(self):
        Filter.__init__(self)
        self.kernel_height = Param("Kernel Height", 10, min_v=1, max_v=256)
        self.kernel_width = Param("Kernel Width", 10, min_v=1, max_v=256)
        self.area_min = Param("Area Min", 3200, min_v=1)
        self.configure()

    def configure(self):
        self._kernel = cv2.getStructuringElement(
            cv2.MORPH_CROSS,
            (self.kernel_width.get(), self.kernel_height.get()))

    def execute(self, image):
        cv2.erode(image, self._kernel, image)
        gray = cv2.split(image)[0]
        contours, _ = cv2.findContours(gray, cv2.RETR_TREE,
                                       cv2.CHAIN_APPROX_SIMPLE)

        image = np.zeros(image.shape, np.uint8)
        for contour in contours:
            area = np.abs(cv2.contourArea(contour))
            if area > self.area_min.get():
                cv2.drawContours(image, [contour],
                                 -1, (255, 255, 255),
                                 thickness=-1)
        return image
예제 #5
0
class LineOrientation(Filter):
    """Port of the old line detection code"""

    def __init__(self):
        Filter.__init__(self)
        self.area_min = Param("Area Min", 300, min_v=1, max_v=100000)
        self.area_max = Param("Area Max", 35000, min_v=1, max_v=100000)

        self._kernel = cv2.getStructuringElement(
            cv2.MORPH_RECT, (3, 3), (0, 0))

    def execute(self, image):
        image_threshold = cv2.split(image)[0]
        image_morphology = cv2.morphologyEx(
            image_threshold, cv2.MORPH_CLOSE, self._kernel, iterations=1)

        contours, _ = cv2.findContours(
            image_morphology,
            cv2.RETR_TREE,
            cv2.CHAIN_APPROX_SIMPLE)
        lines = self.find_lines(contours, image)
        self.draw_lines(lines, image)

        return image

    def draw_lines(self, lines, image):
        msg = "LineOrientation: x1=%s x2=%s y1=%s y2=%s \n"
        for l, t in lines:
            vx, vy, x, y = l
            point1 = (x - t * vx, y - t * vy)
            point2 = (x + t * vx, y + t * vy)
            to_send = msg % (int(point1[0][0]),
                             int(point1[1][0]),
                             int(point2[0][0]),
                             int(point2[1][0]))
            self.notify_output_observers(to_send)
            cv2.line(image, point1, point2, (0, 0, 255), 3, -1)
            cv2.circle(image, (x, y), 5, (0, 255, 0), -1)

        self.notify_output_observers("LineOrientation: \n")

    def find_lines(self, contours, image):
        lines = []
        for contour in contours:
            approx = cv2.approxPolyDP(contour, 0, False)
            area = np.abs(cv2.contourArea(contour))

            if self.area_min.get() < area < self.area_max.get():
                line_values = cv2.fitLine(approx, cv.CV_DIST_L2, 0, 0.01, 0.01)
                rect = cv2.boundingRect(approx)
                t = math.sqrt((rect[2] ** 2 + rect[3] ** 2) / 2.0)
                lines.append((line_values, t))
                cv2.drawContours(image, contour, -1, (255, 255, 0))

        return lines
예제 #6
0
class BilateralFilter(Filter):
    """Applies the bilateral filter to an image."""
    def __init__(self):
        Filter.__init__(self)
        self.diameter = Param("Diameter", 10, min_v=0, max_v=255)
        self.sigma_color = Param("Sigma Color", 0, min_v=0, max_v=255)
        self.sigma_space = Param("Sigma Space", 0, min_v=0, max_v=255)

    def execute(self, image):
        return cv2.bilateralFilter(image, self.diameter.get(),
                                   self.sigma_color.get(),
                                   self.sigma_space.get())
예제 #7
0
class Blur(Filter):
    """Smoothes an image using the normalized box filter"""
    def __init__(self):
        Filter.__init__(self)
        self.kernel_width = Param("width", 3, min_v=1, max_v=10)
        self.kernel_height = Param("height", 3, min_v=1, max_v=10)

    def execute(self, image):
        cv2.blur(image, (self.kernel_width.get(),
                        self.kernel_height.get()),
                        image)
        return image
예제 #8
0
class LineOrientation(Filter):
    """Port of the old line detection code"""
    def __init__(self):
        Filter.__init__(self)
        self.area_min = Param("Area Min", 300, min_v=1, max_v=100000)
        self.area_max = Param("Area Max", 35000, min_v=1, max_v=100000)

        self._kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3),
                                                 (0, 0))

    def execute(self, image):
        image_threshold = cv2.split(image)[0]
        image_morphology = cv2.morphologyEx(image_threshold,
                                            cv2.MORPH_CLOSE,
                                            self._kernel,
                                            iterations=1)

        contours, _ = cv2.findContours(image_morphology, cv2.RETR_TREE,
                                       cv2.CHAIN_APPROX_SIMPLE)
        lines = self.find_lines(contours, image)
        self.draw_lines(lines, image)

        return image

    def draw_lines(self, lines, image):
        msg = "LineOrientation: x1=%s x2=%s y1=%s y2=%s \n"
        for l, t in lines:
            vx, vy, x, y = l
            point1 = (x - t * vx, y - t * vy)
            point2 = (x + t * vx, y + t * vy)
            to_send = msg % (int(point1[0][0]), int(
                point1[1][0]), int(point2[0][0]), int(point2[1][0]))
            self.notify_output_observers(to_send)
            cv2.line(image, point1, point2, (0, 0, 255), 3, -1)
            cv2.circle(image, (x, y), 5, (0, 255, 0), -1)

        self.notify_output_observers("LineOrientation: \n")

    def find_lines(self, contours, image):
        lines = []
        for contour in contours:
            approx = cv2.approxPolyDP(contour, 0, False)
            area = np.abs(cv2.contourArea(contour))

            if self.area_min.get() < area < self.area_max.get():
                line_values = cv2.fitLine(approx, cv.CV_DIST_L2, 0, 0.01, 0.01)
                rect = cv2.boundingRect(approx)
                t = math.sqrt((rect[2]**2 + rect[3]**2) / 2.0)
                lines.append((line_values, t))
                cv2.drawContours(image, contour, -1, (255, 255, 0))

        return lines
예제 #9
0
class Blur(Filter):
    """Smoothes an image using the normalized box filter"""
    def __init__(self):
        Filter.__init__(self)
        self.kernel_width = Param("width", 3, min_v=1, max_v=10)
        self.kernel_height = Param("height", 3, min_v=1, max_v=10)
        self.kernel_height.set_description("kernel's height")
        self.kernel_width.set_description("kernel's width")

    def execute(self, image):
        cv2.blur(image, (self.kernel_width.get(), self.kernel_height.get()),
                 image)
        return image
예제 #10
0
class Rotate(Filter):
    """Draw a black rectangle on top of the image"""

    def __init__(self):
        Filter.__init__(self)
        self.enable = Param('enable', True)
        self.angle = Param('angle', 0, max_v=3, min_v=0)

    def execute(self, image):
        angle = self.angle.get() * 90
        if self.enable.get():
            return scipy.ndimage.interpolation.rotate(image, angle)
        return image
예제 #11
0
class Perspective(Filter):

    """Wrap perspective"""

    def __init__(self):
        Filter.__init__(self)
        self.topleftx = Param("Top Left X", 0, min_v=0, max_v=640)
        self.toplefty = Param("Top Left TY", 0, min_v=0, max_v=480)
        self.bottomleftx = Param("Bottom Left X", 100, min_v=0, max_v=640)
        self.bottomlefty = Param("Bottom Left Y", 480, min_v=0, max_v=480)
        self.toprightx = Param("Top Right X", 640, min_v=0, max_v=640)
        self.toprighty = Param("Top Right Y", 0, min_v=0, max_v=480)
        self.bottomrightx = Param("Bottom Right X", 540, min_v=0, max_v=640)
        self.bottomrighty = Param("Bottom Right Y", 480, min_v=0, max_v=480)

        self.mmat = None
        self.configure()

    def configure(self):
        c1 = np.array([[self.topleftx.get(), self.toplefty.get()],
                       [self.bottomleftx.get(), self.bottomlefty.get()],
                       [self.toprightx.get(), self.toprighty.get()],
                       [self.bottomrightx.get(), self.bottomrighty.get()]],
                      np.float32)
        c2 = np.array([[0, 0], [0, 480], [640, 0], [640, 480]], np.float32)
        self.mmat = cv2.getPerspectiveTransform(c2, c1)

    def execute(self, image):
        cv2.warpPerspective(image, self.mmat, (640, 480), image)
        return image
class BilateralFilter(Filter):
    """Applies the bilateral filter to an image."""

    def __init__(self):
        Filter.__init__(self)
        self.diameter = Param("Diameter", 10, min_v=0, max_v=255)
        self.sigma_color = Param("Sigma Color", 0, min_v=0, max_v=255)
        self.sigma_space = Param("Sigma Space", 0, min_v=0, max_v=255)

    def execute(self, image):
        return cv2.bilateralFilter(image,
                            self.diameter.get(),
                            self.sigma_color.get(),
                            self.sigma_space.get())
예제 #13
0
class Perspective(Filter):
    """Wrap perspective"""
    def __init__(self):
        Filter.__init__(self)
        self.topleftx = Param("Top Left X", 0, min_v=0, max_v=640)
        self.toplefty = Param("Top Left TY", 0, min_v=0, max_v=480)
        self.bottomleftx = Param("Bottom Left X", 100, min_v=0, max_v=640)
        self.bottomlefty = Param("Bottom Left Y", 480, min_v=0, max_v=480)
        self.toprightx = Param("Top Right X", 640, min_v=0, max_v=640)
        self.toprighty = Param("Top Right Y", 0, min_v=0, max_v=480)
        self.bottomrightx = Param("Bottom Right X", 540, min_v=0, max_v=640)
        self.bottomrighty = Param("Bottom Right Y", 480, min_v=0, max_v=480)

        self.mmat = None
        self.configure()

    def configure(self):
        c1 = np.array(
            [[self.topleftx.get(), self.toplefty.get()],
             [self.bottomleftx.get(),
              self.bottomlefty.get()],
             [self.toprightx.get(), self.toprighty.get()],
             [self.bottomrightx.get(),
              self.bottomrighty.get()]], np.float32)
        c2 = np.array([[0, 0], [0, 480], [640, 0], [640, 480]], np.float32)
        self.mmat = cv2.getPerspectiveTransform(c2, c1)

    def execute(self, image):
        cv2.warpPerspective(image, self.mmat, (640, 480), image)
        return image
예제 #14
0
class Canny(Filter):
    """Apply a canny filter to the image"""
    def __init__(self):
        Filter.__init__(self)
        self.threshold1 = Param("Threshold1", 10, min_v=0, max_v=255)
        self.threshold2 = Param("Threshold2", 100, min_v=0, max_v=255)

    def execute(self, image):
        gray = cv2.cvtColor(image, cv.CV_BGR2GRAY)

        cv2.Canny(gray, self.threshold1.get(), self.threshold2.get(), gray)
        cv2.merge((gray, gray, gray), image)

        return image
예제 #15
0
class ExePy1(Filter):
    """
    Python Example Test #1
    Convert BGR color to another color.
    """

    def __init__(self):
        Filter.__init__(self)

        self.convert_color = Param("Convert choice", 1, min_v=0, max_v=4)
        desc = "0 = original\n1 = BGR TO YUV\n2 = BGR TO HSV\n3 = BGR TO RGB\n\
        4 = BGR TO GRAY"
        self.convert_color.set_description(desc)

    def execute(self, image):
        convert_color = self.convert_color.get()

        if convert_color == 1:
            image = cv2.cvtColor(image, cv2.COLOR_BGR2YUV)
        elif convert_color == 2:
            image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
        elif convert_color == 3:
            image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
        elif convert_color == 4:
            image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        return image
예제 #16
0
class ExePy1(Filter):
    """
    Python Example Test #1
    Convert BGR color to another color.
    """
    def __init__(self):
        Filter.__init__(self)

        self.convert_color = Param("Convert choice", 1, min_v=0, max_v=4)
        desc = "0 = original\n1 = BGR TO YUV\n2 = BGR TO HSV\n3 = BGR TO RGB\n\
        4 = BGR TO GRAY"

        self.convert_color.set_description(desc)

    def execute(self, image):
        convert_color = self.convert_color.get()

        if convert_color == 1:
            image = cv2.cvtColor(image, cv2.COLOR_BGR2YUV)
        elif convert_color == 2:
            image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
        elif convert_color == 3:
            image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
        elif convert_color == 4:
            image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        return image
예제 #17
0
class Canny(Filter):

    """Apply a canny filter to the image"""

    def __init__(self):
        Filter.__init__(self)
        self.threshold1 = Param("Threshold1", 10, min_v=0, max_v=255)
        self.threshold2 = Param("Threshold2", 100, min_v=0, max_v=255)

    def execute(self, image):
        gray = cv2.cvtColor(image, cv.CV_BGR2GRAY)

        cv2.Canny(gray, self.threshold1.get(), self.threshold2.get(), gray)
        cv2.merge((gray, gray, gray), image)

        return image
class RemoveObstacle(Filter):
    """Remove obstacles from an image"""

    def __init__(self):
        Filter.__init__(self)
        self.threshold = Param("Threshold", 12, min_v=0, max_v=255)
        #self.vertical_blur = Param("Vertical Blur", 18, min_v=0, max_v=255)
        #self.horizontal_blur = Param("Horizontal Blur", 3, min_v=0, max_v=255)

    def execute(self, image):
        # copy = cv2.cvtColor(image, cv.CV_BGR2HSV)
        copy = cv2.blur(image, (3, 3))
        h, _, _ = cv2.split(copy)
        h[h > self.threshold.get()] = 0
        contours, _ = cv2.findContours(
                                   h,
                                   cv2.RETR_TREE,
                                   cv2.CHAIN_APPROX_SIMPLE)
        for contour in contours:
            x, y, w, h = cv2.boundingRect(contour)
            miny = y - h
            if miny < 0:
                miny = 0
            maxy = y + h
            if maxy > image.shape[0]:
                maxy = image.shape[0]
            minx = x
            if minx < 0:
                minx = 0
            maxx = x + w
            if maxx > image.shape[1]:
                maxx = image.shape[1]
            image[miny:maxy, minx:maxx] = 0

        return image
예제 #19
0
class GaussianBlur(Filter):
    """Smoothes an image using a Gaussian filter"""
    def __init__(self):
        Filter.__init__(self)
        self.kernel_height = Param("Kernel Height", 3, min_v=1, max_v=256)
        self.kernel_width = Param("Kernel Width", 3, min_v=1, max_v=256)
        self.sigma_x = Param("Sigma X", 3, min_v=1, max_v=256)
        self.sigma_y = Param("Sigma Y", 3, min_v=1, max_v=256)

    def execute(self, image):
        cv2.GaussianBlur(image,
                         (self.kernel_height.get(), self.kernel_width.get()),
                         sigmaX=self.sigma_x.get(),
                         sigmaY=self.sigma_y.get(),
                         dst=image)
        return image
예제 #20
0
class RemoveObstacle(Filter):
    """Remove obstacles from an image"""
    def __init__(self):
        Filter.__init__(self)
        self.threshold = Param("Threshold", 12, min_v=0, max_v=255)
        # self.vertical_blur = Param("Vertical Blur", 18, min_v=0, max_v=255)
        # self.horizontal_blur = Param("Horizontal Blur", 3, min_v=0,
        # max_v=255)

    def execute(self, image):
        # copy = cv2.cvtColor(image, cv.CV_BGR2HSV)
        copy = cv2.blur(image, (3, 3))
        h, _, _ = cv2.split(copy)
        h[h > self.threshold.get()] = 0
        contours, _ = cv2.findContours(h, cv2.RETR_TREE,
                                       cv2.CHAIN_APPROX_SIMPLE)
        for contour in contours:
            x, y, w, h = cv2.boundingRect(contour)
            miny = y - h
            if miny < 0:
                miny = 0
            maxy = y + h
            if maxy > image.shape[0]:
                maxy = image.shape[0]
            minx = x
            if minx < 0:
                minx = 0
            maxx = x + w
            if maxx > image.shape[1]:
                maxx = image.shape[1]
            image[miny:maxy, minx:maxx] = 0

        return image
예제 #21
0
class GaussianBlur(Filter):
    """Smoothes an image using a Gaussian filter"""
    def __init__(self):
        Filter.__init__(self)
        self.kernel_height = Param("Kernel Height", 3, min_v=1, max_v=256)
        self.kernel_width = Param("Kernel Width", 3, min_v=1, max_v=256)
        self.sigma_x = Param("Sigma X", 3, min_v=1, max_v=256)
        self.sigma_y = Param("Sigma Y", 3, min_v=1, max_v=256)

    def execute(self, image):
        cv2.GaussianBlur(image,
                         (self.kernel_height.get(),
                          self.kernel_width.get()),
                     sigmaX=self.sigma_x.get(),
                     sigmaY=self.sigma_y.get(),
                     dst=image)
        return image
예제 #22
0
class Rectangle(Filter):
    """Draw a black rectangle on top of the image"""

    def __init__(self):
        Filter.__init__(self)
        self.x1 = Param('x1', 0, max_v=65535, min_v=0)
        self.y1 = Param('y1', 0, max_v=65535, min_v=0)
        self.x2 = Param('x2', 100, max_v=65535, min_v=0)
        self.y2 = Param('y2', 100, max_v=65535, min_v=0)

    def execute(self, image):
        cv2.rectangle(image,
            (self.x1.get(), self.y1.get()),
            (self.x2.get(), self.y2.get()),
            (0, 0, 0),
            cv2.cv.CV_FILLED)
        return image
예제 #23
0
class RemoveGrass(Filter):

    """Remove grass from an image"""

    def __init__(self):
        Filter.__init__(self)
        self.threshold = Param("Threshold", 100, min_v=0, max_v=255)
        self.technique = Param("Technique", 0, min_v=0, max_v=2)

    def remove_green_from_blue(self, image):
        blue, green, red = cv2.split(image)
        new_blue = blue - green / 2
        black = blue < new_blue
        new_blue[black] = 0
        threshold = new_blue < self.threshold.get()
        blue[threshold] = 0
        green[threshold] = 0
        red[threshold] = 0
        cv2.merge((blue, green, red), image)
        return image

    def add_green_to_blue(self, image):
        blue, green, red = cv2.split(image)
        new_color = green + blue
        white = ((new_color < green) & (new_color < blue))
        new_color[white] = 255
        threshold = new_color > self.threshold.get()
        blue[threshold] = 0
        green[threshold] = 0
        red[threshold] = 0
        cv2.merge((blue, green, red), image)
        return image

    def enhance_grass(self, image):
        blue, green, _ = cv2.split(image)
        image[:, :, 0] = np.subtract(blue, green / 2)
        return image

    def execute(self, image):
        if self.technique.get() == 0:
            return self.add_green_to_blue(image)
        elif self.technique.get() == 1:
            return self.remove_green_from_blue(image)
        elif self.technique.get() == 2:
            return self.enhance_grass(image)
예제 #24
0
class Rectangle(Filter):

    """Draw a black rectangle on top of the image"""

    def __init__(self):
        Filter.__init__(self)
        self.x1 = Param('x1', 0, max_v=65535, min_v=0)
        self.y1 = Param('y1', 0, max_v=65535, min_v=0)
        self.x2 = Param('x2', 100, max_v=65535, min_v=0)
        self.y2 = Param('y2', 100, max_v=65535, min_v=0)

    def execute(self, image):
        cv2.rectangle(image,
                      (self.x1.get(), self.y1.get()),
                      (self.x2.get(), self.y2.get()),
                      (0, 0, 0),
                      cv2.cv.CV_FILLED)
        return image
예제 #25
0
class RemoveGrass(Filter):
    """Remove grass from an image"""
    def __init__(self):
        Filter.__init__(self)
        self.threshold = Param("Threshold", 100, min_v=0, max_v=255)
        self.technique = Param("Technique", 0, min_v=0, max_v=2)

    def remove_green_from_blue(self, image):
        blue, green, red = cv2.split(image)
        new_blue = blue - green / 2
        black = blue < new_blue
        new_blue[black] = 0
        threshold = new_blue < self.threshold.get()
        blue[threshold] = 0
        green[threshold] = 0
        red[threshold] = 0
        cv2.merge((blue, green, red), image)
        return image

    def add_green_to_blue(self, image):
        blue, green, red = cv2.split(image)
        new_color = green + blue
        white = ((new_color < green) & (new_color < blue))
        new_color[white] = 255
        threshold = new_color > self.threshold.get()
        blue[threshold] = 0
        green[threshold] = 0
        red[threshold] = 0
        cv2.merge((blue, green, red), image)
        return image

    def enhance_grass(self, image):
        blue, green, _ = cv2.split(image)
        image[:, :, 0] = np.subtract(blue, green / 2)
        return image

    def execute(self, image):
        if self.technique.get() == 0:
            return self.add_green_to_blue(image)
        elif self.technique.get() == 1:
            return self.remove_green_from_blue(image)
        elif self.technique.get() == 2:
            return self.enhance_grass(image)
예제 #26
0
class FaceDetection(Filter):
    """Detect faces and eyes"""

    def __init__(self):
        Filter.__init__(self)
        self.nb_face = 1
        # linux path
        path_frontal_face = os.path.join('/', 'usr', 'share', 'opencv',
                                         'haarcascades',
                                         'haarcascade_frontalface_alt.xml')
        self.face_detect_name = os.path.join(
            'data', 'facedetect', path_frontal_face)

        self.face_cascade = cv2.CascadeClassifier()
        self.face_cascade.load(self.face_detect_name)

        self.notify_filter = Param("notify", False)

    def execute(self, image):
        gray = cv2.cvtColor(image, cv.CV_BGR2GRAY)
        cv2.equalizeHist(gray, gray)
        faces = self.face_cascade.detectMultiScale(gray,
                                                   1.1,
                                                   2,
                                                   0 | cv.CV_HAAR_SCALE_IMAGE,
                                                   (30, 30))
        for face in faces:
            self.draw_rectangle(image, face, (0, 0, 255))
        return image

    def draw_rectangle(self, image, coord, color):
        x, y, w, h = coord
        miny = y
        if miny < 0:
            miny = 0
        max_y = y + h
        if max_y > image.shape[0]:
            max_y = image.shape[0]
        minx = x
        if minx < 0:
            minx = 0
        max_x = x + w
        if max_x > image.shape[1]:
            max_x = image.shape[1]

        cv2.rectangle(image, (minx, miny), (max_x, max_y), color, 3)

        c_x = (max_x - minx) / 2 + minx
        c_y = (max_y - miny) / 2 + miny
        if self.notify_filter.get():
            self.notify_output_observers("facedetect%d : x=%d, y=%d" %
                                         (self.nb_face, c_x, c_y))
        self.nb_face += 1
        return image[miny:max_y, minx:max_x]
예제 #27
0
class ColorLevel(Filter):
    """Determine the value in % a color will have.
        0% = Nothing
        50% = Half the original value.
        100% = Original
        Example: With 50% Blue and the following pixel (100, 100, 100) give (50, 100, 100)"""

    def __init__(self):
        Filter.__init__(self)
        self.red = Param("red", 100, min_v=0, max_v=255)
        self.green = Param("green", 100, min_v=0, max_v=255)
        self.blue = Param("blue", 100, min_v=0, max_v=255)

    def execute(self, image):
        if self.red != 100:
            image[:, :, 2] *= self.red.get() / 100
        if self.green != 100:
            image[:, :, 1] *= self.green.get() / 100
        if self.blue != 100:
            image[:, :, 0] *= self.blue.get() / 100
        return image
예제 #28
0
class ColorLevel(Filter):
    """Determine the value in % a color will have.
        0% = Nothing
        50% = Half the original value.
        100% = Original
        Example: With 50% Blue and the following pixel
        (100, 100, 100) give (50, 100, 100)"""
    def __init__(self):
        Filter.__init__(self)
        self.red = Param("red", 100, min_v=0, max_v=255)
        self.green = Param("green", 100, min_v=0, max_v=255)
        self.blue = Param("blue", 100, min_v=0, max_v=255)

    def execute(self, image):
        if self.red != 100:
            image[:, :, 2] *= self.red.get() / 100
        if self.green != 100:
            image[:, :, 1] *= self.green.get() / 100
        if self.blue != 100:
            image[:, :, 0] *= self.blue.get() / 100
        return image
예제 #29
0
class SectionFilter(Filter):
    def __init__(self):
        Filter.__init__(self)
        self.kernel_erode_height = Param("Kernel Erode Height",
                                         3,
                                         min_v=1,
                                         max_v=255)
        self.kernel_erode_width = Param("Kernel Dilate Width",
                                        3,
                                        min_v=1,
                                        max_v=255)
        self.kernel_dilate_height = Param("Kernel Erode Height",
                                          5,
                                          min_v=1,
                                          max_v=255)
        self.kernel_dilate_width = Param("Kernel Dilate Width",
                                         5,
                                         min_v=1,
                                         max_v=255)
        self.sections = Param("Sections", 5, min_v=1, max_v=10)
        self.min_area = Param("Minimum Area", 1000, min_v=1, max_v=65535)
        self.configure()

    def configure(self):
        self.kerode = cv2.getStructuringElement(
            cv2.MORPH_CROSS,
            (self.kernel_erode_width.get(), self.kernel_erode_height.get()))
        self.kdilate = cv2.getStructuringElement(
            cv2.MORPH_CROSS,
            (iself.kernel_dilate_width.get(), self.kernel_dilate_height.get()))

    def execute(self, image):

        image = cv2.erode(image, self.kerode)

        rows = image.shape[0]
        section_size = rows / self.sections.get()
        for i in xrange(0, self.sections.get()):
            start = (section_size) * i
            end = (section_size) * (i + 1)
            if end > rows:
                end = rows
            section = image[start:end]

            gray = cv2.split(section)[0]
            contours, _ = cv2.findContours(gray, cv2.RETR_TREE,
                                           cv2.CHAIN_APPROX_SIMPLE)

            section = np.zeros(section.shape, np.uint8)
            for contour in contours:
                area = np.abs(cv2.contourArea(contour))
                if area > self.min_area.get():
                    cv2.drawContours(section, [cv2.convexHull(contour)],
                                     -1, (255, 255, 255),
                                     thickness=-1)
            image[start:end] = section

        image = cv2.dilate(image, self.kdilate)

        return image
예제 #30
0
class Rotate(Filter):
    """
    Rotate picture
    """
    def __init__(self):
        Filter.__init__(self)
        self.angle = Param('angle', 0, max_v=3, min_v=0)

    def execute(self, image):
        angle = self.angle.get() * 90
        if self.enable.get():
            return scipy.ndimage.interpolation.rotate(image, angle)
        return image
예제 #31
0
class TestSeagoat(Filter):

    def __init__(self):
        Filter.__init__(self)
        self.param_str = Param("param_str", "")

    def configure(self):
        # This is called when param is modify
        pass

    def execute(self, image):
        self.notify_output_observers(self.param_str.get())
        return image
예제 #32
0
class Rotate(Filter):
    """
    Rotate picture
    """

    def __init__(self):
        Filter.__init__(self)
        self.angle = Param('angle', 0, max_v=3, min_v=0)

    def execute(self, image):
        angle = self.angle.get() * 90
        if self.enable.get():
            return scipy.ndimage.interpolation.rotate(image, angle)
        return image
예제 #33
0
class ParticleFilter(Filter):

    """Remove small particles from the image.
        The image is first converted to grayscale and is then eroded and
        the remaining blobs are filtered according to the area of the blobs."""

    def __init__(self):
        Filter.__init__(self)
        self.kernel_height = Param("Kernel Height", 10, min_v=1, max_v=256)
        self.kernel_width = Param("Kernel Width", 10, min_v=1, max_v=256)
        self.area_min = Param("Area Min", 3200, min_v=1)
        self.configure()

    def configure(self):
        self._kernel = cv2.getStructuringElement(
            cv2.MORPH_CROSS,
            (self.kernel_width.get(),
             self.kernel_height.get()))

    def execute(self, image):
        cv2.erode(image, self._kernel, image)
        gray = cv2.split(image)[0]
        contours, _ = cv2.findContours(
            gray,
            cv2.RETR_TREE,
            cv2.CHAIN_APPROX_SIMPLE)

        image = np.zeros(image.shape, np.uint8)
        for contour in contours:
            area = np.abs(cv2.contourArea(contour))
            if area > self.area_min.get():
                cv2.drawContours(image,
                                 [contour],
                                 - 1,
                                 (255, 255, 255),
                                 thickness=-1)
        return image
class SectionFilter(Filter):
    """"""

    def __init__(self):
        Filter.__init__(self)
        self.kernel_erode_height = Param("Kernel Erode Height", 3, min_v=1, max_v=255)
        self.kernel_erode_width = Param("Kernel Dilate Width", 3, min_v=1, max_v=255)
        self.kernel_dilate_height = Param("Kernel Erode Height", 5, min_v=1, max_v=255)
        self.kernel_dilate_width = Param("Kernel Dilate Width", 5, min_v=1, max_v=255)
        self.sections = Param("Sections", 5, min_v=1, max_v=10)
        self.min_area = Param("Minimum Area", 1000, min_v=1, max_v=65535)
        self.configure()

    def configure(self):
        self.kerode = cv2.getStructuringElement(
                         cv2.MORPH_CROSS,
                         (self.kernel_erode_width.get(),
                          self.kernel_erode_height.get()))
        self.kdilate = cv2.getStructuringElement(
                         cv2.MORPH_CROSS,
                         (iself.kernel_dilate_width.get(),
                          self.kernel_dilate_height.get()))

    def execute(self, image):

        image = cv2.erode(image, self.kerode)

        rows = image.shape[0]
        section_size = rows / self.sections.get()
        for i in xrange(0, self.sections.get()):
            start = (section_size) * i
            end = (section_size) * (i + 1)
            if end > rows:
                end = rows
            section = image[start : end]

            gray = cv2.split(section)[0]
            contours, _ = cv2.findContours(
                                       gray,
                                       cv2.RETR_TREE,
                                       cv2.CHAIN_APPROX_SIMPLE)

            section = np.zeros(section.shape, np.uint8)
            for contour in contours:
                area = np.abs(cv2.contourArea(contour))
                if area > self.min_area.get():
                    cv2.drawContours(section,
                                 [cv2.convexHull(contour)],
                                 - 1,
                                 (255, 255, 255),
                                 thickness= -1)
            image[start: end] = section


        image = cv2.dilate(image, self.kdilate)

        return image
예제 #35
0
class Psychedelic(Filter):
    """Acid trip"""
    def __init__(self):
        Filter.__init__(self)
        self._images = []
        self.nb_images = Param("Nb Images", 10, min_v=1, max_v=99)

    def execute(self, image):
        self._images.append(image)
        while len(self._images) >= self.nb_images.get():
            del self._images[0]

        try:
            for img in self._images:
                image = np.add(image, img)
        except:
            pass
        return image
예제 #36
0
class Psychedelic(Filter):

    """Acid trip"""

    def __init__(self):
        Filter.__init__(self)
        self._images = []
        self.nb_images = Param("Nb Images", 10, min_v=1, max_v=99)

    def execute(self, image):
        self._images.append(image)
        while len(self._images) >= self.nb_images.get():
            del self._images[0]

        try:
            for img in self._images:
                image = np.add(image, img)
        except:
            pass
        return image
예제 #37
0
class HoughTransform(Filter):

    """Apply a Canny filter to the image then
    finds lines in a binary image using the standard Hough transform"""

    def __init__(self):
        Filter.__init__(self)
        self.canny1 = Param("Canny1", 50, min_v=1, max_v=256)
        self.canny2 = Param("Canny2", 200, min_v=1, max_v=256)
        self.rho = Param("Rho", 1, min_v=1, max_v=256)
        self.theta = Param("Theta", 180, min_v=0, max_v=360)
        self.threshold = Param("Threshold", 100, min_v=1, max_v=256)
        self.line_size = Param("Line Size", 1000, min_v=1, max_v=2000)

    def execute(self, image):
        edges = cv2.Canny(image, self.canny1.get(), self.canny2.get())
        lines = cv2.HoughLines(
            edges,
            self.rho.get(),
            cv.CV_PI / self.theta.get(),
            self.threshold.get())
        if lines is None:
            return image
        rho = lines[:, :, 0]
        theta = lines[:, :, 1]
        a = np.cos(theta)
        b = np.sin(theta)
        x0 = a * rho
        y0 = b * rho

        size = lines.shape[1]
        pt1x = np.round(x0 + self.line_size.get() * -b).astype(np.int)
        pt1y = np.round(y0 + self.line_size.get() * a).astype(np.int)
        pt2x = np.round(x0 - self.line_size.get() * -b).astype(np.int)
        pt2y = np.round(y0 - self.line_size.get() * a).astype(np.int)

        for i in xrange(size):
            cv2.line(image,
                     (pt1x.item(i), pt1y.item(i)),
                     (pt2x.item(i), pt2y.item(i)),
                     (0, 0, 255), 3, -1)
        return image
예제 #38
0
class PygameCam(MediaStreaming):
    """Return images from the webcam."""
    def __init__(self, config):
        # Go into configuration/template_media for more information
        self.config = Configuration()
        self.own_config = config
        super(PygameCam, self).__init__()
        self.media_name = config.name
        self.run = True
        self.video = None
        self.thread_image = None
        pygame.init()
        pygame.camera.init()

        self._create_params()
        self.deserialize(self.config.read_media(self.get_name()))
        self.cam = None
        self._is_opened = True
        self.image = None

    def _create_params(self):
        default_resolution_name = "800x600"
        self.dct_resolution = {
            default_resolution_name: (800, 600),
            "320x240": (320, 240),
            "640x480": (640, 480),
            "1024x768": (1024, 768),
            "1280x960": (1280, 960),
            "1280x1024": (1280, 1024)
        }
        self.param_resolution = Param("resolution",
                                      default_resolution_name,
                                      lst_value=self.dct_resolution.keys())
        self.param_resolution.add_notify(self.reload)

        default_fps_name = "30"
        self.dct_fps = {default_fps_name: 30, "15": 15, "7.5": 7.5}
        self.param_fps = Param("fps",
                               default_fps_name,
                               lst_value=self.dct_fps.keys())
        self.param_fps.add_notify(self.reload)

    def open(self):
        try:
            shape = self.dct_resolution[self.param_resolution.get()]
            fps = self.dct_fps[self.param_fps.get()]
            self.video = pygame.camera.Camera(self.own_config.path, shape)
            self.video.start()
            self.thread_image = True
            thread.start_new_thread(self.update_image, ())
        except BaseException as e:
            log.printerror_stacktrace(
                logger, "Open camera %s: %s" % (self.get_name(), e))
            return False
        # call open when video is ready
        return MediaStreaming.open(self)

    def update_image(self):
        while self.thread_image:
            image_surface = self.video.get_image()
            image = pygame.surfarray.pixels3d(image_surface)
            image = np.rot90(image, 3)
            copy_image = np.zeros(image.shape, np.float32)
            copy_image = cv2.cvtColor(image, cv2.cv.CV_BGR2RGB, copy_image)
            self.image = copy_image

    def next(self):
        return self.image

    def close(self):
        MediaStreaming.close(self)
        self.thread_image = False
        # TODO add semaphore?
        self.video.stop()
        self._is_opened = False
        return True
예제 #39
0
class ImageGenerator(MediaStreaming):
    """Return a generate image."""
    def __init__(self, config):
        # Go into configuration/template_media for more information
        self.config = Configuration()
        self.own_config = config
        super(ImageGenerator, self).__init__()
        self.media_name = config.name
        self.run = True
        self._is_opened = True

        self._create_params()

        self.deserialize(self.config.read_media(self.get_name()))

    def _create_params(self):
        default_width = 800
        self.param_width = Param("width", default_width, min_v=1, max_v=1200)
        self.param_width.add_group("Resolution")
        self.param_width.set_description("Change width resolution.")

        default_height = 600
        self.param_height = Param("height",
                                  default_height,
                                  min_v=1,
                                  max_v=1200)
        self.param_height.add_group("Resolution")
        self.param_height.set_description("Change height resolution.")

        default_fps = 30
        self.param_fps = Param("fps", default_fps, min_v=1, max_v=100)
        self.param_fps.set_description("Change frame per second.")

        self.param_color_r = Param("color_r", 0, min_v=0, max_v=255)
        self.param_color_r.add_group("Color")
        self.param_color_r.set_description("Change red color.")

        self.param_color_g = Param("color_g", 0, min_v=0, max_v=255)
        self.param_color_g.add_group("Color")
        self.param_color_g.set_description("Change green color.")

        self.param_color_b = Param("color_b", 0, min_v=0, max_v=255)
        self.param_color_b.add_group("Color")
        self.param_color_b.set_description("Change blue color.")

        self.param_auto_color = Param("auto-change-color", False)
        self.param_auto_color.set_description(
            "Change the color automatically.")
        self.param_auto_color.add_group("Color")

        self.param_random_green = Param("pooling_green_random", False)
        self.param_random_green.set_description(
            "Active pooling update of green color with random value.")
        self.param_random_green.add_notify(self._active_green_pooling)
        self.param_random_green.add_group("Color")

        self.param_transpose_r_color = Param("Transpose red color", None)
        self.param_transpose_r_color.set_description(
            "Copy the red color on others color.")
        self.param_transpose_r_color.add_notify(self._transpose_red_color)
        self.param_transpose_r_color.add_group("Color")

        self.param_freeze = Param("freeze", False)
        self.param_freeze.set_description("Freeze the stream.")

    def next(self):
        if self.param_freeze.get():
            return

        width = self.param_width.get()
        height = self.param_height.get()
        color_r = self.param_color_r.get()
        color_g = self.param_color_g.get()
        color_b = self.param_color_b.get()

        if self.param_auto_color.get():
            color_r += 1
            if color_r > 255:
                color_r = 0
            color_g += 2
            if color_g > 255:
                color_g = 0
            color_b += 3
            if color_b > 255:
                color_b = 0

            self.param_color_r.set(color_r)
            self.param_color_r.set_lock(True)
            self.param_color_g.set(color_g)
            self.param_color_g.set_lock(True)
            self.param_color_b.set(color_b)
            self.param_color_b.set_lock(True)
        else:
            self.param_color_r.set_lock(False)
            self.param_color_g.set_lock(False)
            self.param_color_b.set_lock(False)

        image = np.zeros((height, width, 3), dtype=np.uint8)

        image[:, :, 0] += color_b
        image[:, :, 1] += color_g
        image[:, :, 2] += color_r
        return image

    def _transpose_red_color(self, param):
        color_r = self.param_color_r.get()
        self.param_color_g.set(color_r)
        self.param_color_b.set(color_r)

    def _active_green_pooling(self, param):
        if param.get():
            self.param_color_g.start_pooling(self._pool_random_green)
        else:
            self.param_color_g.stop_pooling()

    def _pool_random_green(self, param):
        return randrange(255)
예제 #40
0
class PygameCam(MediaStreaming):
    """Return images from the webcam."""

    def __init__(self, config):
        # Go into configuration/template_media for more information
        self.config = Configuration()
        self.own_config = config
        super(PygameCam, self).__init__()
        self.media_name = config.name
        self.run = True
        self.video = None
        self.thread_image = None
        pygame.init()
        pygame.camera.init()

        self._create_params()
        self.deserialize(self.config.read_media(self.get_name()))
        self.cam = None
        self._is_opened = True
        self.image = None

    def _create_params(self):
        default_resolution_name = "800x600"
        self.dct_resolution = {default_resolution_name: (800, 600),
                               "320x240": (320, 240),
                               "640x480": (640, 480),
                               "1024x768": (1024, 768),
                               "1280x960": (1280, 960),
                               "1280x1024": (1280, 1024)}
        self.param_resolution = Param(
            "resolution",
            default_resolution_name,
            lst_value=self.dct_resolution.keys())
        self.param_resolution.add_notify(self.reload)

        default_fps_name = "30"
        self.dct_fps = {default_fps_name: 30, "15": 15, "7.5": 7.5}
        self.param_fps = Param("fps", default_fps_name,
                               lst_value=self.dct_fps.keys())
        self.param_fps.add_notify(self.reload)

    def open(self):
        try:
            shape = self.dct_resolution[
                self.param_resolution.get()]
            fps = self.dct_fps[self.param_fps.get()]
            self.video = pygame.camera.Camera(self.own_config.path, shape)
            self.video.start()
            self.thread_image = True
            thread.start_new_thread(self.update_image, ())
        except BaseException as e:
            log.printerror_stacktrace(
                logger, "Open camera %s: %s" %
                (self.get_name(), e))
            return False
        # call open when video is ready
        return MediaStreaming.open(self)

    def update_image(self):
        while self.thread_image:
            image_surface = self.video.get_image()
            image = pygame.surfarray.pixels3d(image_surface)
            image = np.rot90(image, 3)
            copy_image = np.zeros(image.shape, np.float32)
            copy_image = cv2.cvtColor(image, cv2.cv.CV_BGR2RGB, copy_image)
            self.image = copy_image

    def next(self):
        return self.image

    def close(self):
        MediaStreaming.close(self)
        self.thread_image = False
        # TODO add semaphore?
        self.video.stop()
        self._is_opened = False
        return True
예제 #41
0
class FaceDetection(Filter):
    """Detect faces and eyes"""

    def __init__(self):
        Filter.__init__(self)
        self.nb_face = 1
        eye_xml = 'haarcascade_eye_tree_eyeglasses.xml'
        self.eye_detect_name = os.path.join('/', 'usr', 'share', 'opencv',
                                            'haarcascades', eye_xml)
        self.face_detect_nam = os.path.join('/', 'usr', 'share', 'opencv',
                                            'haarcascades',
                                            'haarcascade_frontalface_alt.xml')
        self.eye_cascade = cv2.CascadeClassifier()
        self.face_cascade = cv2.CascadeClassifier()
        self.eye_cascade.load(self.eye_detect_name)
        self.face_cascade.load(self.face_detect_name)
        self.show_rectangle = Param("show_rectangle", True)

        # To share parameter between filter, create it with :
        self.add_shared_param(Param("width", 3, min_v=1, max_v=10))
        # On the execution, use it like this :
        # param = self.get_shared_params("width")

    def configure(self):
        # This is called when param is modify
        pass

    def execute(self, image):
        gray = cv2.cvtColor(image, cv.CV_BGR2GRAY)
        cv2.equalizeHist(gray, gray)
        faces = self.face_cascade.detectMultiScale(gray,
                                                   1.1,
                                                   2,
                                                   0 | cv.CV_HAAR_SCALE_IMAGE,
                                                   (30, 30)
        )
        for face in faces:
            faceimg = self.draw_rectangle(image, face, (0, 0, 255))
            self.nb_face = 1

        return image

    def draw_rectangle(self, image, coord, color):
        x, y, w, h = coord
        miny = y
        if miny < 0:
            miny = 0
        maxy = y + h
        if maxy > image.shape[0]:
            maxy = image.shape[0]
        minx = x
        if minx < 0:
            minx = 0
        maxx = x + w
        if maxx > image.shape[1]:
            maxx = image.shape[1]

        if self.show_rectangle.get():
            cv2.rectangle(image, (minx, miny), (maxx, maxy), color, 3)

        c_x = (maxx - minx) / 2 + minx
        c_y = (maxy - miny) / 2 + miny
        self.notify_output_observers(
            "facedetect%d : x=%d, y=%d" %
            (self.nb_face, c_x, c_y))
        self.nb_face += 1
        return image[miny:maxy, minx:maxx]
예제 #42
0
class Filter(PoolParam):
    def __init__(self, name=None):
        super(Filter, self).__init__()
        self._output_observers = list()
        self.original_image = None
        self.name = name
        self.dct_global_param = {}
        self.dct_media_param = {}
        self.execution_name = None
        self._publisher = None
        self._publish_key = None

        # add generic param
        self._active_param = Param("_active_filter", True)
        self._active_param.set_description("Enable filter in filterchain.")
        self._active_param.add_group("Generic")

    def serialize(self, is_config=False, is_info=False):
        if is_info:
            return {"name": self.name, "doc": self.__doc__}
        lst_param = super(Filter, self).serialize(is_config=is_config)
        return {
            "filter_name": self.__class__.__name__,
            "lst_param": lst_param
        }

    def deserialize(self, value):
        return super(Filter, self).deserialize(value.get("lst_param"))

    def get_name(self):
        return self.name

    def get_code_name(self):
        key = "-"
        if key in self.name:
            return self.name[:self.name.rfind("-")]
        return self.name

    def set_name(self, name):
        self.name = name

    def get_is_active(self):
        return bool(self._active_param.get())

    def destroy(self):
        # edit me
        # It's called just before to be destroyed
        pass

    def configure(self):
        # edit me
        pass

    def execute(self, image):
        # edit me
        return image

    def set_global_params(self, dct_global_param):
        # complete the list and point on it
        for key, param in self.dct_global_param.items():
            if key in dct_global_param:
                log.print_function(
                    logger.error, "Duplicate key on dct_global_param : %s",
                    key)
                continue
            dct_global_param[key] = param
        self.dct_global_param = dct_global_param
        self.set_global_params_cpp(self.dct_global_param)

    def set_global_params_cpp(self, dct_global_param):
        pass

    def set_media_param(self, dct_media_param):
        self.dct_media_param = dct_media_param

    def set_execution_name(self, execution_name):
        self.execution_name = execution_name

    def get_media_param(self, param_name):
        return self.dct_media_param.get(param_name, None)

    def set_original_image(self, image):
        self.original_image = image

    def get_original_image(self):
        return self.original_image

    def notify_output_observers(self, data):
        for obs in self._output_observers:
            obs(data)

    def get_list_output_observer(self):
        return self._output_observers

    def add_output_observer(self, observer):
        self._output_observers.append(observer)

    def remove_output_observer(self, observer):
        self._output_observers.remove(observer)

    def set_publisher(self, publisher):
        self._publisher = publisher
        # create publisher key
        execution_name = self.execution_name
        filter_name = self.name
        key = keys.create_unique_exec_filter_name(execution_name,
                                                  filter_name)
        self._publish_key = key
        self._publisher.register(key)
        # create callback publisher
        self._cb_publish = self._get_cb_publisher()

    def _add_notification_param(self, param):
        # send from publisher
        if not self._publisher:
            return
        data = {
            "execution": self.execution_name,
            "filter": self.name,
            "param": param.serialize()
        }
        json_data = json.dumps(data)
        self._publisher.publish(keys.get_key_filter_param(), json_data)

    def _get_cb_publisher(self):
        if not self._publisher:
            return
        return self._publisher.get_callback_publish(self._publish_key)

    def get_media(self, name):
        from resource import Resource

        resource = Resource()
        return resource.get_media(name)
예제 #43
0
class Filter(PoolParam):
    def __init__(self, name=None):
        super(Filter, self).__init__()
        self._output_observers = list()
        self.original_image = None
        self.name = name
        self.dct_global_param = {}
        self.dct_media_param = {}
        self.execution_name = None
        self._publisher = None
        self._publish_key = None

        # add generic param
        self._active_param = Param("_active_filter", True)
        self._active_param.set_description("Enable filter in filterchain.")
        self._active_param.add_group("Generic")

    def serialize(self, is_config=False, is_info=False):
        if is_info:
            return {"name": self.name, "doc": self.__doc__}
        lst_param = super(Filter, self).serialize(is_config=is_config)
        return {"filter_name": self.__class__.__name__, "lst_param": lst_param}

    def deserialize(self, value):
        return super(Filter, self).deserialize(value.get("lst_param"))

    def get_name(self):
        return self.name

    def get_code_name(self):
        key = "-"
        if key in self.name:
            return self.name[:self.name.rfind("-")]
        return self.name

    def set_name(self, name):
        self.name = name

    def get_is_active(self):
        return bool(self._active_param.get())

    def destroy(self):
        # edit me
        # It's called just before to be destroyed
        pass

    def configure(self):
        # edit me
        pass

    def execute(self, image):
        # edit me
        return image

    def set_global_params(self, dct_global_param):
        # complete the list and point on it
        for key, param in self.dct_global_param.items():
            if key in dct_global_param:
                log.print_function(logger.error,
                                   "Duplicate key on dct_global_param : %s",
                                   key)
                continue
            dct_global_param[key] = param
        self.dct_global_param = dct_global_param
        self.set_global_params_cpp(self.dct_global_param)

    def set_global_params_cpp(self, dct_global_param):
        pass

    def set_media_param(self, dct_media_param):
        self.dct_media_param = dct_media_param

    def set_execution_name(self, execution_name):
        self.execution_name = execution_name

    def get_media_param(self, param_name):
        return self.dct_media_param.get(param_name, None)

    def set_original_image(self, image):
        self.original_image = image

    def get_original_image(self):
        return self.original_image

    def notify_output_observers(self, data):
        for obs in self._output_observers:
            obs(data)

    def get_list_output_observer(self):
        return self._output_observers

    def add_output_observer(self, observer):
        self._output_observers.append(observer)

    def remove_output_observer(self, observer):
        self._output_observers.remove(observer)

    def set_publisher(self, publisher):
        self._publisher = publisher
        # create publisher key
        execution_name = self.execution_name
        filter_name = self.name
        key = keys.create_unique_exec_filter_name(execution_name, filter_name)
        self._publish_key = key
        self._publisher.register(key)
        # create callback publisher
        self._cb_publish = self._get_cb_publisher()

    def _add_notification_param(self, param):
        # send from publisher
        if not self._publisher:
            return
        data = {
            "execution": self.execution_name,
            "filter": self.name,
            "param": param.serialize()
        }
        json_data = json.dumps(data)
        self._publisher.publish(keys.get_key_filter_param(), json_data)

    def _get_cb_publisher(self):
        if not self._publisher:
            return
        return self._publisher.get_callback_publish(self._publish_key)

    def get_media(self, name):
        from resource import Resource

        resource = Resource()
        return resource.get_media(name)
예제 #44
0
class FaceDetection(Filter):
    """Detect faces and eyes"""
    def __init__(self):
        Filter.__init__(self)
        self.nb_face = 1
        eye_xml = 'haarcascade_eye_tree_eyeglasses.xml'
        self.eye_detect_name = os.path.join('/', 'usr', 'share', 'opencv',
                                            'haarcascades', eye_xml)
        self.face_detect_nam = os.path.join('/', 'usr', 'share', 'opencv',
                                            'haarcascades',
                                            'haarcascade_frontalface_alt.xml')
        self.eye_cascade = cv2.CascadeClassifier()
        self.face_cascade = cv2.CascadeClassifier()
        self.eye_cascade.load(self.eye_detect_name)
        self.face_cascade.load(self.face_detect_name)
        self.show_rectangle = Param("show_rectangle", True)

        # To share parameter between filter, create it with :
        self.add_shared_param(Param("width", 3, min_v=1, max_v=10))
        # On the execution, use it like this :
        # param = self.get_shared_params("width")

    def configure(self):
        # This is called when param is modify
        pass

    def execute(self, image):
        gray = cv2.cvtColor(image, cv.CV_BGR2GRAY)
        cv2.equalizeHist(gray, gray)
        faces = self.face_cascade.detectMultiScale(gray, 1.1, 2,
                                                   0 | cv.CV_HAAR_SCALE_IMAGE,
                                                   (30, 30))
        for face in faces:
            faceimg = self.draw_rectangle(image, face, (0, 0, 255))
            self.nb_face = 1

        return image

    def draw_rectangle(self, image, coord, color):
        x, y, w, h = coord
        miny = y
        if miny < 0:
            miny = 0
        maxy = y + h
        if maxy > image.shape[0]:
            maxy = image.shape[0]
        minx = x
        if minx < 0:
            minx = 0
        maxx = x + w
        if maxx > image.shape[1]:
            maxx = image.shape[1]

        if self.show_rectangle.get():
            cv2.rectangle(image, (minx, miny), (maxx, maxy), color, 3)

        c_x = (maxx - minx) / 2 + minx
        c_y = (maxy - miny) / 2 + miny
        self.notify_output_observers("facedetect%d : x=%d, y=%d" %
                                     (self.nb_face, c_x, c_y))
        self.nb_face += 1
        return image[miny:maxy, minx:maxx]
예제 #45
0
class Webcam(MediaStreaming):
    """Return images from the webcam."""

    def __init__(self, config):
        # Go into configuration/template_media for more information
        self.config = Configuration()
        self.own_config = config
        super(Webcam, self).__init__()
        self.media_name = config.name
        self.run = True
        self.video = None
        video = cv2.VideoCapture(config.no)
        if video.isOpened():
            self._is_opened = True
            video.release()

        self._create_params()

        self.deserialize(self.config.read_media(self.get_name()))

    def _create_params(self):
        self.dct_params = {}

        default_resolution_name = "800x600"
        self.dct_resolution = {default_resolution_name: (800, 600),
                               "320x240": (320, 240),
                               "640x480": (640, 480),
                               "1024x768": (1024, 768),
                               "1280x960": (1280, 960),
                               "1280x1024": (1280, 1024)}
        self.param_resolution = Param(
            "resolution",
            default_resolution_name,
            lst_value=self.dct_resolution.keys())
        self.param_resolution.add_notify(self.reload)

        default_fps_name = "30"
        self.dct_fps = {default_fps_name: 30, "15": 15, "7.5": 7.5}
        self.param_fps = Param("fps", default_fps_name,
                               lst_value=self.dct_fps.keys())
        self.param_fps.add_notify(self.reload)

    def open(self):
        try:
            shape = self.dct_resolution[self.param_resolution.get()]
            fps = self.dct_fps[self.param_fps.get()]

            # TODO check argument video capture
            self.video = cv2.VideoCapture(self.own_config.no)
            self.video.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH, shape[0])
            self.video.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT, shape[1])
            self.video.set(cv2.cv.CV_CAP_PROP_FPS, fps)
        except BaseException as e:
            log.printerror_stacktrace(
                logger, "Open camera %s: %s" %
                (self.get_name(), e))
            return False
        # call open when video is ready
        return MediaStreaming.open(self)

    def next(self):
        run, image = self.video.read()
        if not run:
            raise StopIteration
        return image

    def close(self):
        MediaStreaming.close(self)
        if self.video:
            self.video.release()
        self._is_opened = False
        return True
예제 #46
0
class Webcam(MediaStreaming):
    """Return images from the webcam."""
    def __init__(self, config):
        # Go into configuration/template_media for more information
        self.config = Configuration()
        self.own_config = config
        super(Webcam, self).__init__()
        self.media_name = config.name
        self.run = True
        self.video = None
        video = cv2.VideoCapture(config.no)
        if video.isOpened():
            self._is_opened = True
            video.release()

        self._create_params()

        self.deserialize(self.config.read_media(self.get_name()))

    def _create_params(self):
        self.dct_params = {}

        default_resolution_name = "800x600"
        self.dct_resolution = {
            default_resolution_name: (800, 600),
            "320x240": (320, 240),
            "640x480": (640, 480),
            "1024x768": (1024, 768),
            "1280x960": (1280, 960),
            "1280x1024": (1280, 1024)
        }
        self.param_resolution = Param("resolution",
                                      default_resolution_name,
                                      lst_value=self.dct_resolution.keys())
        self.param_resolution.add_notify(self.reload)

        default_fps_name = "30"
        self.dct_fps = {default_fps_name: 30, "15": 15, "7.5": 7.5}
        self.param_fps = Param("fps",
                               default_fps_name,
                               lst_value=self.dct_fps.keys())
        self.param_fps.add_notify(self.reload)

    def open(self):
        try:
            shape = self.dct_resolution[self.param_resolution.get()]
            fps = self.dct_fps[self.param_fps.get()]

            # TODO check argument video capture
            self.video = cv2.VideoCapture(self.own_config.no)
            self.video.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH, shape[0])
            self.video.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT, shape[1])
            self.video.set(cv2.cv.CV_CAP_PROP_FPS, fps)
        except BaseException as e:
            log.printerror_stacktrace(
                logger, "Open camera %s: %s" % (self.get_name(), e))
            return False
        # call open when video is ready
        return MediaStreaming.open(self)

    def next(self):
        run, image = self.video.read()
        if not run:
            raise StopIteration
        return image

    def close(self):
        MediaStreaming.close(self)
        if self.video:
            self.video.release()
        self._is_opened = False
        return True
예제 #47
0
class IPC(MediaStreaming):
    """
    Return image from IPC socket with ZeroMQ
    This media is a subscriber of ZeroMQ
    """
    key_ipc_name = "ipc name"

    def __init__(self, config):
        # Go into configuration/template_media for more information
        super(IPC, self).__init__()
        self.config = Configuration()
        self.own_config = config
        self.media_name = config.name
        if config.device:
            self.device_name = config.device
        else:
            self.device_name = "/tmp/seagoatvision_media.ipc"
        self._is_opened = True
        self.run = True
        self.video = None

        self.context = zmq.Context()
        self.subscriber = None
        self.message = None

        self._create_params()
        self.deserialize(self.config.read_media(self.get_name()))

    def _create_params(self):
        default_ipc_name = "ipc://%s" % self.device_name
        self.param_ipc_name = Param(self.key_ipc_name, default_ipc_name)
        self.param_ipc_name.add_notify(self.reload)

    def open(self):
        self.subscriber = self.context.socket(zmq.SUB)
        self.subscriber.setsockopt(zmq.SUBSCRIBE, b'')
        device_name = self.param_ipc_name.get()
        logger.info("Open media device %s" % device_name)
        self.subscriber.connect(device_name)
        thread.start_new_thread(self.fill_message, tuple())
        # call open when video is ready
        return MediaStreaming.open(self)

    def next(self):
        if not self.subscriber or not self.message:
            return
        image = None
        message = self.message[:]
        self.message = None
        lst_pixel = list(bytearray(message))
        # the first 2 bytes is width of image
        len_message = len(lst_pixel) - 2
        if len_message:
            width = (lst_pixel[0] << 8) + lst_pixel[1]
            if not width:
                return
            image = np.array(lst_pixel[2:])
            # check if missing pixel and replace by zero
            diff = len_message % width
            if diff:
                image += [0] * (width - diff)
            image = image.reshape((-1, width))
        shape = image.shape
        if len(shape) < 3 or 3 > shape[2]:
            # convert in 3 depth, bgr picture
            image_float = np.array(image, dtype=np.float32)
            vis2 = cv2.cvtColor(image_float, cv2.COLOR_GRAY2BGR)
            image = np.array(vis2, dtype=np.uint8)
        return image

    def close(self):
        MediaStreaming.close(self)
        # TODO need to debug, closing socket create errors and \
        # context.term freeze
        # self.subscriber.close()
        # self.context.term()
        self.subscriber = None
        return True

    def fill_message(self):
        try:
            while self.subscriber:
                self.message = self.subscriber.recv()
        except zmq.ContextTerminated:
            pass
        finally:
            self.message = None
예제 #48
0
class ExePy2(Filter):
    """
    Python Example Test #2
    Example filter to test params.
    Show rectangle on each detected face.
    """

    def __init__(self):
        Filter.__init__(self)
        self.dct_color_choose = {"red": (0, 0, 255), "green": (0, 255, 0),
                                 "blue": (255, 0, 0)}
        self.color_rect = self.dct_color_choose["red"]
        self.i_text_size = 1.0
        # add params
        self.show_output = Param("enable_output", True)
        self.show_output.set_description("Enable to show rectangle.")

        self.color_rectangle = Param("color_rectangle", "red",
                                     lst_value=self.dct_color_choose.keys())
        self.color_rectangle.set_description(
            "Change the RGB color of the rectangle.")
        self.color_rectangle.add_group("rectangle")

        self.show_rectangle = Param("show_rectangle", True)
        self.show_rectangle.set_description(
            "Colorize a rectangle around the face.")
        self.show_rectangle.add_group("rectangle")

        self.border_rec_size = Param("border_rec_size", 3, min_v=1, max_v=9)
        self.border_rec_size.set_description(
            "Change the border size of the rectangle.")
        self.border_rec_size.add_group("rectangle")

        self.show_text = Param("enable_text", True)
        self.show_text.set_description("Show text upper the rectangle.")
        self.show_text.add_group("message")

        self.text_face = Param("text_face", "")
        self.text_face.set_description("The text to write on the rectangle.")
        self.text_face.add_group("message")

        self.text_size = Param("text_size", self.i_text_size, min_v=0.1,
                               max_v=4.9)
        self.text_size.set_description("Change the text size.")
        self.text_size.add_group("message")

        self.nb_face = 1
        # linux path
        path_frontal_face = os.path.join('/', 'usr', 'share', 'opencv',
                                         'haarcascades',
                                         'haarcascade_frontalface_alt.xml')
        self.face_detect_name = os.path.join('data', 'facedetect',
                                             path_frontal_face)
        self.face_cascade = cv2.CascadeClassifier()
        self.face_cascade.load(self.face_detect_name)

    def configure(self):
        self.color_rect = self.dct_color_choose[self.color_rectangle.get()]
        self.i_text_size = self.text_size.get()

    def execute(self, image):
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        cv2.equalizeHist(gray, gray)
        faces = self.face_cascade.detectMultiScale(gray, 1.1, 2,
                                                   0 | cv.CV_HAAR_SCALE_IMAGE,
                                                   (30, 30))
        for face in faces:
            self.draw_rectangle(image, face, self.color_rect, self.i_text_size)
            self.nb_face = 1

        return image

    def draw_rectangle(self, image, coord, color, txt_size):
        x, y, w, h = coord
        min_y = y
        if min_y < 0:
            min_y = 0
        min_face_y = min_y - 10
        if min_face_y < 0:
            min_face_y = 0
        max_y = y + h
        if max_y > image.shape[0]:
            max_y = image.shape[0]
        min_x = x
        if min_x < 0:
            min_x = 0
        max_x = x + w
        if max_x > image.shape[1]:
            max_x = image.shape[1]

        if self.show_rectangle.get():
            cv2.rectangle(image, (min_x, min_y), (max_x, max_y), color,
                          thickness=self.border_rec_size.get())
        if self.show_text.get():
            text = "%s.%s" % (self.nb_face, self.text_face.get())
            cv2.putText(image, text, (min_x, min_face_y),
                        cv2.FONT_HERSHEY_SCRIPT_SIMPLEX, txt_size,
                        color)

        # note: >> 2 == / 2
        c_x = (max_x - min_x) >> 2 + min_x
        c_y = (max_y - min_y) >> 2 + min_y
        if self.show_output.get():
            self.notify_output_observers(
                "face detect no %d : x=%d, y=%d" % (self.nb_face, c_x, c_y))
        self.nb_face += 1
예제 #49
0
class HDR(Filter):

    """High-dynamic-range_imaging with python PIL - works with files"""

    def __init__(self):
        Filter.__init__(self)
        self.case = 'test'
        self.resize = False

        self.strength = Param("strength", 0.0, min_v=0.0, max_v=3.0)
        self.naturalness = Param("naturalness", 10, min_v=0, max_v=10)
        # self.sub_lum = Param("sub_lum", 100, min_v=0, max_v=255)
        # self.shift_x = Param("shift_x", 0, min_v=-800, max_v=800)
        # self.shift_y = Param("shift_y", 0, min_v=-600, max_v=600)

        self.show_image = Param("show_images", 1, min_v=1, max_v=10)
        self.limit_image = Param("limit_image", 4, min_v=1, max_v=10)
        self.debug_show = Param(
            "show_debug",
            "show_normal",
            lst_value=[
                "show_normal",
                "show_sat",
                "show_con"])
        self.show_hdr = Param("show_hdr", False)
        self.index = 0
        self.images = []
        self.imgs = []
        self.first_time = True

    def execute(self, image):
        show_hdr = self.show_hdr.get()
        limit_image = self.limit_image.get()
        len_image = len(self.images)
        if len_image == limit_image:
            self.images[self.index - 1] = image
            self.index += 1
            if self.index > limit_image:
                self.index = 1
        elif len_image < limit_image:
            self.images.append(image)
            self.index += 1
        else:
            self.images.pop()
            if self.index > limit_image:
                self.index = limit_image

        len_image = len(self.images)

        show_no = self.show_image.get()
        show_no = len_image if show_no > len_image else show_no

        if not show_hdr:
            return self.images[show_no - 1]
        nature = self.naturalness.get()
        if nature:
            nature /= 10.0
        return self.get_hdr(self.images, strength=self.strength.get(),
                            naturalness=nature)

    """
    SOURCE: https://sites.google.com/site/bpowah/hdrandpythonpil
    a collection of images to merge into HDR

    blend an arbitrary number of photos into a single HDR image
    or several images with various combinations of HDR parameters

    it is assumed that project folders contain all the images you want to merge
    case = folder name
    cur_dir = folder where the project folders are located
    images are auto-sorted by degree of exposure (image brightness)
    """

    def get_masks(self, imgs, cur_str):
        """
        create a set of masks from a list of images
        (one mask for every adjacent pair of images
        """
        masks = []
        mask_ct = len(imgs) - 1
        imgs = [self.bal(img.convert(mode='L'), cur_str) for img in imgs]
        for i in range(mask_ct):
            blend_fraction = .5  # 1. - (float(i)+.5)/float(mask_ct)
            m = Image.blend(imgs[i], imgs[i + 1], blend_fraction)
            masks.append(m)
        return masks

    def bal(self, im, cur_str):
        """
        adjust the balance of the mask
        (re-distribute the histogram so that there are more
        extreme blacks and whites)
        like increasing the contrast, but without clipping
        and maintains overall average image brightness
        """
        h = im.histogram()
        ln = range(len(h))
        up = [sum(h[0: i]) for i in ln]
        lo = [sum(h[i:-1]) for i in ln]
        ct = sum(h)
        st = int(cur_str * 255.)

        lut = [i + st * up[i] * lo[i] * (up[i] - lo[i]) / ct ** 3 for i in ln]
        for i in ln:
            if lut[i] < 1:
                lut[i] = 1
            if lut[i] > 255:
                lut[i] = 255
        return im.point(lut)

    def merge(self, imgs, cur_str):
        """
        combine a set images into a smaller set by combinding all
        adjacent images
        """
        masks = self.get_masks(imgs, cur_str)
        imx = lambda i: Image.composite(imgs[i], imgs[i + 1], masks[i])
        return [imx(i) for i in range(len(masks))]

    def merge_all(self, imgs, cur_str):
        """
        iteratively merge a set of images until only one remains
        """
        while len(imgs) > 1:
            imgs = self.merge(imgs, cur_str)
        return imgs[0]

    def get_hdr(self, images, strength=0.0, naturalness=1.0):
        """
        process the hdr image(s)
        strength - a float that defines how strong the hdr
                   effect should be
                 - a value of zero will combine images by using a
                   greyscale image average
                 - a value greater than zero will use higher contrast
                   versions of those greyscale images
                 - suggest you a value between 0.0 and 2.0
        naturalness - values between zero and one
                 - zero will be a very high-contrast image
                 - 1.0 will be a very flat image
                 - 0.7 to 0.9 tend to give the best results
        """
        imgs = copy([Image.fromarray(img) for img in images])

        sat_img = self.merge_all(imgs, strength)
        if self.debug_show.get_pos_list() == 1:
            return np.array(sat_img)
        imgs.reverse()

        con_img = self.merge_all(imgs, strength)
        if self.debug_show.get_pos_list() == 2:
            return np.array(con_img)

        """
        combines a saturated image with a contrast image
        and puts them in a dictionary of completed images
        """
        images = Image.blend(con_img, sat_img, naturalness)
        images = np.array(images)
        return images
예제 #50
0
class ImageGenerator(MediaStreaming):
    """Return a generate image."""

    def __init__(self, config):
        # Go into configuration/template_media for more information
        self.config = Configuration()
        self.own_config = config
        super(ImageGenerator, self).__init__()
        self.media_name = config.name
        self.run = True
        self._is_opened = True

        self._create_params()

        self.deserialize(self.config.read_media(self.get_name()))

    def _create_params(self):
        default_width = 800
        self.param_width = Param("width", default_width, min_v=1, max_v=1200)
        self.param_width.add_group("Resolution")
        self.param_width.set_description("Change width resolution.")

        default_height = 600
        self.param_height = Param("height", default_height, min_v=1,
                                  max_v=1200)
        self.param_height.add_group("Resolution")
        self.param_height.set_description("Change height resolution.")

        default_fps = 30
        self.param_fps = Param("fps", default_fps, min_v=1, max_v=100)
        self.param_fps.set_description("Change frame per second.")

        self.param_color_r = Param("color_r", 0, min_v=0, max_v=255)
        self.param_color_r.add_group("Color")
        self.param_color_r.set_description("Change red color.")

        self.param_color_g = Param("color_g", 0, min_v=0, max_v=255)
        self.param_color_g.add_group("Color")
        self.param_color_g.set_description("Change green color.")

        self.param_color_b = Param("color_b", 0, min_v=0, max_v=255)
        self.param_color_b.add_group("Color")
        self.param_color_b.set_description("Change blue color.")

        self.param_auto_color = Param("auto-change-color", False)
        self.param_auto_color.set_description(
            "Change the color automatically.")
        self.param_auto_color.add_group("Color")

        self.param_random_green = Param("pooling_green_random", False)
        self.param_random_green.set_description(
            "Active pooling update of green color with random value.")
        self.param_random_green.add_notify(self._active_green_pooling)
        self.param_random_green.add_group("Color")

        self.param_transpose_r_color = Param("Transpose red color", None)
        self.param_transpose_r_color.set_description(
            "Copy the red color on others color.")
        self.param_transpose_r_color.add_notify(self._transpose_red_color)
        self.param_transpose_r_color.add_group("Color")

        self.param_freeze = Param("freeze", False)
        self.param_freeze.set_description("Freeze the stream.")

    def next(self):
        if self.param_freeze.get():
            return

        width = self.param_width.get()
        height = self.param_height.get()
        color_r = self.param_color_r.get()
        color_g = self.param_color_g.get()
        color_b = self.param_color_b.get()

        if self.param_auto_color.get():
            color_r += 1
            if color_r > 255:
                color_r = 0
            color_g += 2
            if color_g > 255:
                color_g = 0
            color_b += 3
            if color_b > 255:
                color_b = 0

            self.param_color_r.set(color_r)
            self.param_color_r.set_lock(True)
            self.param_color_g.set(color_g)
            self.param_color_g.set_lock(True)
            self.param_color_b.set(color_b)
            self.param_color_b.set_lock(True)
        else:
            self.param_color_r.set_lock(False)
            self.param_color_g.set_lock(False)
            self.param_color_b.set_lock(False)

        image = np.zeros((height, width, 3), dtype=np.uint8)

        image[:, :, 0] += color_b
        image[:, :, 1] += color_g
        image[:, :, 2] += color_r
        return image

    def _transpose_red_color(self, param):
        color_r = self.param_color_r.get()
        self.param_color_g.set(color_r)
        self.param_color_b.set(color_r)

    def _active_green_pooling(self, param):
        if param.get():
            self.param_color_g.start_pooling(self._pool_random_green)
        else:
            self.param_color_g.stop_pooling()

    def _pool_random_green(self, param):
        return randrange(255)