File size: 2,744 Bytes
caa1b69
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
from interactive_pipe import interactive_pipeline, interactive, Image
import numpy as np

# Helper functions
# ----------------


def flip_image(img, flip=True, mirror=True):
    img = img[::-1] if flip else img
    img = img[:, ::-1] if mirror else img
    return img


def get_crop(img, pos_x, pos_y, crop_size=0.1):
    c_size = int(crop_size * img.shape[0])
    crop_x = (int(pos_x * img.shape[1]), int((pos_x) * img.shape[1]) + c_size)
    crop_y = (int(pos_y * img.shape[0]), int((pos_y) * img.shape[0]) + c_size)
    return crop_x, crop_y

# Processing blocks
# -----------------


@interactive(seed=(45, [0, 100], "Puzzle seed"))
def generate_random_puzzle(seed: int = 45, context: dict = {}):
    np.random.seed(seed)
    pos_x, pos_y, intensity = np.random.uniform(0.2, 0.8, 3)
    context["puzzle"] = (pos_x, pos_y, intensity)
    context["puzzle_flip_mirror"] = np.random.choice([True, False], 2)


def create_puzzle(img, context: dict = {}):
    out = img.copy()
    x_gt, y_gt, intensity = context["puzzle"]
    flip_gt, mirror_gt = context["puzzle_flip_mirror"]
    cs_x, cs_y = get_crop(img, x_gt, y_gt)
    crop = img[cs_y[0]:cs_y[1], cs_x[0]:cs_x[1], ...]
    out[cs_y[0]:cs_y[1], cs_x[0]:cs_x[1]] = intensity*0.4*crop
    crop = flip_image(crop, flip=flip_gt, mirror=mirror_gt)
    return out, crop


@interactive(
    flip=(True, "Flip Image"),
    mirror=(True, "Mirror Image"),
)
def flip_mirror_piece(piece: np.ndarray, flip=True, mirror=True):
    return flip_image(piece.copy(), flip=flip, mirror=mirror)


@interactive(
    pos_x=(0.5, [0.1, 0.9], "Position X"),
    pos_y=(0.5, [0.1, 0.9], "Position Y"),
)
def place_puzzle(puzzle, piece, pos_x: float = 0.5, pos_y: float = 0.5):
    out = puzzle.copy()
    cp_x, cp_y = get_crop(img, pos_x, pos_y)
    out[cp_y[0]:cp_y[1], cp_x[0]:cp_x[1]] = piece
    return out


# pipeline definition
# -------------------
def captcha_pipe(inp):
    generate_random_puzzle()
    puzzle, puzzle_piece = create_puzzle(inp)
    puzzle_piece = flip_mirror_piece(puzzle_piece)
    puzzle = place_puzzle(puzzle, puzzle_piece)
    return [puzzle_piece, puzzle]


if __name__ == "__main__":
    import argparse
    parser = argparse.ArgumentParser()
    parser.add_argument("-b", "--backend", default="gradio",
                        choices=["gradio", "qt"], type=str)
    args = parser.parse_args()
    markdown_description = "# Code to build this app on gradio \n"
    markdown_description += "```python\n"+open(__file__, 'r').read()+"```"
    img = Image.load_image("sample.jpg")
    captcha_pipe_interactive = interactive_pipeline(
        gui=args.backend,
        cache=True,
        markdown_description=markdown_description
    )(captcha_pipe)
    captcha_pipe_interactive(img)