Skip to content

Instantly share code, notes, and snippets.

@brianlan
Last active February 9, 2018 16:14
Show Gist options
  • Save brianlan/88aa08660fa42993145909b8a3dea4b2 to your computer and use it in GitHub Desktop.
Save brianlan/88aa08660fa42993145909b8a3dea4b2 to your computer and use it in GitHub Desktop.
Script that cuts a line into small pieces
import numpy as np
import cv2
import matplotlib.pyplot as plt
def linear_transform(x, src_range=(360, 719), dest_range=(16, 60)):
src_width, dest_width = src_range[1] - src_range[0], dest_range[1] - dest_range[0]
return dest_range[1] - (src_range[1] - x) / src_width * dest_width
def norm2(x):
return np.linalg.norm(x, ord=2)
def cut(start, end, intensity=1, min_y=360):
xy_delta = np.array([end[0] - start[0], end[1] - start[1]])
dir_vec = (end - start) / norm2(end - start)
dest_range = (linear_transform(end[1]), linear_transform(start[1]))
dest_width = dest_range[1] - dest_range[0]
moves = []
cur_pt = start.copy().astype(np.float_)
centers = np.array([]).reshape(-1, 2)
centers = np.vstack((centers, cur_pt.reshape(-1, 2)))
for i in range(25):
step_pix = (dest_range[1] - norm2(cur_pt - start) / norm2(xy_delta) * dest_width)
moves.append(step_pix)
cur_pt += dir_vec * step_pix / intensity
centers = np.vstack((centers, cur_pt.reshape(-1, 2)))
if cur_pt[1] <= min_y:
break
step_pix = (dest_range[1] - norm2(cur_pt - start) / norm2(xy_delta) * dest_width)
moves.append(step_pix)
return centers, moves
def test_cutter():
start, end = np.array([400, 700]), np.array([640, 360])
centers, moves = cut(start, end, intensity=1)
im = np.zeros((720, 1280, 3))
cv2.line(im, tuple(start), tuple(end), (0, 0, 255), 1)
for c, m in zip(centers, moves):
piece = [c[0] - m / 2, c[1] - m / 2, c[0] + m / 2, c[1] + m / 2]
cv2.rectangle(im, (int(piece[0]), int(piece[1])), (int(piece[2]), int(piece[3])), (0, 255, 0), 1)
plt.imshow(im, interpolation='bilinear');
plt.show()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment