class ParticleFilter:
    """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):
        self.kernel_height = Parameter("Kernel Height", 1, 256, 10)
        self.kernel_width = Parameter("Kernel Width", 1, 256, 10)
        self.area_min = Parameter("Area Min", 1, None, 3200)
        self.configure()

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

    def execute(self, image):
        image = cv2.erode(image, self._kernel)
        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_current_value():
                cv2.drawContours(image, [contour],
                                 -1, (255, 255, 255),
                                 thickness=-1)
        return image
class Morphology:
    
    def __init__(self):
        self.kernel_width = Parameter("Kernel Width",1,256,3)
        self.kernel_height = Parameter("Kernel Height",1,256,3)
        self.anchor_x = Parameter("Anchor X",None,None,-1)
        self.anchor_y = Parameter("Anchor Y",None,None,-1)
        self.iterations = Parameter("Iteration,",1,None,1)
        self.configure()
        
    def configure(self):
        self._kernel = cv2.getStructuringElement(cv2.MORPH_RECT, 
                                (int(self.kernel_width.get_current_value()), 
                                int(self.kernel_height.get_current_value())), 
                                (int(self.anchor_x.get_current_value()), 
                                int(self.anchor_y.get_current_value())))
    
    def execute(self, image):
        image_threshold = cv2.cvtColor(image, cv.CV_BGR2GRAY)
        image_morphology = cv2.morphologyEx(
                image_threshold, 
                cv2.MORPH_CLOSE, 
                self._kernel, 
                iterations=int(self.iterations.get_current_value()))
        image[:, :, 0] = image_morphology
        image[:, :, 1] = image_morphology
        image[:, :, 2] = image_morphology
        
        return image
Exemplo n.º 3
0
class RemoveObstacle:
    """Remove obstacles from an image"""
    def __init__(self):
        self.threshold = Parameter("Threshold", 0, 255, 12)
        self.vertical_blur = Parameter("Vertical Blur", 1, 255, 18)
        self.horizontal_blur = Parameter("Horizontal Blur", 1, 255, 3)

    def execute(self, image):
        copy = cv2.cvtColor(image, cv.CV_RGB2HSV)
        copy = cv2.blur(copy, (int(self.horizontal_blur.get_current_value()),
                               int(self.vertical_blur.get_current_value())))
        h, _, _ = cv2.split(copy)
        h[h > self.threshold.get_current_value()] = 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
class ParticleFilter:
    """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):
        self.kernel_height = Parameter("Kernel Height",1,256,10)
        self.kernel_width = Parameter("Kernel Width",1,256,10)
        self.area_min = Parameter("Area Min",1,None,3200)
        self.configure()
        
    def configure(self):
        self._kernel = cv2.getStructuringElement(
                                                 cv2.MORPH_CROSS, 
                                                 (int(self.kernel_width.get_current_value()), 
                                                  int(self.kernel_height.get_current_value())))
            
    def execute(self, image):
        image = cv2.erode(image, self._kernel)
        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_current_value():
                cv2.drawContours(image, 
                                 [contour], 
                                 -1, 
                                 (255, 255, 255), 
                                 thickness=-1)        
        return image
class Morphology:
    def __init__(self):
        self.kernel_width = Parameter("Kernel Width", 1, 256, 3)
        self.kernel_height = Parameter("Kernel Height", 1, 256, 3)
        self.anchor_x = Parameter("Anchor X", None, None, -1)
        self.anchor_y = Parameter("Anchor Y", None, None, -1)
        self.iterations = Parameter("Iteration,", 1, None, 1)
        self.configure()

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

    def execute(self, image):
        image_threshold = cv2.cvtColor(image, cv.CV_BGR2GRAY)
        image_morphology = cv2.morphologyEx(
            image_threshold,
            cv2.MORPH_CLOSE,
            self._kernel,
            iterations=int(self.iterations.get_current_value()))
        image[:, :, 0] = image_morphology
        image[:, :, 1] = image_morphology
        image[:, :, 2] = image_morphology

        return image
Exemplo n.º 6
0
class RemoveObstacle:
    """Remove obstacles from an image"""
    
    def __init__(self):
        self.threshold = Parameter("Threshold",0,255,12)
        self.vertical_blur = Parameter("Vertical Blur",1,255,18)
        self.horizontal_blur = Parameter("Horizontal Blur",1,255,3)
    
    def execute(self, image):
        copy = cv2.cvtColor(image, cv.CV_RGB2HSV)
        copy = cv2.blur(copy, (int(self.horizontal_blur.get_current_value()), int(self.vertical_blur.get_current_value())))
        h, _, _ = cv2.split(copy)
        h[h > self.threshold.get_current_value()] = 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
Exemplo n.º 7
0
class Blur:
    """Smoothes an image using the normalized box filter"""
    def __init__(self):
        
        self.kernel_width = Parameter("width",1,10,3)
        self.kernel_height = Parameter("height",1,10,3)        
    
    def execute(self, image):
        return cv2.blur(image, (int(self.kernel_width.get_current_value()), 
                                int(self.kernel_height.get_current_value())))
class Blur:
    """Smoothes an image using the normalized box filter"""
    def __init__(self):

        self.kernel_width = Parameter("width", 1, 10, 3)
        self.kernel_height = Parameter("height", 1, 10, 3)

    def execute(self, image):
        return cv2.blur(image, (int(self.kernel_width.get_current_value()),
                                int(self.kernel_height.get_current_value())))
class GaussianBlur:
    """Smoothes an image using a Gaussian filter"""
    def __init__(self):
        self.kernel_height = Parameter("Kernel Height",1,256,3)
        self.kernel_width = Parameter("Kernel Width",1,256,3)
        self.sigma_x = Parameter("Sigma X",1,256,3)
        self.sigma_y = Parameter("Sigma Y",1,256,3)
    
    def execute(self, image):
        return cv2.GaussianBlur(image, (self.kernel_height.get_current_value(), self.kernel_width.get_current_value()), 
                     sigmaX = self.sigma_x.get_current_value(), sigmaY = self.sigma_y.get_current_value())
Exemplo n.º 10
0
class BilateralFilter:
    """Applies the bilateral filter to an image."""
    def __init__(self):
        self.diameter = Parameter("Diameter", 0, 255, 10)
        self.sigma_color = Parameter("Sigma Color", 0, 255, 20)
        self.sigma_space = Parameter("Sigma Space", 0, 255, 5)

    def execute(self, image):
        return cv2.bilateralFilter(image,
                                   int(self.diameter.get_current_value()),
                                   int(self.sigma_color.get_current_value()),
                                   int(self.sigma_space.get_current_value()))
Exemplo n.º 11
0
class ChannelConverter:
    def __init__(self):
        self.channels = Parameter("channels", 1, 3, 3)

    def execute(self, image):
        if image[0][0].size == 1 and self.channels.get_current_value() == 3 or \
        len(image.shape) == 2 and self.channels.get_current_value() == 3:
            return cv2.merge((image, image, image))
        elif image[0][0].size == 3 and self.channels.get_current_value() == 1:
            return cv2.cvtColor(image, cv.CV_BGR2GRAY)
        else:
            return image
Exemplo n.º 12
0
class GaussianBlur:
    """Smoothes an image using a Gaussian filter"""
    def __init__(self):
        self.kernel_height = Parameter("Kernel Height", 1, 256, 3)
        self.kernel_width = Parameter("Kernel Width", 1, 256, 3)
        self.sigma_x = Parameter("Sigma X", 1, 256, 3)
        self.sigma_y = Parameter("Sigma Y", 1, 256, 3)

    def execute(self, image):
        return cv2.GaussianBlur(image, (self.kernel_height.get_current_value(),
                                        self.kernel_width.get_current_value()),
                                sigmaX=self.sigma_x.get_current_value(),
                                sigmaY=self.sigma_y.get_current_value())
class BilateralFilter:
    """Applies the bilateral filter to an image."""
    
    def __init__(self):
        self.diameter = Parameter("Diameter", 0, 255, 10) 
        self.sigma_color = Parameter("Sigma Color", 0, 255, 20)
        self.sigma_space = Parameter("Sigma Space", 0, 255, 5)
        
    def execute(self, image):
        return cv2.bilateralFilter(image,
                            int(self.diameter.get_current_value()),
                            int(self.sigma_color.get_current_value()),
                            int(self.sigma_space.get_current_value()))
class Perspective:
    """Wrap perspective"""
    def __init__(self):
        self.topleftx = Parameter("Top Left X",0,640,0)
        self.toplefty = Parameter("Top Left TY",0,480,0)
        self.bottomleftx = Parameter("Bottom Left X",0,640,100)
        self.bottomlefty = Parameter("Bottom Left Y",0,480,480)
        self.toprightx = Parameter("Top Right X",0,640,640)
        self.toprighty = Parameter("Top Right Y",0,480,0)
        self.bottomrightx = Parameter("Bottom Right X",0,640,540)
        self.bottomrighty = Parameter("Bottom Right Y",0,480,480)
        
        self.mmat = None
        self.configure()
        
    def configure(self):
        c1 = np.array([[self.topleftx.get_current_value(), self.toplefty.get_current_value()], 
                       [self.bottomleftx.get_current_value(), self.bottomlefty.get_current_value()], 
                       [self.toprightx.get_current_value(), self.toprighty.get_current_value()], 
                       [self.bottomrightx.get_current_value(), self.bottomrighty.get_current_value()]], 
                      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):
        return cv2.warpPerspective(image, self.mmat, (640, 480))
class LineOrientation(dataextract.DataExtractor):
    """Port of the old line detection code"""
    
    def __init__(self):
        dataextract.DataExtractor.__init__(self)
        self.area_min = Parameter("Area Min",1,100000,300)
        self.area_max = Parameter("Area Max",1,100000,35000)
    
        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):
        for l, t in lines:
            vx, vy, x, y = l
            point1 = (x - t * vx, y - t * vy)
            point2 = (x + t * vx, y + t * vy)
            toSend = "LineOrientation: x1=" + str(int(point1[0][0])) + " y1=" + str(int(point1[1][0])) + " x2=" + str(int(point2[0][0])) + " y2=" + str(int(point2[1][0])) + " \n"
            self.notify_output_observers(toSend)
            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_current_value() < area < self.area_max.get_current_value():
                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
Exemplo n.º 16
0
class Resize():
    """Resizes an image"""
    
    def __init__(self):
        self.width = Parameter("Width",100,2584,1292)
        self.height = Parameter("Height",100,1468,734)

    def configure(self):
        pass

    def execute(self, image): 
        width = int(self.width.get_current_value())
        height = int(self.height.get_current_value())
        image = cv2.resize(image,(width,height))
        return image
Exemplo n.º 17
0
class Canny:
    """Apply a canny filter to the image"""
    def __init__(self):
        self.threshold1 = Parameter("Threshold1", 0, 255, 10)
        self.threshold2 = Parameter("Threshold2", 0, 255, 100)

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

        gray = cv2.Canny(gray, self.threshold1.get_current_value(),
                         self.threshold2.get_current_value())
        image[:, :, 0] = gray
        image[:, :, 1] = gray
        image[:, :, 2] = gray
        return image
class Rectangle:
    """Draw a black rectangle on top of the image"""
    def __init__(self):
        self.x1 = Parameter('x1', 0, 65535, 0)
        self.y1 = Parameter('y1', 0, 65535, 0)
        self.x2 = Parameter('x2', 0, 65535, 100)
        self.y2 = Parameter('y2', 0, 65535, 100)

    def execute(self, image):
        cv2.rectangle(image, (int(
            self.x1.get_current_value()), int(self.y1.get_current_value())),
                      (int(self.x2.get_current_value()),
                       int(self.y2.get_current_value())), (0, 0, 0),
                      cv2.cv.CV_FILLED)
        return image
Exemplo n.º 19
0
class Canny:
    """Apply a canny filter to the image"""
    
    def __init__(self):
        self.threshold1 = Parameter("Threshold1",0,255,10)
        self.threshold2 = Parameter("Threshold2",0,255,100)
    
    def execute(self, image):
        gray = cv2.cvtColor(image, cv.CV_BGR2GRAY)
        
        gray = cv2.Canny(gray, self.threshold1.get_current_value(), self.threshold2.get_current_value())
        image[:, :, 0] = gray
        image[:, :, 1] = gray
        image[:, :, 2] = gray
        return image
Exemplo n.º 20
0
class RemoveGrass:
    """Remove grass from an image"""
    
    def __init__(self):
        self.threshold = Parameter("Threshold",0,255,100)
        self.technique = Parameter("Technique",0,2,0)
        
    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_current_value()
        blue[threshold] = 0
        green[threshold] = 0
        red[threshold] = 0
        image[:,:,0] = blue
        image[:,:,1] = green 
        image[:,:,2] = red 
        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_current_value()
        blue[threshold] = 0
        green[threshold] = 0
        red[threshold] = 0
        image[:,:,0] = blue
        image[:,:,1] = green
        image[:,:,2] = red
        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_current_value() == 0:
            return self.add_green_to_blue(image)
        elif self.technique.get_current_value() == 1:
            return self.remove_green_from_blue(image)
        elif self.technique.get_current_value() == 2:
            return self.enhance_grass(image)
            
Exemplo n.º 21
0
class Rectangle:
    """Draw a black rectangle on top of the image"""
    
    def __init__(self):
        self.x1 = Parameter('x1', 0, 65535, 0)
        self.y1 = Parameter('y1', 0, 65535, 0)
        self.x2 = Parameter('x2', 0, 65535, 100)
        self.y2 = Parameter('y2', 0, 65535, 100)
    
    def execute(self, image):
        cv2.rectangle(image, 
            (int(self.x1.get_current_value()), int(self.y1.get_current_value())), 
            (int(self.x2.get_current_value()), int(self.y2.get_current_value())), 
            (0, 0, 0),
            cv2.cv.CV_FILLED)
        return image    
class ColorLevel:
    """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):
        self.red = Parameter("red", 0, 255, 100)
        self.green = Parameter("green", 0, 255, 100)
        self.blue = Parameter("blue", 0, 255, 100)

    def execute(self, image):
        if self.red <> 100:
            image[:, :, 2] *= (self.red.get_current_value() / 100)
        #image[:,:, 1] *= ((image[:,:, 0])/2)
        if self.green <> 100:
            image[:, :, 1] *= (self.green.get_current_value() / 100)
        if self.blue <> 100:
            image[:, :, 0] *= (self.blue.get_current_value() / 100)
        return image
class SectionFilter:
    """"""
    
    def __init__(self):
        self.kernel_erode_height = Parameter("Kernel Erode Height", 1, 255, 3)
        self.kernel_erode_width = Parameter("Kernel Erode Width", 1, 255, 3)
        self.kernel_dilate_height = Parameter("Kernel Dilate Height", 1, 255, 5)
        self.kernel_dilate_width = Parameter("Kernel Dilate Width", 1, 255, 5)
        self.sections = Parameter("Sections", 1, 10, 5)
        self.min_area = Parameter("Minimum Area", 1, 65535, 1000)
        self.configure()
        
    def configure(self):
        self.kerode = cv2.getStructuringElement(
                         cv2.MORPH_CROSS, 
                         (int(self.kernel_erode_width.get_current_value()), 
                          int(self.kernel_erode_height.get_current_value())))
        self.kdilate = cv2.getStructuringElement(
                         cv2.MORPH_CROSS, 
                         (int(self.kernel_dilate_width.get_current_value()), 
                          int(self.kernel_dilate_height.get_current_value())))

    def execute(self, image):

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

        rows = image.shape[0]
        section_size = rows / int(self.sections.get_current_value())
        for i in xrange(0, int(self.sections.get_current_value())):
            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_current_value():
                    cv2.drawContours(section, 
                                 [cv2.convexHull(contour)], 
                                 -1, 
                                 (255, 255, 255), 
                                 thickness=-1)        
            image[start: end] = section
        
        
        image = cv2.dilate(image, self.kdilate)
        
        return image
class ColorLevel:
    """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):
        self.red = Parameter("red",0,255,100)
        self.green = Parameter("green",0,255,100)
        self.blue = Parameter("blue",0,255,100)
        
    def execute(self, image):
        if self.red <> 100:
            image[:,:, 2] *= (self.red.get_current_value()/100)
        #image[:,:, 1] *= ((image[:,:, 0])/2)
        if self.green <> 100:
            image[:,:, 1] *= (self.green.get_current_value()/100)
        if self.blue <> 100:
            image[:,:, 0] *= (self.blue.get_current_value()/100) 
        return image
Exemplo n.º 25
0
class HoughTransform:
    """Apply a Canny filter to the image then
    finds lines in a binary image using the standard Hough transform"""
    def __init__(self):
        self.canny1 = Parameter("Canny1",1,256,50)
        self.canny2 = Parameter("Canny2",1,256,200)
        self.rho = Parameter("Rho",1,256,1)
        self.theta = Parameter("Theta",0,360,180)
        self.threshold = Parameter("Threshold",1,256,100)
        self.line_size = Parameter("Line Size",1,2000,1000)
            
    def execute(self, image):
        edges = cv2.Canny(image, self.canny1.get_current_value(), self.canny2.get_current_value())
        lines = cv2.HoughLines(edges, self.rho.get_current_value(), cv.CV_PI / self.theta.get_current_value(), self.threshold.get_current_value())
        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_current_value() * -b).astype(np.int)
        pt1y = np.round(y0 + self.line_size.get_current_value() * a).astype(np.int)
        pt2x = np.round(x0 - self.line_size.get_current_value() * -b).astype(np.int)
        pt2y = np.round(y0 - self.line_size.get_current_value() * 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
Exemplo n.º 26
0
class Perspective:
    """Wrap perspective"""
    def __init__(self):
        #self.topleftx = Parameter("Top Left X",0,640,0)
        #self.toplefty = Parameter("Top Left TY",0,480,0)
        #self.bottomleftx = Parameter("Bottom Left X",0,640,100)
        #self.bottomlefty = Parameter("Bottom Left Y",0,480,480)
        #self.toprightx = Parameter("Top Right X",0,640,640)
        #self.toprighty = Parameter("Top Right Y",0,480,0)
        #self.bottomrightx = Parameter("Bottom Right X",0,640,540)
        #self.bottomrighty = Parameter("Bottom Right Y",0,480,480)

        self.topleftx = Parameter("Top Left X", -1292, 1292, -200)
        self.toplefty = Parameter("Top Left TY", -734, 734, 0)
        self.bottomleftx = Parameter("Bottom Left X", 0, 1292, 202)
        self.bottomlefty = Parameter("Bottom Left Y", 0, 734, 734)
        self.toprightx = Parameter("Top Right X", 0, 1292, 1292)
        self.toprighty = Parameter("Top Right Y", 0, 734, 0)
        self.bottomrightx = Parameter("Bottom Right X", 0, 1292, 1090)
        self.bottomrighty = Parameter("Bottom Right Y", 0, 734, 734)

        self.mmat = None
        self.configure()

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

    def execute(self, image):
        height, width, channels = image.shape
        return cv2.warpPerspective(image, self.mmat, (width, height))
Exemplo n.º 27
0
class SectionFilter:
    """"""
    def __init__(self):
        self.kernel_erode_height = Parameter("Kernel Erode Height", 1, 255, 3)
        self.kernel_erode_width = Parameter("Kernel Erode Width", 1, 255, 3)
        self.kernel_dilate_height = Parameter("Kernel Dilate Height", 1, 255,
                                              5)
        self.kernel_dilate_width = Parameter("Kernel Dilate Width", 1, 255, 5)
        self.sections = Parameter("Sections", 1, 10, 5)
        self.min_area = Parameter("Minimum Area", 1, 65535, 1000)
        self.configure()

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

    def execute(self, image):

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

        rows = image.shape[0]
        section_size = rows / int(self.sections.get_current_value())
        for i in xrange(0, int(self.sections.get_current_value())):
            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_current_value():
                    cv2.drawContours(section, [cv2.convexHull(contour)],
                                     -1, (255, 255, 255),
                                     thickness=-1)
            image[start:end] = section

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

        return image
Exemplo n.º 28
0
class ColorThreshold:
    """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):
        self.shift_hue_plane = Parameter("Shift Hue Plane", True, False, False)
        self.c1min = Parameter("Channel 1 Min", 1, 256, 20.0)
        self.c1max = Parameter("Channel 1 Max", 1, 256, 256.0)
        self.c2min = Parameter("Channel 2 Min", 1, 256, 20.0)
        self.c2max = Parameter("Channel 2 Max", 1, 256, 256.0)
        self.c3min = Parameter("Channel 3 Min", 1, 256, 20.0)
        self.c3max = Parameter("Channel 3 Max", 1, 256, 256.0)
        #self._barray = None
        #self._garray = None
        #self._rarray = None
        #self.configure()

    def configure(self):
        pass

    #    self._barray = np.array(
    #                    [self.get_binary_value(self.bluemin.get_current_value(), self.bluemax.get_current_value(), x)
    #                        for x in range(0, 256)], dtype=np.float32)
    #    self._garray = np.array(
    #                    [self.get_binary_value(self.greenmin.get_current_value(), self.greenmax.get_current_value(), x)
    #                        for x in range(0, 256)], dtype=np.float32)
    #    self._rarray = np.array(
    #                    [self.get_binary_value(self.redmin.get_current_value(), self.redmax.get_current_value(), x)
    #                        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]])

        lower = np.zeros((1, 3), dtype=np.uint8)
        upper = np.zeros((1, 3), dtype=np.uint8)
        lower[0] = (self.c1min.get_current_value(),
                    self.c2min.get_current_value(),
                    self.c3min.get_current_value())
        upper[0] = (self.c1max.get_current_value(),
                    self.c2max.get_current_value(),
                    self.c3max.get_current_value())

        result = cv2.inRange(image, lower, upper)
        return cv2.cvtColor(result, cv.CV_GRAY2BGR)

    def get_binary_value(self, mini, maxi, val):
        if mini <= val <= maxi:
            return 1.0
        else:
            return 0.0
class Psychedelic:
    """Acid trip"""
    def __init__(self):
        self._images = []
        self.nb_images = Parameter("Nb Images", 1, 99, 10)

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

        try:
            for img in self._images:
                image = np.add(image, img)
        except:
            pass
        return image
class Psychedelic:
    """Acid trip"""
    
    def __init__(self):
        self._images = []
        self.nb_images = Parameter("Nb Images", 1, 99, 10)
        
    def execute(self, image):
        self._images.append(image)
        while len(self._images) >= self.nb_images.get_current_value():
            del self._images[0]
            
        try:
            for img in self._images:
                image = np.add(image, img)
        except:
            pass
        return image
Exemplo n.º 31
0
class ColorThreshold:
    """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):
        self.shift_hue_plane = Parameter("Shift Hue Plane",True,False,False)
        self.c1min = Parameter("Channel 1 Min",1,256,20.0)
        self.c1max = Parameter("Channel 1 Max",1,256,256.0)
        self.c2min = Parameter("Channel 2 Min",1,256,20.0)
        self.c2max = Parameter("Channel 2 Max",1,256,256.0)
        self.c3min = Parameter("Channel 3 Min",1,256,20.0)
        self.c3max = Parameter("Channel 3 Max",1,256,256.0)
        #self._barray = None
        #self._garray = None
        #self._rarray = None
        #self.configure()

    def configure(self):
        pass
    #    self._barray = np.array(
    #                    [self.get_binary_value(self.bluemin.get_current_value(), self.bluemax.get_current_value(), x)
    #                        for x in range(0, 256)], dtype=np.float32)
    #    self._garray = np.array(
    #                    [self.get_binary_value(self.greenmin.get_current_value(), self.greenmax.get_current_value(), x)
    #                        for x in range(0, 256)], dtype=np.float32)
    #    self._rarray = np.array(
    #                    [self.get_binary_value(self.redmin.get_current_value(), self.redmax.get_current_value(), x) 
    #                        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]])

        lower = np.zeros((1,3), dtype=np.uint8)
        upper = np.zeros((1,3), dtype=np.uint8)
        lower[0] = (self.c1min.get_current_value(), self.c2min.get_current_value(), self.c3min.get_current_value())
        upper[0] = (self.c1max.get_current_value(), self.c2max.get_current_value(), self.c3max.get_current_value())

        result = cv2.inRange(image, lower, upper)
        return cv2.cvtColor(result, cv.CV_GRAY2BGR)

    def get_binary_value(self, mini, maxi, val):
        if mini <= val <= maxi:
            return 1.0
        else:
            return 0.0
class ConvexHull(dataextract.DataExtractor):
    def __init__(self):
        dataextract.DataExtractor.__init__(self)
        self.area_min = Parameter("Area Min", 1, 100000, 300)
        self.area_max = Parameter("Area Max", 1, 100000, 35000)

    def execute(self, image):
        gray = cv2.cvtColor(image, cv.CV_BGR2GRAY)
        cnt, _ = cv2.findContours(gray, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
        image *= 0
        for c in cnt:
            hull = cv2.convexHull(c)
            approx = cv2.approxPolyDP(c, 0, False)
            area = np.abs(cv2.contourArea(c))

            if self.area_min.get_current_value() < area:
                cv2.drawContours(image, [hull], -1, (255, 255, 255), -1)
                #self.notify_output_observers(str(area) + "\n")

        return image
Exemplo n.º 33
0
class ConvexHull(dataextract.DataExtractor):
        
    def __init__(self):
        dataextract.DataExtractor.__init__(self)
        self.area_min = Parameter("Area Min", 1, 100000, 300)
        self.area_max = Parameter("Area Max", 1, 100000, 35000)
    
    def execute(self, image):
        gray = cv2.cvtColor(image, cv.CV_BGR2GRAY)
        cnt, _ = cv2.findContours(gray, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
        image *= 0
        for c in cnt:
            hull = cv2.convexHull(c)
            approx = cv2.approxPolyDP(c, 0, False)
            area = np.abs(cv2.contourArea(c))
            
            if self.area_min.get_current_value() < area:
                cv2.drawContours(image, [hull],-1, (255,255,255), -1)
                #self.notify_output_observers(str(area) + "\n")
                
        return image
class HoughTransform:
    """Apply a Canny filter to the image then
    finds lines in a binary image using the standard Hough transform"""

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

    def execute(self, image):
        edges = cv2.Canny(image, self.canny1.get_current_value(), self.canny2.get_current_value())
        lines = cv2.HoughLines(
            edges,
            self.rho.get_current_value(),
            cv.CV_PI / self.theta.get_current_value(),
            self.threshold.get_current_value(),
        )
        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_current_value() * -b).astype(np.int)
        pt1y = np.round(y0 + self.line_size.get_current_value() * a).astype(np.int)
        pt2x = np.round(x0 - self.line_size.get_current_value() * -b).astype(np.int)
        pt2y = np.round(y0 - self.line_size.get_current_value() * 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
class ColorThreshold:
    """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):
        self.shift_hue_plane = Parameter("Shift Hue Plane",True,False,False)
        self.bluemin = Parameter("Blue Min",1,256,20.0)
        self.bluemax = Parameter("Blue Max",1,256,256.0)
        self.greenmin = Parameter("Green Min",1,256,20.0)
        self.greenmax = Parameter("Green Max",1,256,256.0)
        self.redmin = Parameter("Red Min",1,256,20.0)
        self.redmax = Parameter("Red Max",1,256,256.0)
        self._barray = None
        self._garray = None
        self._rarray = None
        self.configure()
    
    def configure(self):
        self._barray = np.array(
                        [self.get_binary_value(self.bluemin.get_current_value(), self.bluemax.get_current_value(), x) 
                            for x in range(0, 256)], dtype=np.float32)
        self._garray = np.array(
                        [self.get_binary_value(self.greenmin.get_current_value(), self.greenmax.get_current_value(), x) 
                            for x in range(0, 256)], dtype=np.float32)
        self._rarray = np.array(
                        [self.get_binary_value(self.redmin.get_current_value(), self.redmax.get_current_value(), x) 
                            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

    def get_binary_value(self, mini, maxi, val):
        if mini <= val <= maxi:
            return 1.0
        else:
            return 0.0
Exemplo n.º 36
0
class LineOrientation(dataextract.DataExtractor):
    """Port of the old line detection code"""

    filter_name = "LineOrientation:"

    def __init__(self):
        dataextract.DataExtractor.__init__(self)
        self.area_min = Parameter("Area Min", 1, 100000, 300)
        self.area_max = Parameter("Area Max", 1, 100000, 35000)

        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)
        self.send_lines(lines)

        return image

    def draw_lines(self, lines, image):
        for l in lines:
            x1, y1, x2, y2 = l
            point1 = (x1, y1)
            point2 = (x2, y2)
            cv2.line(image, point1, point2, (0, 0, 255), 3, -1)
            #cv2.circle(image, (x, y), 5, (0, 255, 0), -1)

    def send_lines(self, lines):
        toSend = ""
        for l in lines:
            x1, y1, x2, y2 = l
            toSend += self.filter_name + " x1=" + str(
                int(x1) * 2) + " y1=" + str(int(y1) * 2) + " x2=" + str(
                    int(x2) * 2) + " y2=" + str(int(y2) * 2) + " \n"

        toSend += "=\n"
        self.notify_output_observers(toSend)

    def is_point_intersecting(self, point, image):
        x, y = point
        if x >= 0 and y >= 0 and x < image.shape[1] and y < image.shape[0]:
            if not image[y][x][0] == 0:
                return True
        return False

    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_current_value(
            ) < area < self.area_max.get_current_value():
                line_values = cv2.fitLine(approx, cv.CV_DIST_L2, 0, 0.01, 0.01)
                rect = cv2.boundingRect(approx)
                t0 = t1 = math.sqrt((rect[2]**2 + rect[3]**2) / 2.0)

                vx, vy, x, y = line_values

                # CHEAP FIX
                limit1Found = limit2Found = False

                while not (limit1Found and limit2Found) and t0 > 0 and t1 > 0:
                    if not limit1Found:
                        if not self.is_point_intersecting(
                            (int(x - t0 * vx), int(y - t0 * vy)), image):
                            t0 = t0 - 20
                        else:
                            limit1Found = True

                    if not limit2Found:
                        if not self.is_point_intersecting(
                            (int(x + t1 * vx), int(y + t1 * vy)), image):
                            t1 = t1 - 20
                        else:
                            limit2Found = True

                line = (x - t0 * vx, y - t0 * vy, x + t1 * vx, y + t1 * vy)

                lines.append(line)
                cv2.drawContours(image, contour, -1, (255, 255, 0))

        return lines
Exemplo n.º 37
0
class LaserObstacleFilter:
    def __init__(self):
        self.bottomy = Parameter("Bottom Y", 0,734,73)
        self.realy = Parameter("Real bottom y", 0, 654, 33)
        self.resolution = Parameter("Resolution", 0, 500, 20)
        self.scan = None
        self.size = (0, 0)
        self.res = (0, 0)
        self.trans = [0, 0]

        rospy.Subscriber('/scan_5m', LaserScan, self.handle_cloud)

    def execute(self, image):
        height, width = image.shape[:2]
        self.trans[0] = width / 2
        self.trans[1] = int(self.bottomy.get_current_value())
        self.res = width / 5.0, height / 5.0

        if self.scan is None:
            return image

        angles = np.arange(self.scan.angle_min, self.scan.angle_max, self.scan.angle_increment)

        current = []
        obstacles = []
        trans_real = np.array([self.trans[0], self.realy.get_current_value()])

        for i in range(len(angles)):
            angle = angles[i]
            r = self.scan.ranges[i]

            if isnan(r):
                if len(current) > 0:
                    obstacles.append(current)
                    current = []
            else:
                current.append(i)

        if len(current) > 0:
            obstacles.append(current)
            
        for obstacle in obstacles:
            a, b = obstacle[0], obstacle[-1]

            # filter out obstacles that are ~5 degrees wide
            
            if isnan(self.scan.ranges[a]) or isnan(self.scan.ranges[b]): continue
            if abs(angles[a] - angles[b]) < 0.0872664626: continue


            laser_height = 0.44
            obstacle_height = 1
            ang = 0.17
            
            dn_d = 0.08
            dn_1 = sin(angles[a] + 2 * pi) * dn_d
            dn_2 = sin(angles[a] + 2 * pi) * dn_d

            p1 = np.array([cos(angles[a] - ang + dn_1) * self.scan.ranges[a], sin(angles[a] - ang + dn_1) * self.scan.ranges[a]])
            p2 = np.array([cos(angles[b] + ang + dn_2) * self.scan.ranges[b], sin(angles[b] + ang + dn_2) * self.scan.ranges[b]])
            
            if np.any(np.isnan(p1)): continue
            if np.any(np.isnan(p2)): continue

            p1_m = self.meters_to_pixels(*p1)
            p2_m = self.meters_to_pixels(*p2)


            cv2.rectangle(image, (self.trans[0], self.trans[1]), (self.trans[0] + 10, self.trans[1] + 10), (0, 0, 255))
            cv2.rectangle(image, (int(trans_real[0]), int(trans_real[1])), (int(trans_real[0] + 10), int(trans_real[1] + 10)), (0, 255, 255))


            d1 = p1_m - trans_real
            d2 = p2_m - trans_real

            k = 5
            m1 = d1 * k + p1_m
            m2 = d2 * k + p2_m

            cv2.fillPoly(image, [np.array([
                p1_m.astype(int),
                m1.astype(int),
                m2.astype(int),
                p2_m.astype(int)
            ])], (0, 0, 0))

            for obs in obstacle:
                angle, r = angles[obs], self.scan.ranges[obs]

                if isnan(r): continue

                x, y = cos(angle) * r, sin(angle) * r
                px, py = self.meters_to_pixels(x, y)

                cv2.rectangle(image, (px, py), (px + 5, py + 5), (0, 255, 0))
                
                
            # cv2.line(image, tuple(self.meters_to_pixels(*p1)), tuple(self.meters_to_pixels(*p2)), (0, 0, 255))

            # cv2.line(image, tuple(p1_m.astype(int)), tuple(m1.astype(int)), (0, 255, 0))
            # cv2.line(image, tuple(p2_m.astype(int)), tuple(m2.astype(int)), (0, 255, 0))

            # cv2.line(image, tuple(trans_real.astype(int)), tuple(self.meters_to_pixels(*p1)), (0, 255, 0))
            # cv2.line(image, tuple(trans_real.astype(int)), tuple(self.meters_to_pixels(*p2)), (0, 255, 0))
            
            # cv2.line(image, tuple(map(int, self.trans)), tuple(self.meters_to_pixels(*p1).astype(int)), (0, 255, 0))

            # cv2.rectangle(image, p1_pix, (p2_pix[0], p2_pix[1] + 5), (255, 0, 0), -1)


#             points = [
#                 self.meters_to_pixels(p1[0], p1[1] - laser_height),
#                 self.meters_to_pixels(p2[0], p2[1] - laser_height),
#                 self.meters_to_pixels(p2[0], p2[1] + obstacle_height),
#                 self.meters_to_pixels(p1[0], p1[1] + obstacle_height),
#             ]


   
        return image
        
    def handle_cloud(self, msg):
        self.scan = msg

    def meters_to_pixels(self, x, y):
        # 1.255 distance du robot du tf /image
        return np.array([int(self.trans[0] - y * self.res[0]), int(self.trans[1] - x * self.res[1] + 1.255 * self.res[1])])
Exemplo n.º 38
0
class LineOrientation(dataextract.DataExtractor):
    """Port of the old line detection code"""
    
    filter_name = "LineOrientation:"
    
    def __init__(self):
        dataextract.DataExtractor.__init__(self)
        self.area_min = Parameter("Area Min",1,100000,300)
        self.area_max = Parameter("Area Max",1,100000,35000)
    
        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)
        self.send_lines(lines)
        
        return image
    
    def draw_lines(self, lines, image):
        for l in lines:
            x1, y1, x2, y2 = l
            point1 = (x1,y1)
            point2 = (x2,y2)
            cv2.line(image, point1, point2, (0, 0, 255), 3, -1)
            #cv2.circle(image, (x, y), 5, (0, 255, 0), -1)
            
    def send_lines(self, lines):
        toSend = ""
        for l in lines:
            x1, y1, x2, y2 = l
            toSend += self.filter_name + " x1=" + str(int(x1)*2) + " y1=" + str(int(y1)*2) + " x2=" + str(int(x2)*2) + " y2=" + str(int(y2)*2) + " \n"
            
        toSend += "=\n"
        self.notify_output_observers(toSend)
    
    def is_point_intersecting (self, point, image):
        x,y = point
        if x >= 0 and y >= 0 and x < image.shape[1] and y < image.shape[0]:
            if not image[y][x][0] == 0:
                return True
        return False
                       
    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_current_value() < area < self.area_max.get_current_value():
                line_values = cv2.fitLine(approx, cv.CV_DIST_L2, 0, 0.01, 0.01)
                rect = cv2.boundingRect(approx)
                t0 = t1 = math.sqrt((rect[2]**2 + rect[3]**2) / 2.0)
                
                vx,vy,x,y = line_values

                # CHEAP FIX
                limit1Found = limit2Found = False

                while not (limit1Found and limit2Found) and t0 > 0 and t1 > 0:
                    if not limit1Found:
                        if not self.is_point_intersecting((int(x - t0 * vx),int( y - t0 * vy)), image):
                            t0 = t0 - 20
                        else:
                            limit1Found = True
                            
                    if not limit2Found:
                        if not self.is_point_intersecting((int(x + t1 * vx),int( y + t1 * vy)), image):
                            t1 = t1 - 20 
                        else:
                            limit2Found = True     
                
                line = (x - t0 * vx, y - t0 * vy, x + t1 * vx, y + t1 * vy )
                
                lines.append(line)
                cv2.drawContours(image, contour, -1, (255, 255, 0))

        return lines
Exemplo n.º 39
0
class Lines(dataextract.DataExtractor):
    """New detection code"""
    
    filter_name = "Lines:"
    
    def __init__(self):
        dataextract.DataExtractor.__init__(self)
        self.area_min = Parameter("Area Min",1,100000,300)
        self.area_max = Parameter("Area Max",1,100000,35000)
    
        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)
        self.send_lines(lines)
        
        return image
    
    def draw_lines(self, lines, image):
        for l in lines:
            x1, y1, x2, y2 = l
            point1 = (x1,y1)
            point2 = (x2,y2)
            cv2.line(image, point1, point2, (0, 0, 255), 3, -1)
            #cv2.circle(image, (x, y), 5, (0, 255, 0), -1)
            
    def send_lines(self, lines):
        toSend = ""
        for l in lines:
            x1, y1, x2, y2 = l
            toSend += self.filter_name + " x1=" + str(int(x1) * 2) + " y1=" + str(int(y1) * 2) + " x2=" + str(int(x2) * 2) + " y2=" + str(int(y2) * 2) + " \n"
            
        toSend += "=\n"
        self.notify_output_observers(toSend)
    
    def is_point_intersecting (self, point, image):
        x,y = point
        if x >= 0 and y >= 0 and x < image.shape[1] and y < image.shape[0]:
            if not image[y][x][0] == 0:
                return True
        return False
                       
    def find_lines(self, contours, image):
        lines = []
        for contour in contours:
            approx = cv2.approxPolyDP(contour, 2, False)       
                
            area = np.abs(cv2.contourArea(contour))
            
            if self.area_min.get_current_value() < area < self.area_max.get_current_value():
                for a in approx:
                    x = a[0,0]
                    y = a[0,1]
                    cv2.circle(image, (x, y), 5, (255, 0, 0), -1)
                
                count = approx.shape[0]
                        
                points = []            
                for i in range(0, count / 2):
                    p1 = approx[i]
                    p2 = approx[-i]                
                    x = (p1[0,0] + p2[0,0]) / 2
                    y = (p1[0,1] + p2[0,1]) / 2
                    cv2.circle(image, (x, y), 5, (0, 255, 0), -1)                
                    points.append((x,y))
                
                avgPoints = []
                ptsByAvg = 5
                
                i = 0
                while i < len(points):
                    if len(points) - i < ptsByAvg:
                        ptsByAvg = len(points) - i
                    
                    i += 1
                
                if len(points) <= ptsByAvg:
                    avgPoints = points
                else:
                    nbAvg = len(points) / ptsByAvg
                    avgPoints.append(points[0])
                    for i in range(0,ptsByAvg):  
                        avgX = avgY = 0
                        for j in range(nbAvg*i, nbAvg*(i+1)):
                            avgX += points[j][0]
                            avgY += points[j][1]
                        avgX /= nbAvg
                        avgY /= nbAvg
                        avgPoints.append((avgX,avgY)) 
                    avgPoints.append(points[-1])                      
   
                for i in range(0,len(avgPoints)-1):
                    lines.append((avgPoints[i][0], avgPoints[i][1], avgPoints[i+1][0], avgPoints[i+1][1]))   

                cv2.drawContours(image, contour, -1, (255, 255, 0))

        return lines