Spaces:
Sleeping
Sleeping
File size: 3,410 Bytes
be5548b |
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 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
import math
import numpy as np
def downsample(img, factor):
"""
Downsample an image along both dimensions by some factor
"""
assert img.shape[0] % factor == 0
assert img.shape[1] % factor == 0
img = img.reshape([img.shape[0]//factor, factor, img.shape[1]//factor, factor, 3])
img = img.mean(axis=3)
img = img.mean(axis=1)
return img
def fill_coords(img, fn, color):
"""
Fill pixels of an image with coordinates matching a filter function
"""
for y in range(img.shape[0]):
for x in range(img.shape[1]):
yf = (y + 0.5) / img.shape[0]
xf = (x + 0.5) / img.shape[1]
if fn(xf, yf):
img[y, x] = color
return img
def rotate_fn(fin, cx, cy, theta):
def fout(x, y):
x = x - cx
y = y - cy
x2 = cx + x * math.cos(-theta) - y * math.sin(-theta)
y2 = cy + y * math.cos(-theta) + x * math.sin(-theta)
return fin(x2, y2)
return fout
def point_in_line(x0, y0, x1, y1, r):
p0 = np.array([x0, y0])
p1 = np.array([x1, y1])
dir = p1 - p0
dist = np.linalg.norm(dir)
dir = dir / dist
xmin = min(x0, x1) - r
xmax = max(x0, x1) + r
ymin = min(y0, y1) - r
ymax = max(y0, y1) + r
def fn(x, y):
# Fast, early escape test
if x < xmin or x > xmax or y < ymin or y > ymax:
return False
q = np.array([x, y])
pq = q - p0
# Closest point on line
a = np.dot(pq, dir)
a = np.clip(a, 0, dist)
p = p0 + a * dir
dist_to_line = np.linalg.norm(q - p)
return dist_to_line <= r
return fn
def point_in_circle(cx, cy, r):
def fn(x, y):
return (x-cx)*(x-cx) + (y-cy)*(y-cy) <= r * r
return fn
def point_in_circle_clip(cx, cy, r, theta_start=0, theta_end=-np.pi):
def fn(x, y):
if (x-cx)*(x-cx) + (y-cy)*(y-cy) <= r * r:
if theta_start < 0:
return theta_start > np.arctan2(y-cy, x-cx) > theta_end
else:
return theta_start < np.arctan2(y - cy, x - cx) < theta_end
return fn
def point_in_rect(xmin, xmax, ymin, ymax):
def fn(x, y):
return x >= xmin and x <= xmax and y >= ymin and y <= ymax
return fn
def point_in_triangle(a, b, c):
a = np.array(a)
b = np.array(b)
c = np.array(c)
def fn(x, y):
v0 = c - a
v1 = b - a
v2 = np.array((x, y)) - a
# Compute dot products
dot00 = np.dot(v0, v0)
dot01 = np.dot(v0, v1)
dot02 = np.dot(v0, v2)
dot11 = np.dot(v1, v1)
dot12 = np.dot(v1, v2)
# Compute barycentric coordinates
inv_denom = 1 / (dot00 * dot11 - dot01 * dot01)
u = (dot11 * dot02 - dot01 * dot12) * inv_denom
v = (dot00 * dot12 - dot01 * dot02) * inv_denom
# Check if point is in triangle
return (u >= 0) and (v >= 0) and (u + v) < 1
return fn
def point_in_quadrangle(a, b, c, d):
fn1 = point_in_triangle(a, b, c)
fn2 = point_in_triangle(b, c, d)
fn = lambda x, y: fn1(x, y) or fn2(x, y)
return fn
def highlight_img(img, color=(255, 255, 255), alpha=0.30):
"""
Add highlighting to an image
"""
blend_img = img + alpha * (np.array(color, dtype=np.uint8) - img)
blend_img = blend_img.clip(0, 255).astype(np.uint8)
img[:, :, :] = blend_img
|