<jupyter_start><jupyter_text>Cracks AugmentationOld photographs seem to have cracks and folds often, so if we want to fix this using deep learning, we have to make appropriate data augmentations.<jupyter_code>def get_cracks(size: Tuple[int, int], *, simple_fork: bool = True, **kwargs) -> Tuple[np.ndarray, float]:
    assert len(size) == 2
    assert size[0] > 0 and size[1] > 0

    mtx = np.zeros(size, dtype=np.uint8)

    def stain(x_: float, y_: float) -> None:
        x_, y_ = int(x_), int(y_)
        x_ = abs(x_) % size[0]
        y_ = abs(y_) % size[1]
        mtx[x_, y_] = 1

    # Draw a crack and return its length
    def crack(x_: float, y_: float, angle: float, angle_amp: float = math.pi / 6, angle_dist: float = 10.0,
              fork_dist: float = 100.0, end_dist: float = 1000.0, end_dist_factor: float = 0.1,
              exact_end_dist: Optional[int] = None, exact_end_fork_factor: float = 0.25, step: float = 1.0) -> float:
        dist: float = 0.0
        forks_length: float = 0.0
        while True:
            angle_p = math.exp(-1 * dist / angle_dist)
            fork_p = math.exp(-1 * dist / fork_dist)
            end_p = math.exp(-1 * dist / end_dist)
            
            # Decide either to end the crack or not
            if exact_end_dist is None:
                # End the crack with probability (1 - end_p)
                if bernoulli.rvs(1 - end_p):
                    break
            else:
                if dist + forks_length > exact_end_dist:
                    break
            
            # Decide either to fork the crack or not
            if bernoulli.rvs(1 - fork_p):
                if simple_fork:
                    # Fork a new crack perpendicularly
                    cc_angle = angle + random.choice([-1, 1]) * math.pi / 2
                else:
                    # Fork a new crack in a different direction and
                    # alter the current crack's propagation angle too
                    angle_delta = random.uniform(-1, 1) * angle_amp
                    angle = angle + angle_delta
                    cc_angle = angle - angle_delta
                cc_end_dist = end_dist * end_dist_factor
                cc_exact_end_dist = (None
                                     if exact_end_dist is None else
                                     (exact_end_dist - dist - forks_length) * exact_end_fork_factor)
                forks_length += crack(x_, y_, angle=cc_angle, end_dist=cc_end_dist, exact_end_dist=cc_exact_end_dist)
            
            # Changes angle of the crack propagation with probability of (1 - angle_p)
            if bernoulli.rvs(1 - angle_p):
                angle += random.uniform(-1, 1) * angle_amp
            
            x_ += step * math.cos(angle)
            y_ += step * math.sin(angle)
            dist += step
            stain(x_, y_)
        return dist + forks_length
    
    x = random.randrange(0, size[0])
    y = random.randrange(0, size[1])
    angle = 2 * math.pi * random.random()
    length = crack(x, y, angle, **kwargs)
    return mtx, length
        
def plot_cracks(nrows_: int = 5, ncols_: int = 5, **kwargs) -> None:
    assert nrows_ > 1 and ncols_ > 1
    _, axes = plt.subplots(nrows=nrows_, ncols=ncols_, sharex=True, sharey=True, figsize=(12, 12))
    for i in range(nrows_):
        for j in range(ncols_):
            m, l = get_cracks((100, 100), **kwargs)
            plt.sca(ax=axes[i][j])
            plt.title(f'{l:.2f}')
            plt.imshow(m)

%%time
plot_cracks()
%%time
plot_cracks(fork_dist=1000, exact_end_dist=500)
%%time
plot_cracks(angle_dist=100, fork_dist=10000, exact_end_dist=500)
%%time
plot_cracks(simple_fork=False, angle_dist=100, fork_dist=10000, exact_end_dist=500)
%%time
plot_cracks(fork_dist=2000, end_dist=5000)
%%time
plot_cracks(simple_fork=False, fork_dist=1000, end_dist=5000)<jupyter_output>CPU times: user 903 ms, sys: 3.64 ms, total: 906 ms
Wall time: 907 ms
{'fraction_non_alphanumeric': 0.10418250950570342, 'fraction_numerical': 0.031685678073510776, 'mean_word_length': 1.9535928143712575, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '256263', 'license': 'MIT', 'n_tokens_mistral': 1387, 'n_tokens_neox': 1257, 'n_words': 349, 'path': 'notebooks/s1_cracks.ipynb', 'repo_name': 'Lamsie/rift', 'size': '3945'}