python计算两点间距离,在Python中计算位图中两点之间的最短路径

I have a black and white bitmap image shown here:

bY8cN.png

The image size is 200,158.

I want to pick two points that fall on the white path and calculate the shortest distance between those two points following only the white pixels. I am not sure how to approach this problem. I want to create a function that I call with 2 sets of x,y coordinates and it returns the number of pixels following the shortest route along the white pixels only.

Any pointers would be greatly appreciated.

解决方案

As stated in the comments, this problem can be reduced to Dijkstra.

The key concept behind the solution is to represent the image as a graph and then use a pre-made implementation of the shortest-path algorithm.

Firstly, observe a naive representation of an image of size 4x4:

T F F T

T T F T

F T T F

T T T T

Where T is a white dot and F is a black one. In this case, a path is a set of moves between adjacent white points.

Assuming a graph would be a set of nodes {1, 2, ..., 16}, we can map every point (i, j) to the number i * 4 + j. In the graph, the edges are a reflection of neighboring points, meaning that if (i1, j1) and (i2, j2) are adjacent in the image, then i1 * 4 + j1 and i2 * 4 + j2 are adjacent in the graph.

At this point, we have a graph on which we can compute the shortest path.

Luckily, python provides easy implementation to the image loading and to the shortest path implementation. The following code handles the path computation the visualizes the result:

import itertools

from scipy import misc

from scipy.sparse.dok import dok_matrix

from scipy.sparse.csgraph import dijkstra

# Load the image from disk as a numpy ndarray

original_img = misc.imread('path_t_image')

# Create a flat color image for graph building:

img = original_img[:, :, 0] + original_img[:, :, 1] + original_img[:, :, 2]

# Defines a translation from 2 coordinates to a single number

def to_index(y, x):

return y * img.shape[1] + x

# Defines a reversed translation from index to 2 coordinates

def to_coordinates(index):

return index / img.shape[1], index % img.shape[1]

# A sparse adjacency matrix.

# Two pixels are adjacent in the graph if both are painted.

adjacency = dok_matrix((img.shape[0] * img.shape[1],

img.shape[0] * img.shape[1]), dtype=bool)

# The following lines fills the adjacency matrix by

directions = list(itertools.product([0, 1, -1], [0, 1, -1]))

for i in range(1, img.shape[0] - 1):

for j in range(1, img.shape[1] - 1):

if not img[i, j]:

continue

for y_diff, x_diff in directions:

if img[i + y_diff, j + x_diff]:

adjacency[to_index(i, j),

to_index(i + y_diff, j + x_diff)] = True

# We chose two arbitrary points, which we know are connected

source = to_index(14, 47)

target = to_index(151, 122)

# Compute the shortest path between the source and all other points in the image

_, predecessors = dijkstra(adjacency, directed=False, indices=[source],

unweighted=True, return_predecessors=True)

# Constructs the path between source and target

pixel_index = target

pixels_path = []

while pixel_index != source:

pixels_path.append(pixel_index)

pixel_index = predecessors[0, pixel_index]

# The following code is just for debugging and it visualizes the chosen path

import matplotlib.pyplot as plt

for pixel_index in pixels_path:

i, j = to_coordinates(pixel_index)

original_img[i, j, 0] = original_img[i, j, 1] = 0

plt.imshow(original_img)

plt.show()

f3403b9e459d6a0ad0626202a8645ad9.png

Disclaimer:

I have no experience in image processing, so I'd suspect every step in the solution.

The solution assumes a very naive adjacency-predicate. There're probably some better approaches in computetional geometry for this part.

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值