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()
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
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
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)
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()
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()
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)