地図画像データを読んで出発地点到着地点を設定し最短ルートを求める
Python のプログラム

出発地点到着地点 座標はY Xとしてください 色の指定はBgrとしてください
from PIL import Image, ImageFilter, ImageDraw
import numpy as np
import networkx as nx
import cv2
def preprocess_image(image_path, road_colors, road_tolerance, exclude_colors, exclude_tolerance):
image = cv2.imread(image_path)
mask = np.zeros(image.shape[:2], dtype=np.uint8)
# 道路と認識する色の範囲
for road_color in road_colors:
lower_bound = np.clip(road_color - road_tolerance, 0, 255)
upper_bound = np.clip(road_color + road_tolerance, 0, 255)
road_mask = cv2.inRange(image, lower_bound, upper_bound)
mask = cv2.bitwise_or(mask, road_mask)
# 除外する色の範囲
for exclude_color in exclude_colors:
exclude_lower = np.clip(exclude_color - exclude_tolerance, 0, 255)
exclude_upper = np.clip(exclude_color + exclude_tolerance, 0, 255)
exclude_mask = cv2.inRange(image, exclude_lower, exclude_upper)
mask[exclude_mask > 0] = 0
cv2.imwrite('masked_image.png', mask) # マスク画像を保存
return mask, image
def image_to_graph(image):
height, width = image.shape
graph = nx.grid_2d_graph(height, width)
for y in range(height):
for x in range(width):
if image[y, x] > 0: # 道路部分のみノードを追加
graph.add_node((y, x))
else:
graph.remove_node((y, x))
return graph
def find_shortest_path(graph, start, goal):
try:
path = nx.shortest_path(graph, source=start, target=goal)
except nx.NetworkXNoPath:
return None
return path
def draw_path(original_image, path, thickness=5):
for (y, x) in path:
cv2.circle(original_image, (x, y), thickness, (0, 0, 255), -1) # 赤色の太線で描画
return original_image
def main():
image_path = '2025-02-21_17h42_50.png' # マップの画像データ
road_colors = [
np.array([210, 210, 210]), # 一般的なグレーの道路色
np.array([237, 242, 231]), # 一般的なグレーの道路色
np.array([200, 200, 200]), # もう少し暗めのグレー
np.array([220, 220, 220]) # 明るめのグレー
]
road_tolerance = 20 # 道路とする色の許容範囲
exclude_colors = [
np.array([240, 229, 245]), # #F5F0E5のBGR値
np.array([247, 247, 248]) # #F8F7F7のBGR値
]
exclude_tolerance = 15 # 除外する色の許容範囲
start, goal = (47, 40), (453, 599) # 開始位置とゴール位置を指定 座標はY X
mask, original_image = preprocess_image(image_path, road_colors, road_tolerance, exclude_colors, exclude_tolerance)
graph = image_to_graph(mask)
if start not in graph or goal not in graph:
print("Start or goal is not a valid point on the map.")
return
path = find_shortest_path(graph, start, goal)
if path is None:
print("No path found.")
return
result_image = draw_path(original_image, path, thickness=5) # オリジナル画像に描画
cv2.imwrite('shortest_path.png', result_image)
print("Path saved as shortest_path.png")
if __name__ == "__main__":
main()
二極化
許容範囲を調整し道路を白くしてください

説明
このプログラムは、画像処理とグラフ理論を組み合わせて、地図画像内の道路部分を認識し、最短経路を見つけるためのものです。以下は、各関数の詳細な説明です:
preprocess_image
- 画像読み込み:
image_path
から画像を読み込みます。 - マスク生成: 画像と同じサイズのゼロマスクを作成します。
- 道路色マスクの適用:
road_colors
内の色に対して、それぞれの色の範囲(許容範囲内)を計算します。- 色範囲に応じたマスクを作成し、ゼロマスクに追加します。
- 除外色マスクの適用:
exclude_colors
内の色に対して、それぞれの色の範囲(許容範囲内)を計算します。- 色範囲に応じたマスクを作成し、ゼロマスクから該当部分を除外します。
- マスク画像を保存:
masked_image.png
として保存します。
image_to_graph
- グリッドグラフ生成: 画像の高さと幅を持つ2次元グリッドグラフを生成します。
- ノード追加と削除:
- マスク画像の各ピクセルに対して、値がゼロでない場合、グラフにノードを追加します。
- ゼロである場合、そのノードをグラフから削除します。
find_shortest_path
- 最短経路探索:
- グラフ内の開始ノード
start
からゴールノードgoal
までの最短経路を求めます。 - 経路が存在しない場合、
None
を返します。
draw_path
- 経路描画:
- 経路上の各ノードに対して、指定された太さ(
thickness
)で赤色の円を描画します。
main
- 画像パス: マップの画像データを読み込みます。
- 道路色と除外色の定義: 道路と認識する色、および除外する色を定義します。
- 開始位置とゴール位置を指定:
start
とgoal
の座標を設定します。 - 画像前処理:
preprocess_image
関数を呼び出してマスク画像とオリジナル画像を取得します。 - グラフ生成:
image_to_graph
関数を呼び出してマスク画像からグラフを生成します。 - 最短経路探索:
find_shortest_path
関数を呼び出して、開始位置からゴール位置までの最短経路を求めます。 - 経路描画:
draw_path
関数を呼び出して、オリジナル画像に経路を描画します。 - 結果画像の保存: 結果画像を
shortest_path.png
として保存します。
ColorColor Picker ユーティリティ
GitHub – martinchrzan/ColorPicker: Windows system-wide color picker
画像の座標を調べる
ペイントなどのグラフィックソフトで調べることが可能です
ディスカッション
コメント一覧
まだ、コメントがありません