def polyline2coords(points):
"""
Return row and column coordinates for a polyline.
>>> rr, cc = polyline2coords([(0, 0), (2, 2), (2, 4)])
>>> list(rr)
[0, 1, 2, 2, 3, 4]
>>> list(cc)
[0, 1, 2, 2, 2, 2]
:param list of tuple points: Polyline in format [(x1,y1), (x2,y2), ...]
:return: tuple with row and column coordinates in numpy arrays
:rtype: tuple of numpy array
"""
coords = []
for i in range(len(points) - 1):
xy = list(map(int, points[i] + points[i + 1]))
coords.append(skd.line(xy[1], xy[0], xy[3], xy[2]))
return [np.hstack(c) for c in zip(*coords)]
python类line()的实例源码
def LineKernel(dim, angle, linetype):
kernelwidth = dim
kernelCenter = int(math.floor(dim/2))
angle = SanitizeAngleValue(kernelCenter, angle)
kernel = np.zeros((kernelwidth, kernelwidth), dtype=np.float32)
lineAnchors = lineDict.lines[dim][angle]
if(linetype == 'right'):
lineAnchors[0] = kernelCenter
lineAnchors[1] = kernelCenter
if(linetype == 'left'):
lineAnchors[2] = kernelCenter
lineAnchors[3] = kernelCenter
rr,cc = line(lineAnchors[0], lineAnchors[1], lineAnchors[2], lineAnchors[3])
kernel[rr,cc]=1
normalizationFactor = np.count_nonzero(kernel)
kernel = kernel / normalizationFactor
return kernel
def main():
"""Create a noisy line image, recover the line via hough transform and
plot an unnoise image with that line."""
# generate example image (noisy lines)
img = np.zeros((128, 128))
for y in range(12, 120):
img[y, y] = 1
for y in range(40, 75):
img[y, 12] = 1
for x in range(16, 64):
img[int(10 + x*0.2), x] = 1
img = (img * 100) + np.random.binomial(80, 0.5, (img.shape))
accumulator, local_maxima, img_hough = hough(img, 5)
util.plot_images_grayscale(
[img, accumulator, local_maxima, img_hough],
["Image", "Accumulator content", "Local Maxima", "Line from Hough Transform"]
)
def ccw(a,b,c):
ax, ay = a
bx, by = b
cx, cy = c
return (cy-ay) * (bx-ax) > (by-ay) * (cx-ax)
# Return true if line segments AB and CD intersect
def ccw(a,b,c):
ax, ay = a
bx, by = b
cx, cy = c
return (cy-ay) * (bx-ax) > (by-ay) * (cx-ax)
# Return true if line segments AB and CD intersect
def getRandomMotionBlurMask(extent):
X = makeRandomWalkCurve(40, 20, 2)
Y = smoothCurve(X, 20)
Y = Y - np.mean(Y, 0)[None, :]
Y = Y/np.max(Y, 0)
Y = Y*extent
theta = np.random.rand()*2*np.pi
Y[:, 0] = Y[:, 0] + np.cos(theta)*np.linspace(0, extent, Y.shape[0])
Y[:, 1] = Y[:, 1] + np.sin(theta)*np.linspace(0, extent, Y.shape[0])
D = np.sum(Y**2, 1)[:, None]
D = D + D.T - 2*Y.dot(Y.T)
D[D < 0] = 0
D = 0.5*(D + D.T)
D = np.sqrt(D)
Y = Y*extent/np.max(D)
Y = Y - np.mean(Y, 0)[None, :]
Y = Y - np.min(Y)
I = np.zeros((extent, extent))
for i in range(Y.shape[0]-1):
c = [Y[i, 0], Y[i, 1], Y[i+1, 0], Y[i+1, 1]]
c = [int(np.round(cc)) for cc in c]
rr, cc = line(c[0], c[1], c[2], c[3])
rr = [min(max(rrr, 0), extent-1) for rrr in rr]
cc = [min(max(ccc, 0), extent-1) for ccc in cc]
I[rr, cc] += 1.0
I = I/np.sum(I)
return (Y, I)
def get_inner_paths(grid, regions):
"""Create 1 pixel width paths connecting the loose ends surrounding the
regions to their center. Each region is defined by its top-left
and bottom-right corners points expressed in [x, y] coordinates. Grid must
be a black and white image"""
color = 255 # white
height, width = grid.shape
inner_paths = sparse.lil_matrix(grid.shape, dtype=np.uint8)
for (cx1, cy1), (cx2, cy2) in regions:
center = (cx1 + cx2) // 2, (cy1 + cy2) // 2
cx1_min = max(cx1 - 1, 0)
cy1_min = max(cy1 - 1, 0)
cx2_max = min(cx2 + 1, width - 1)
cy2_max = min(cy2 + 1, height - 1)
borders = (
# border, border_x, border_y, border_horizontal
(grid[cy1_min, cx1_min:cx2_max], cx1_min, cy1, True), # top
(grid[cy2_max, cx1_min:cx2_max], cx1_min, cy2, True), # bottom
(grid[cy1_min:cy2_max, cx1_min], cx1, cy1_min, False), # left
(grid[cy1_min:cy2_max, cx2_max], cx2, cy1_min, False), # right
)
for border, border_x, border_y, border_horizontal in borders:
for border_step in np.argwhere(border).ravel():
if border_horizontal:
point = border_x + border_step, border_y
else:
point = border_x, border_y + border_step
line = draw.line(point[1], point[0], center[1], center[0])
inner_paths[line] = color
return inner_paths.tocsc()
def gridsize(original, segdst=SEGMENT_DISTANCE):
global im
# read the image from disk
im = original.copy()
add_image('Original')
# edge detection
im = sobel(im)
# blurring
im = filters.gaussian(im, sigma=5)
# thresholding: convert to binary rage
loc = threshold_local(im, 31)
im = im > loc
if (DEBUG): add_image('Threshold')
# detect straight lines longer than 150px
segs = probabilistic_hough_line(
im,
threshold=30,
line_length=250,
line_gap=7)
#segs = [seg for seg in segs if vertical(seg)]
# draw the segments
im[:] = 0 # set image to black
for seg in segs:
((x1, y1), (x2, y2)) = seg
rr,cc = draw.line(y1,x1,y2,x2)
im[rr, cc] = 1
if (DEBUG): add_image('Hough Lines')
hh, vv = process_segments(segs)
# draw the segments
im[:] = 0 # set image to black
num = 0
for yy in hh:
for yyy in yy:
(_,y),_ = yyy
rr,cc = draw.line(y,0,y,999)
im[rr, cc] = 1
num += 1
for xx in vv:
for xxx in xx:
(x,_),_ = xxx
rr,cc = draw.line(0,x,999,x)
im[rr, cc] = 1
num += 1
if (DEBUG):
add_image('Filtered Segs')
# finally save the result
displ()
return len(vv)-1, len(hh)-1
def draw_keypoints(img, keypoints, draw_prob):
"""Draws for each keypoint a circle (roughly matching the sigma of the scale)
with a line for the orientation.
Args:
img The image to which to add the keypoints (gets copied)
keypoints The keypoints to draw
draw_prob Probability of drawing a keypoint (the lower the less keypoints are drawn)
Returns:
Image with keypoints"""
height, width = img.shape
img = np.copy(img)
# convert from grayscale image to RGB so that keypoints can be drawn in red
img = img[:, :, np.newaxis]
img = np.repeat(img, 3, axis=2)
for (y, x), orientation, scale_idx, scale_size, kp_type in keypoints:
if draw_prob < 1.0 and random.random() <= draw_prob:
# draw the circle
radius = int(scale_size)
rr, cc = draw.circle_perimeter(y, x, radius, shape=img.shape)
img[rr, cc, 0] = 1.0
img[rr, cc, 1:] = 0
# draw orientation
orientation = util.quantize(orientation, [-135, -90, -45, 0, 45, 90, 135, 180])
x_start = x
y_start = y
if orientation == 0:
x_end = x + radius
y_end = y
elif orientation == 45:
x_end = x + radius*(1/math.sqrt(2))
y_end = y + radius*(1/math.sqrt(2))
elif orientation == 90:
x_end = x
y_end = y + radius
elif orientation == 135:
x_end = x - radius*(1/math.sqrt(2))
y_end = y - radius*(1/math.sqrt(2))
elif orientation == 180:
x_end = x - radius
y_end = y
elif orientation == -135:
x_end = x - radius*(1/math.sqrt(2))
y_end = y - radius*(1/math.sqrt(2))
elif orientation == -90:
x_end = x
y_end = y - radius
elif orientation == -45:
x_end = x + radius*(1/math.sqrt(2))
y_end = y - radius*(1/math.sqrt(2))
x_end = np.clip(x_end, 0, width-1)
y_end = np.clip(y_end, 0, height-1)
rr, cc = draw.line(int(y_start), int(x_start), int(y_end), int(x_end))
img[rr, cc, 0] = 1.0
img[rr, cc, 1:] = 0
img = np.clip(img, 0, 1.0)
return img
def hough(img, nb_lines):
"""Applies the Hough Transformation to an image.
Args:
img The image
nb_lines The number of lines to search for.
Returns:
Accumulator image,
Local maxima in accumulator image,
image with detected lines"""
height, width = img.shape
magnitude = grad_magnitude(img)
mag_avg = np.average(magnitude)
max_d = math.sqrt(height**2 + width**2)
min_d = -max_d
alphas = np.linspace(0, np.pi, NB_QUANTIZATION_STEPS)
distances = np.linspace(min_d, max_d, NB_QUANTIZATION_STEPS)
accumulator = np.zeros((NB_QUANTIZATION_STEPS, NB_QUANTIZATION_STEPS))
for y in range(1, height-1):
for x in range(1, width-1):
if magnitude[y, x] > mag_avg:
for alpha_idx, alpha in enumerate(alphas):
distance = x * math.cos(alpha) + y * math.sin(alpha)
distance_idx = util.quantize_idx(distance, distances)
accumulator[alpha_idx, distance_idx] += 1
img_hough = np.zeros((height, width, 3))
img_hough[:, :, 0] = np.copy(img)
img_hough[:, :, 1] = np.copy(img)
img_hough[:, :, 2] = np.copy(img)
local_maxima = find_local_maxima(accumulator)
peaks_idx = get_peak_indices(local_maxima, nb_lines)
for value, (alpha_idx, distance_idx) in peaks_idx:
peak_alpha_rad = alphas[alpha_idx]
peak_distance = distances[distance_idx]
x0 = 0
x1 = width - 1
y0 = (peak_distance - 0 * np.cos(peak_alpha_rad)) / (np.sin(peak_alpha_rad) + 1e-8)
y1 = (peak_distance - (width-1) * np.cos(peak_alpha_rad)) / (np.sin(peak_alpha_rad) + 1e-8)
y0 = np.clip(y0, 0, height-1)
y1 = np.clip(y1, 0, height-1)
rr, cc = draw.line(int(y0), int(x0), int(y1), int(x1))
img_hough[rr, cc, 0] = 1
img_hough[rr, cc, 1] = 0
img_hough[rr, cc, 2] = 0
return accumulator, local_maxima, img_hough