Slider captcha: matching the puzzle image

    bg_w, bg_h, bg_ch, bg_rows = decode_png(bg_path)
    bk_w, bk_h, bk_ch, bk_rows = decode_png(block_path)
    if bg_ch != 3:
        raise ValueError("background.png 需要是 RGB 图")
    if bk_ch != 4:
        raise ValueError("block.png 需要是 RGBA 图")

    bg_gray = to_gray(bg_rows, bg_ch)
    bk_gray = to_gray(bk_rows, bk_ch)
    bk_mask = alpha_mask(bk_rows, bk_ch)
    tpl_gray, tpl_mask = crop_by_mask(bk_gray, bk_mask)

    bg_edges = edge_map(bg_gray)
    tpl_edges = edge_map(tpl_gray)

    x, y, score = find_best_position(bg_edges, tpl_edges, tpl_mask)

    print(f"背景图尺寸: {bg_w}x{bg_h}")
    print(f"滑块图尺寸: {bk_w}x{bk_h}")
    print(f"缺口左上角坐标: ({x}, {y})")
    print(f"建议滑动距离(像素): {x}")
    print(f"匹配误差(越小越好): {score:.2f}")


if __name__ == "__main__":
    main()

How it works

In essence: treat the slider image as a template, slide it across the background image and compare, then take the position with the smallest error.

The reference implementation lives in
main.py

Step by step, matching the images you see above

  1. step_01 Grayscale
    Convert RGB to grayscale to cut down colour noise and keep only the brightness structure.

  2. step_02 Alpha mask
    From block.png 's alpha channel we take the valid pixels (opaque = 1, transparent = 0) so only meaningful areas are compared.

  3. step_03 Background edge map
    Apply a simple gradient to the grayscale background (difference against the left/upper pixel) to bring out the contours.

  4. step_04 Template edge map
    Run the same edge processing on the cropped slider template so both sides are compared on equal footing.

  5. Template matching (the key step)
    For every candidate (x,y) position in the background, compute the SSE error over the masked pixels:
    [
    score(x,y)=\frac{1}{N}\sum (bg_edge[y+py][x+px]-tpl_edge[py][px])^2
    ]
    Take the score position with the smallest value as the gap location.

  6. step_05 / step_06 Visualisation
    step_05 draw the matching box;step_06 overlay the slider semi-transparently on the matched position to verify the result visually.