예제 #1
0
    def _find_power_plug_thing(self):
        """ Find the power plug at the solar array box """
        """ This uses color to determine if we have a choke """
        lower = np.array([100, 40, 0], dtype="uint8")
        upper = np.array([255, 255, 20], dtype="uint8")
        mask = cv2.inRange(self.img, lower, upper)

        blurred = cv2.GaussianBlur(mask, (5, 5), 0)
        thresh = cv2.threshold(blurred, 60, 255, cv2.THRESH_BINARY)[1]

        contours = cv2.findContours(thresh, cv2.RETR_EXTERNAL,
                                    cv2.CHAIN_APPROX_SIMPLE)
        contours = contours[0] if is_cv2() else contours[1]

        sorted_contours = sorted(
            contours,
            cmp=lambda a, b: int(cv2.contourArea(b)) - int(cv2.contourArea(a)))

        if len(sorted_contours) > 0:
            plug = self._find_a_thing(sorted_contours[0], 0, 0.06, 0, 0.06,
                                      99.0)

            if plug is not None:
                plug.set_power_plug()
                self.things.append(plug)
                self.power_plug = plug

                if self.debug:
                    debug_img = self.img.copy()
                    for c in sorted_contours:
                        cv2.drawContours(debug_img, [c], -1, (0, 255, 0), 2)
                    cv2.imshow("plug picture", debug_img)
                    cv2.setMouseCallback("plug picture", self.handle_mouse)
                    cv2.waitKey(0)
                    cv2.destroyAllWindows()
예제 #2
0
    def is_detector(self, img):
        """ This uses color to determine if we have a detector, and if so, returns where
            the big screen and smaller screen is in the subimage """
        lower = np.array([190, 190, 0], dtype="uint8")
        upper = np.array([255, 255, 100], dtype="uint8")
        mask = cv2.inRange(img, lower, upper)

        contours = cv2.findContours(mask, cv2.RETR_EXTERNAL,
                                    cv2.CHAIN_APPROX_SIMPLE)
        contours = contours[0] if is_cv2() else contours[1]
        if len(contours) == 0:
            return None, False

        sorted_contours = sorted(
            contours,
            cmp=lambda a, b: int(cv2.contourArea(b)) - int(cv2.contourArea(a)))
        center, radius = cv2.minEnclosingCircle(sorted_contours[0])
        up = True
        if len(contours) > 1:
            center2, radius = cv2.minEnclosingCircle(sorted_contours[1])
            if center2[1] < center[1]:
                up = False

        if self.debug:
            debug_img = img.copy()
            cv2.drawContours(debug_img, [sorted_contours[0]], -1, (0, 255, 0),
                             2)
            cv2.imshow("cont", debug_img)
            cv2.waitKey(0)
            cv2.destroyAllWindows()

        return center, up
예제 #3
0
    def is_repair_tool(self, img):
        """ This uses color to determine if we have a repair tool, and if so, returns where
            the button is located within the provided subimage """
        lower = np.array([190, 0, 0], dtype="uint8")
        upper = np.array([255, 125, 100], dtype="uint8")
        mask = cv2.inRange(img, lower, upper)

        contours = cv2.findContours(mask, cv2.RETR_EXTERNAL,
                                    cv2.CHAIN_APPROX_SIMPLE)
        contours = contours[0] if is_cv2() else contours[1]
        if len(contours) == 0:
            return None, False

        sorted_contours = sorted(
            contours,
            cmp=lambda a, b: int(cv2.contourArea(b)) - int(cv2.contourArea(a)))
        center, radius = cv2.minEnclosingCircle(sorted_contours[0])
        up = True
        if center[1] > (img.shape[0] / 2):
            up = False

        if self.debug:
            debug_img = img.copy()
            cv2.drawContours(debug_img, [sorted_contours[0]], -1, (0, 255, 0),
                             2)
            cv2.imshow("cont", debug_img)
            cv2.waitKey(0)
            cv2.destroyAllWindows()

        return center, up
예제 #4
0
    def _find_a_thing(self,
                      c,
                      min_height,
                      max_height,
                      min_width,
                      max_width,
                      max_distance,
                      debug_img=None):
        rect = cv2.minAreaRect(c)
        box = cv2.cv.BoxPoints(rect) if is_cv2() else cv2.boxPoints(rect)

        top, bottom, left, right, center = self.find_dimensions(
            np.int0(np.array(box)))

        if top is None or left is None or center is None:
            return None

        vertical = self.find_distance(top, bottom)
        horizontal = self.find_distance(left, right)
        away = self.find_distance(center, None)

        if vertical > horizontal:
            height = vertical
            width = horizontal
            flipped = False
        else:
            height = horizontal
            width = vertical
            flipped = True

        if height < min_height or height > max_height:
            return None

        if width < min_width or width > max_height:
            return None

        if away > max_distance:
            return None

        # This page was helpful in understanding angle
        # https://namkeenman.wordpress.com/2015/12/18/open-cv-determine-angle-of-rotatedrect-minarearect/
        angle = rect[2]
        if rect[1][0] < rect[1][1]:
            angle -= 90.0

        if debug_img is not None:
            x, y, w, h = cv2.boundingRect(c)
            cv2.drawContours(debug_img, [c], -1, (0, 255, 0), 2)
            cv2.drawContours(debug_img, [np.int0(np.array(box))], -1,
                             (0, 0, 255), 2)
            cv2.rectangle(debug_img, (x, y), (x + w, y + h), (255, 0, 0), 2)

            cv2.circle(debug_img, top, 5, (255, 255, 0))
            cv2.circle(debug_img, bottom, 5, (255, 255, 0))
            cv2.circle(debug_img, left, 5, (255, 255, 0))
            cv2.circle(debug_img, right, 5, (255, 255, 0))
            cv2.circle(debug_img, center, 5, (255, 255, 0))

        return Thing(height, width, center, angle)
예제 #5
0
    def _find_choke_thing(self):
        """ Find the choke at the solar array box """
        """ This uses color to determine if we have a choke """
        lower = np.array([128, 0, 0], dtype="uint8")
        upper = np.array([255, 10, 20], dtype="uint8")
        mask = cv2.inRange(self.img, lower, upper)

        blurred = cv2.GaussianBlur(mask, (5, 5), 0)
        thresh = cv2.threshold(blurred, 60, 255, cv2.THRESH_BINARY)[1]

        contours = cv2.findContours(thresh, cv2.RETR_EXTERNAL,
                                    cv2.CHAIN_APPROX_SIMPLE)
        contours = contours[0] if is_cv2() else contours[1]

        # Note: you can get your view of the choke cut; so you see an end as 2 contours.
        #  In a dream world, we would combine two small controus close together.
        #  But for now, we just operate with the two biggest contours
        sorted_contours = sorted(
            contours,
            cmp=lambda a, b: int(cv2.contourArea(b)) - int(cv2.contourArea(a)))

        if len(sorted_contours) >= 2:
            thing1 = self._find_a_thing(sorted_contours[0], 0, 0.1, 0, 0.1,
                                        99.0)
            thing2 = self._find_a_thing(sorted_contours[1], 0, 0.1, 0, 0.1,
                                        99.0)

            if thing1 is not None and thing2 is not None:
                print "We have a choke!"
                box1 = cv2.boundingRect(sorted_contours[0])
                box2 = cv2.boundingRect(sorted_contours[1])
                if box1[0] > box2[0]:
                    inner = thing1
                    outer = thing2
                else:
                    inner = thing2
                    outer = thing1

                inner.set_choke_inner()
                self.things.append(inner)
                self.choke_inner = inner
                outer.set_choke_outer()
                self.things.append(outer)
                self.choke_outer = outer

                if self.debug:
                    debug_img = self.img.copy()
                    for c in sorted_contours:
                        cv2.drawContours(debug_img, [c], -1, (0, 255, 0), 2)
                    cv2.imshow("choke picture", debug_img)
                    cv2.setMouseCallback("choke picture", self.handle_mouse)
                    cv2.waitKey(0)
                    cv2.destroyAllWindows()
예제 #6
0
    def _find_habitat_things(self):
        """ Find interesting objects in the habitat world """
        self._find_repair_button_thing()

        # Start by grey scale, blur, and thresholding
        gray = cv2.cvtColor(self.img, cv2.COLOR_BGR2GRAY)
        blurred = cv2.GaussianBlur(gray, (5, 5), 0)
        thresh = cv2.threshold(blurred, 60, 255, cv2.THRESH_BINARY)[1]

        # find contours in the thresholded image
        contours = cv2.findContours(thresh, cv2.RETR_EXTERNAL,
                                    cv2.CHAIN_APPROX_SIMPLE)
        contours = contours[0] if is_cv2() else contours[1]

        debug_img = self.img.copy()

        for c in contours:
            thing = self._find_a_thing(c, self.MINIMUM_TOOL_LENGTH,
                                       self.MAXIMUM_TOOL_LENGTH,
                                       self.MINIMUM_TOOL_WIDTH,
                                       self.MAXIMUM_TOOL_WIDTH,
                                       self.TOOL_MUST_BE_WITHIN, debug_img)
            if thing is None:
                continue

            x, y, w, h = cv2.boundingRect(c)
            detector_center, up = self.is_detector(self.img[y:y + h,
                                                            x:x + w].copy())

            if detector_center is not None:
                adjusted_detector = (int(detector_center[0] + x),
                                     int(detector_center[1] + y))
                thing.set_detector(adjusted_detector, up)
                self.things.append(thing)
                self.leak_detector = thing

            repair_center, up = self.is_repair_tool(self.img[y:y + h,
                                                             x:x + w].copy())
            if repair_center is not None:
                adjusted_repair = (int(repair_center[0] + x),
                                   int(repair_center[1] + y))
                thing.set_repair_tool(adjusted_repair, up)
                self.things.append(thing)
                self.repair_tool = thing

        if self.debug:
            for c in contours:
                cv2.drawContours(debug_img, [c], -1, (0, 255, 0), 2)
            cv2.imshow("habitat things", debug_img)
            cv2.setMouseCallback("habitat things", self.handle_mouse)
            cv2.waitKey(0)
            cv2.destroyAllWindows()
예제 #7
0
    def _find_repair_button_thing(self):
        """ Find the repairt button in front of us """
        """ This uses color to determine if we have a repair button"""
        lower = np.array([190, 0, 0], dtype="uint8")
        upper = np.array([255, 150, 20], dtype="uint8")
        mask = cv2.inRange(self.img, lower, upper)

        blurred = cv2.GaussianBlur(mask, (5, 5), 0)
        thresh = cv2.threshold(blurred, 60, 255, cv2.THRESH_BINARY)[1]

        contours = cv2.findContours(thresh, cv2.RETR_EXTERNAL,
                                    cv2.CHAIN_APPROX_SIMPLE)
        contours = contours[0] if is_cv2() else contours[1]

        debug_img = None
        if self.debug:
            debug_img = self.img.copy()
            cv2.imshow("button mask", thresh)
            cv2.setMouseCallback("button mask", self.handle_mouse)
            cv2.waitKey(0)
            cv2.destroyAllWindows()

        button_box = None
        for c in contours:
            box = cv2.boundingRect(c)

            if button_box is None:
                button_box = box
            else:
                button_box = self._union_box(deepcopy(button_box), box)

        if button_box is None:
            print "No button box"
            return

        top, bottom, left, right, center = self.find_dimensions(
            np.int0(np.array(self._bound_to_boxpoints(button_box))))
        if top is None or left is None or center is None:
            print "Missing one of bounds.  {}/{}/{}".format(top, left, center)
            return None

        height = self.find_distance(top, bottom)
        width = self.find_distance(left, right)

        if self.debug:
            for c in contours:
                cv2.drawContours(debug_img, [c], -1, (0, 255, 0), 2)

            cv2.circle(debug_img, top, 5, (255, 255, 0))
            cv2.circle(debug_img, bottom, 5, (255, 255, 0))
            cv2.circle(debug_img, left, 5, (255, 255, 0))
            cv2.circle(debug_img, right, 5, (255, 255, 0))
            cv2.rectangle(
                debug_img, (button_box[0], button_box[1]),
                (button_box[0] + button_box[2], button_box[1] + button_box[3]),
                (128, 0, 128), 2)
            #cv2.circle(debug_img, center, 5, (255, 255, 0))

            cv2.imshow("repair button picture", debug_img)
            cv2.setMouseCallback("repair button picture", self.handle_mouse)
            cv2.waitKey(0)
            cv2.destroyAllWindows()

        self.repair_button = Thing(height, width, center, None)
        self.repair_button.set_repair_button()
        self.repair_button.computed_center = self.compute_center(
            left, right, top, bottom)
        self.things.append(self.repair_button)