コード例 #1
0
def get_wire_colors(img, coords):
    """
    Get a list of colors for each wire. Colors can be either:
    -1 (no wire), 0 (blue), 1 (white), 2 (red), or 3 (blue + red).
    """
    wires = [-1] * 6
    colors = config.WIRE_COLOR_RANGE[2:]
    rgb = features_util.split_channels(img)
    # Radius around each wire pixel to search for colors.
    search_radius = 9
    # Minimum threshold for number of pixels to be of a specific color.
    color_threshold = 6
    for i, (y, x) in enumerate(coords):  # Look through each wire pixel.
        valid_colors = [0] * len(colors)  # Track occurences of each color.
        for k, (lo, hi) in enumerate(colors):  # Look through possible colors.
            for m in range(y - search_radius, y +
                           search_radius):  # Look in a radius around a pixel.
                for n in range(x - search_radius, x + search_radius):
                    if features_util.color_in_range((m, n), rgb, lo, hi):
                        if valid_colors[k] < color_threshold:
                            valid_colors[k] += 1
        if valid_colors[COLOR.Blue.value] == color_threshold:  # Wire is blue.
            if valid_colors[
                    COLOR.Red.value] == color_threshold:  # Wire is also red.
                wires[i] = COLOR.Both.value  # Both colors.
            else:
                wires[i] = COLOR.Blue.value
        elif valid_colors[
                COLOR.Red.value] == color_threshold:  # Wire is just red.
            wires[i] = COLOR.Red.value
        elif valid_colors[
                COLOR.White.value] == color_threshold:  # Wire is white.
            wires[i] = COLOR.White.value
    return wires
コード例 #2
0
 def monitor(self):
     _, SH = get_screen_size()
     lo = (30, 30, 30)
     hi = (255, 255, 255)
     self.change_event.set()
     while self.is_active:
         sc = screenshot(0, SH - 200, 200, 200)
         img = features_util.convert_to_cv2(sc)
         rgb = features_util.split_channels(img)
         if self.lights_on:
             if not features_util.color_in_range(self.pixel, rgb, lo, hi):
                 if self.bomb_exploded(rgb):  # We died :(
                     self.is_active = False
                     self.exit_after_explosion()
                 else:
                     log("Lights in the room are turned off. Pausing execution temporarily..."
                         )
                     self.lights_on = False
                     self.change_event.clear()
                     sleep(1)
         else:
             if features_util.color_in_range(self.pixel, rgb, lo, hi):
                 log("Lights in the room are turned back on. Resuming...")
                 self.change_event.set()
                 self.lights_on = True
                 sleep(1)
         sleep(0.25)
コード例 #3
0
def get_strip_color(img, pixel):
    colors = config.BUTTON_COLOR_RANGE
    for i, (low, high) in enumerate(colors):
        rgb = feature_util.split_channels(img)
        if feature_util.color_in_range(pixel, rgb, low, high):
            return i
    return -1
コード例 #4
0
def get_wire_colors(img, coords):
    wires = [-1] * 6
    radius = 5
    Color = Enum("Colors", {"Blue": 0, "White": 1, "Red": 2, "Both": 3})
    colors = config.WIRE_COLOR_RANGE[2:]
    rgb = features_util.split_channels(img)
    color_threshold = 5
    for i, (y, x) in enumerate(coords):
        valid_colors = [0] * len(colors)
        for k, (lo, hi) in enumerate(colors):
            for m in range(y - radius, y + radius):
                for n in range(x - radius, x + radius):
                    if features_util.color_in_range((m, n), rgb, lo, hi):
                        if valid_colors[k] < color_threshold:
                            valid_colors[k] += 1
        if valid_colors[Color.Blue.value] == color_threshold:
            if valid_colors[Color.Red.value] == color_threshold:
                wires[i] = Color.Both.value  # Both colors.
            else:
                wires[i] = Color.Blue.value
        elif valid_colors[Color.Red.value] == color_threshold:
            wires[i] = Color.Red.value
        elif valid_colors[Color.White.value] == color_threshold:
            wires[i] = Color.White.value
    return wires
コード例 #5
0
def get_next_color(img, sc_func, ranges, features, curr_match):
    coords = [(140, 95), (74, 155), (204, 156), (140, 216)]
    colors = ["Red", "Blue", "Green", "Yellow"]
    button_coords = []
    pause_between_blinks = 0.35
    colors_matched = 0
    timestamp = 0
    while True:
        sc, _, _ = sc_func()
        rgb = feature_util.split_channels(
            cv2.cvtColor(array(sc), cv2.COLOR_RGB2BGR))
        for i, (low, high) in enumerate(ranges):
            coord = coords[i]
            if feature_util.color_in_range(
                    coord, rgb, low,
                    high) and time() - timestamp > pause_between_blinks:
                colors_matched += 1
                press_color = get_response_color(i, features)
                button_coords.append(coords[press_color])
                timestamp = time()
                if colors_matched == curr_match:
                    log(f"Color: {colors[i]}. Press: {colors[press_color]}",
                        LOG_DEBUG, "Simon Says")
                    return button_coords
        sleep(0.1)  # Lamps are lit for 0.25 seconds.
コード例 #6
0
def get_button_color(image):
    color_ranges = config.BUTTON_COLOR_RANGE
    pixel = 210, 120
    for i, (low, high) in enumerate(color_ranges):
        rgb = feature_util.split_channels(image)
        if feature_util.color_in_range(pixel, rgb, low, high):
            return i
    return -1
コード例 #7
0
ファイル: needy_knob.py プロジェクト: vestigegroup/BombSolver
def get_led_states(img):
    coords = [(195, 77), (219, 94), (236, 120), (236, 179), (219, 205),
              (195, 222), (204, 57), (236, 78), (258, 112), (258, 187),
              (236, 220), (204, 242)]
    lit_low = (130, 190, 25)
    lit_high = (220, 255, 100)
    rgb = features_util.split_channels(img)
    states = []
    for y, x in coords:
        states.append(
            features_util.color_in_range((y, x), rgb, lit_low, lit_high))
    return states
コード例 #8
0
def get_indicator_ratio(img):
    min_y, max_y = 125, 246
    x = 66
    min_rgb = config.DISCHARGE_MIN_RED
    max_rgb = config.DISCHARGE_MAX_RED
    rgb = features_util.split_channels(img)
    filled_height = 0
    for y in range(min_y, max_y):
        if features_util.color_in_range((y, x), rgb, min_rgb, max_rgb):
            filled_height += 1

    total_height = max_y - min_y
    return filled_height / total_height
コード例 #9
0
def is_active(img):
    cropped = crop_image(img)
    h, w = cropped.shape[:2]
    y = h // 2
    step_x = w // 12
    start_x = (w // 10)
    min_red = (170, 0, 0)
    max_red = (255, 70, 70)
    rgb = features_util.split_channels(cropped)
    for i in range(1, 11):
        x = int(start_x + i * step_x)
        pixel = (y, x)
        if features_util.color_in_range(pixel, rgb, min_red, max_red):
            return True
    return False
コード例 #10
0
ファイル: needy_knob.py プロジェクト: vestigegroup/BombSolver
def get_dial_orientation(img):
    dial_y_min, dial_x_min, dial_y_max, dial_x_max = 130, 118, 194, 182
    rgb = features_util.split_channels(img)
    mid_y = (dial_y_min + dial_y_max) / 2
    mid_x = (dial_x_min + dial_x_max) / 2
    offset = 16
    coords = [(mid_y - offset, mid_x), (mid_y, mid_x + offset),
              (mid_y + offset, mid_x), (mid_y, mid_x - offset)]
    red_min = (190, 30, 0)
    red_max = (255, 85, 40)
    for i, (y, x) in enumerate(coords):
        if features_util.color_in_range((int(y), int(x)), rgb, red_min,
                                        red_max):
            return i
    return -1
コード例 #11
0
def solve(img, features):
    wire_coords = [(140, 49), (140, 74), (140, 126), (140, 168), (140, 190),
                   (140, 226)]
    wires = get_wire_colors(img, wire_coords)
    stars = get_stars(img)
    lights = get_lights(features_util.split_channels(img))
    log(desc_wires(wires, stars, lights), LOG_DEBUG, "Complicated Wires")
    wires_to_cut = []
    for (star, light, wire) in zip(stars, lights, wires):
        if wire == -1:
            wires_to_cut.append(False)
            continue
        solve_label = get_wire_label(star, light, wire)
        wires_to_cut.append(parse_label(solve_label, features))
    log(f"Wires to cut: {wires_to_cut}", LOG_DEBUG, "Complicated Wires")
    return wires_to_cut, wire_coords
コード例 #12
0
def solve(img, features):
    wire_coords = [(140, 49), (140, 74), (140, 126), (140, 168), (140, 190),
                   (140, 226)]
    wires = get_wire_colors(img, wire_coords)
    stars = get_stars(img)
    lights = get_lights(features_util.split_channels(img))
    log(desc_wires(wires, stars, lights), LOG_DEBUG, "Complicated Wires")
    wires_to_cut = []
    for (star, light, wire) in zip(stars, lights, wires):
        if wire == -1:
            wires_to_cut.append(False)
            continue
        # Get label from Venn Diagram,
        # based on the color of the wire and whether it has a star or lit LED.
        solve_label = get_wire_label(star, light, wire)
        # Determine whether to cut the wire, based on label and other bomb features.
        wires_to_cut.append(parse_label(solve_label, features))
    log(f"Wires to cut: {wires_to_cut}", LOG_DEBUG, "Complicated Wires")
    return wires_to_cut, wire_coords
コード例 #13
0
def determine_alignment(image, bbox, lit):
    if lit:
        return lit
    mid_x = (bbox[2] + bbox[3]) // 2
    q = abs(bbox[3] - bbox[2]) // 4
    q1_x = (bbox[2] + q)
    q3_x = abs(bbox[2] - bbox[3]) - q + bbox[2]
    x_coords = [q1_x, mid_x, q3_x]
    y_coords = [bbox[1] - 30, bbox[1] - 60, bbox[0] + 30, bbox[0] + 60]
    for x in x_coords:
        for i, y in enumerate(y_coords):
            h, _ = image.shape[:2]
            if y >= h or y < 0:
                continue
            min_c, max_c = ((25, 25, 25), (45, 45, 45))
            rgb = features_util.split_channels(image)
            pixel = (y, x)
            if features_util.color_in_range(pixel, rgb, min_c, max_c):
                return 1 if i < 2 else -1
    return 0
コード例 #14
0
def get_wire_colors(img):
    Colors = Enum("Colors", {"Red": 0, "Blue": 1, "Black": 2})
    coords = [  # Top to bottom.
        (91, 86), (102, 100), (102, 80), (127, 106), (138, 90), (146, 90),
        (174, 91), (173, 111), (184, 106)
    ]
    colors = [  # Red, Blue & Black.
        ((139, 0, 0), (255, 99, 71)), ((20, 20, 120), (130, 130, 255)),
        ((0, 0, 0), (10, 10, 10))
    ]
    rgb = features_util.split_channels(img)
    wires = [-1] * 3
    destinations = [-1] * 3
    coords_to_cut = [-1] * 3
    for i, pixel in enumerate(coords):
        for color, (lo, hi) in enumerate(colors):
            if features_util.color_in_range(pixel, rgb, lo, hi):
                coords_to_cut[i // 3] = coords[i]
                wires[i // 3] = color
                destinations[i // 3] = i % 3
    return wires, destinations, coords_to_cut
コード例 #15
0
ファイル: maze.py プロジェクト: Xen0byte/BombSolver
def get_start_and_end(img):
    red_l = (200, 0, 0)
    red_h = (255, 30, 40)
    white_l = (190, 190, 190)
    white_h = (255, 255, 255)
    rgb = features_util.split_channels(img)
    start_x = 17
    start_y = 16
    gap = 25
    start = None
    end = None
    for j in range(0, 6):
        y = start_y + j * gap
        for i in range(0, 6):
            x = start_x + i * gap
            pixel = (y, x)
            r, g, b = rgb
            if features_util.color_in_range(pixel, rgb, white_l, white_h):
                start = (i, j)
            elif features_util.color_in_range(pixel, rgb, red_l, red_h):
                end = (i, j)
    assert start is not None
    assert end is not None
    return start, end
コード例 #16
0
def is_solved(image):
    rgb = feature_util.split_channels(cv2.cvtColor(image, cv2.COLOR_RGB2BGR))
    pixel = (18, 270)
    lit_low = (0, 200, 0)
    lit_high = (50, 255, 50)
    return feature_util.color_in_range(pixel, rgb, lit_low, lit_high)
コード例 #17
0
def solve(img, features):
    h, w, c = img.shape

    # Coordinates of wire endpoints.
    coords = [(40, 70), (80, 74), (118, 74), (157, 74), (198, 70), (240, 72)]
    # Colords of wires.
    color_ranges = config.WIRE_COLOR_RANGE
    Colors = Enum("Colors", {
        "Black": 0,
        "Yellow": 1,
        "Blue": 2,
        "White": 3,
        "Red": 4
    })
    num_wires = 0
    color_hist = [0, 0, 0, 0, 0]
    wire_hist = [-1, -1, -1, -1, -1, -1]
    rgb = features_util.split_channels(img)
    for i, coord in enumerate(coords):
        for j, (low, high) in enumerate(color_ranges):
            if features_util.color_in_range(coord, rgb, low, high):
                color_hist[j] += 1
                wire_hist[i] = j
                num_wires += 1
                log(f"Wire {i+1} is {Colors(j)}", LOG_DEBUG, "Wires")
                break

    serial_odd = features.get("last_serial_odd", None)
    if serial_odd is None:
        log("WARNING: Serial number information not provided", LOG_WARNING,
            "Wires")
        raise ValueError  # Something went wrong.

    if num_wires == 3:
        if color_hist[Colors.Red.value] == 0:  # There are no red wires.
            return get_nth_wire(wire_hist, 1), coords  # Cut second wire.
        last_wire = get_nth_wire(wire_hist, -1)
        if wire_hist[last_wire] == Colors.White.value:  # Last wire is white.
            return get_nth_wire(wire_hist, -1), coords  # Cut last wire
        if color_hist[Colors.Blue.value] > 1:  # More than one blue wire.
            return get_nth_wire(
                wire_hist, -1,
                Colors.Blue.value), coords  # Cut last blue wire.
        return get_nth_wire(wire_hist, -1), coords  # Cut the last wire.
    if num_wires == 4:
        if color_hist[
                Colors.Red.
                value] > 1 and serial_odd:  # More than one red wire + serial number odd.
            return get_nth_wire(wire_hist, -1,
                                Colors.Red.value), coords  # Cut last red wire.
        last_wire = get_nth_wire(wire_hist, -1)
        # Last wire is yellow + no red wires.
        if wire_hist[last_wire] == Colors.Yellow.value and color_hist[
                Colors.Red.value] == 0:
            return get_nth_wire(wire_hist, 0), coords  # Cut the first wire.
        if color_hist[Colors.Blue.value] == 1:  # Exactly one blue wire.
            return get_nth_wire(wire_hist, 0), coords  # Cut the first wire.
        if color_hist[Colors.Yellow.value] > 1:  # More than one yellow wire.
            return get_nth_wire(wire_hist, -1,
                                Colors.Red.value), coords  # Cut last red wire.
        return get_nth_wire(wire_hist, 1), coords  # Cut the second wire.
    if num_wires == 5:
        last_wire = get_nth_wire(wire_hist, -1)
        # Last wire is black + serial number odd.
        if wire_hist[last_wire] == Colors.Black.value and serial_odd:
            return get_nth_wire(wire_hist, 3), coords  # Cut the fourth wire.
        # One red wire + more than one yellow.
        if color_hist[
                Colors.Red.value] == 1 and color_hist[Colors.Yellow.value] > 1:
            return get_nth_wire(wire_hist, 0), coords  # Cut the first wire.
        if color_hist[Colors.Black.value] == 0:  # No black wires.
            return get_nth_wire(wire_hist, 1), coords  # Cut the second wire.
        return get_nth_wire(wire_hist, 0), coords  # Cut the first wire.
    if num_wires == 6:
        if color_hist[
                Colors.Yellow.
                value] == 0 and serial_odd:  # No yellow wires + serial number odd.
            return get_nth_wire(wire_hist, 2), coords  # Cut the third wire.
        # One yellow + more than one white.
        if color_hist[Colors.Yellow.
                      value] == 1 and color_hist[Colors.White.value] > 1:
            return get_nth_wire(wire_hist, 3), coords  # Cut the fourth wire.
        if color_hist[Colors.Red.value] == 0:  # No red wires.
            return get_nth_wire(wire_hist, -1), coords  # Cut last wire.
        return get_nth_wire(wire_hist, 3), coords  # Cut the fourth wire.
    log("WARNING: Invalid number of wires.", LOG_WARNING, "Wires")
    raise ValueError  # Something went wrong.
コード例 #18
0
ファイル: wire_solver.py プロジェクト: Xen0byte/BombSolver
def solve(img, features):
    # Coordinates of wire endpoints.
    coords = [(40, 70), (80, 74), (118, 74), (157, 74), (198, 70), (240, 72)]
    # Colors of wires.
    color_ranges = config.WIRE_COLOR_RANGE
    Colors = Enum("Colors", {
        "Black": 0,
        "Yellow": 1,
        "Blue": 2,
        "White": 3,
        "Red": 4
    })
    num_wires = 0
    color_hist = [0, 0, 0, 0, 0]  # Histogram of color occurences.
    wire_colors = [-1, -1, -1, -1, -1,
                   -1]  # Color of each wire. -1 means wire is missing.
    rgb = features_util.split_channels(img)
    radius = 5

    # Look through coordinates for each wire and check if a color matches that pixel.
    for i, coord in enumerate(coords):
        valid_colors = [0] * len(color_ranges)
        max_color_index = 0
        max_color_count = 0

        for j, (low, high) in enumerate(
                color_ranges):  # Run through each possible color range.
            for m in range(coord[0] - radius, coord[0] +
                           radius):  # Look in a 5px radius around pixel.
                for n in range(coord[1] - radius, coord[1] + radius):
                    if features_util.color_in_range((m, n), rgb, low,
                                                    high):  # Color detected.
                        valid_colors[
                            j] += 1  # Record occurence of current color.
                        if valid_colors[
                                j] > max_color_count:  # Track most seen color.
                            max_color_count = valid_colors[j]
                            max_color_index = j

        if max_color_count > 10:  # Assume no wire is present if too few pixels matched a color.
            color_hist[max_color_index] += 1  # Record occurence of wire color.
            wire_colors[
                i] = max_color_index  # Record what color the ith wire is.
            num_wires += 1
            log(f"Wire {i+1} is {Colors(max_color_index)}", LOG_DEBUG, "Wires")

    serial_odd = features.get("last_serial_odd", None)
    if num_wires > 3 and serial_odd is None:
        # Serial number was not previous detected correctly.
        # If we depend on this info to solve wires, raise an error.
        log("WARNING: Serial number information not provided", LOG_WARNING,
            "Wires")
        raise ValueError

    if num_wires == 3:
        if color_hist[Colors.Red.value] == 0:  # There are no red wires.
            return get_nth_wire(wire_colors, 1), coords  # Cut second wire.
        last_wire = get_nth_wire(wire_colors, -1)
        if wire_colors[last_wire] == Colors.White.value:  # Last wire is white.
            return get_nth_wire(wire_colors, -1), coords  # Cut last wire
        if color_hist[Colors.Blue.value] > 1:  # More than one blue wire.
            return get_nth_wire(
                wire_colors, -1,
                Colors.Blue.value), coords  # Cut last blue wire.
        return get_nth_wire(wire_colors, -1), coords  # Cut the last wire.
    if num_wires == 4:
        if color_hist[
                Colors.Red.
                value] > 1 and serial_odd:  # More than one red wire + serial number odd.
            return get_nth_wire(wire_colors, -1,
                                Colors.Red.value), coords  # Cut last red wire.
        last_wire = get_nth_wire(wire_colors, -1)
        # Last wire is yellow + no red wires.
        if wire_colors[last_wire] == Colors.Yellow.value and color_hist[
                Colors.Red.value] == 0:
            return get_nth_wire(wire_colors, 0), coords  # Cut the first wire.
        if color_hist[Colors.Blue.value] == 1:  # Exactly one blue wire.
            return get_nth_wire(wire_colors, 0), coords  # Cut the first wire.
        if color_hist[Colors.Yellow.value] > 1:  # More than one yellow wire.
            return get_nth_wire(wire_colors, -1,
                                Colors.Red.value), coords  # Cut last red wire.
        return get_nth_wire(wire_colors, 1), coords  # Cut the second wire.
    if num_wires == 5:
        last_wire = get_nth_wire(wire_colors, -1)
        # Last wire is black + serial number odd.
        if wire_colors[last_wire] == Colors.Black.value and serial_odd:
            return get_nth_wire(wire_colors, 3), coords  # Cut the fourth wire.
        # One red wire + more than one yellow.
        if color_hist[
                Colors.Red.value] == 1 and color_hist[Colors.Yellow.value] > 1:
            return get_nth_wire(wire_colors, 0), coords  # Cut the first wire.
        if color_hist[Colors.Black.value] == 0:  # No black wires.
            return get_nth_wire(wire_colors, 1), coords  # Cut the second wire.
        return get_nth_wire(wire_colors, 0), coords  # Cut the first wire.
    if num_wires == 6:
        if color_hist[
                Colors.Yellow.
                value] == 0 and serial_odd:  # No yellow wires + serial number odd.
            return get_nth_wire(wire_colors, 2), coords  # Cut the third wire.
        # One yellow + more than one white.
        if color_hist[Colors.Yellow.
                      value] == 1 and color_hist[Colors.White.value] > 1:
            return get_nth_wire(wire_colors, 3), coords  # Cut the fourth wire.
        if color_hist[Colors.Red.value] == 0:  # No red wires.
            return get_nth_wire(wire_colors, -1), coords  # Cut last wire.
        return get_nth_wire(wire_colors, 3), coords  # Cut the fourth wire.
    log("WARNING: Invalid number of wires.", LOG_WARNING, "Wires")
    raise ValueError  # Something went wrong.
コード例 #19
0
def solve(img, screenshot_func):
    pixel = (43, 108)
    rgb = features_util.split_channels(img)

    dot_pause = 0.1  # 15 frames = 0.25 seconds.
    dash_pause = 0.6  # 47 frames ~ 0.75 seconds.
    letter_pause = 1  # 63 frames ~ 1 second
    word_pause = 2.5  # 194 frames ~ 3.3 seconds
    sleep_duration = 0.05
    duration = 0
    solved_from_prefix = True
    for i in range(
            2
    ):  # Run twice to ensure the whole sequence of letters are recorded.
        if not solved_from_prefix:
            log("Solved Morse in first round!", LOG_DEBUG, "Morse")
            break
        lit = is_lit(pixel, rgb)
        checkpoint = time()
        letters = ""
        symbols = ""
        while True:
            sleep(sleep_duration)
            screenshot, _, _ = screenshot_func()
            rgb = features_util.split_channels(
                cv2.cvtColor(array(screenshot), cv2.COLOR_RGB2BGR))

            if is_lit(pixel, rgb) != lit:  # Check if light has changed state.
                lit = not lit
                if lit:
                    duration = time() - checkpoint  # Record length of gap.
                    checkpoint = time()  # Record time of light being lit.

                    if duration >= letter_pause:
                        letter = LETTERS.get(symbols, '')
                        log(f"LETTER: {letter}", LOG_DEBUG, "Morse")
                        letters += letter
                        if i == 0 and len(
                                letters) > 1 and get_word_from_substring(
                                    letters[1:]) is not None:
                            # Terminate if we can already guess from a substring of the word.
                            solved_from_prefix = False  # Indicate word was solved in first round.
                            break
                        if i == 1 and get_word_from_prefix(
                                letters) is not None:
                            break  # Terminate if we can already guess from a prefix of the word.
                        symbols = ""
                    if duration >= word_pause:
                        pos_str = "START" if i == 0 else "END"
                        log(f"=== {pos_str} OF WORD ===", LOG_DEBUG, "Morse")
                        break
                else:
                    duration = time() - checkpoint  # Record length of flash.
                    checkpoint = time()  # Record time of light being unlit.

                    if duration >= dash_pause:
                        symbols += "-"
                    elif duration >= dot_pause:
                        symbols += "."

    # Return amount of times to press morse button.
    presses = (get_word_from_prefix(letters)
               if solved_from_prefix else get_word_from_substring(letters))
    log(f"Word: {WORDS[presses]}", LOG_DEBUG, "Morse")
    return presses, FREQUENCIES[presses]