55 lines
1.7 KiB
Python
55 lines
1.7 KiB
Python
import cv2
|
||
import numpy as np
|
||
|
||
def extract_building_coordinates(image_path):
|
||
# 加载图片
|
||
img = cv2.imread(image_path)
|
||
if img is None:
|
||
print("无法加载图片")
|
||
return
|
||
|
||
# 转换到灰度空间
|
||
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
|
||
|
||
# 针对 Google Maps 风格的建筑颜色进行阈值处理
|
||
# 建筑通常是特定的浅灰色 (约 230-245 之间)
|
||
# 我们通过 inRange 提取这个颜色区间
|
||
mask = cv2.inRange(gray, 220, 245)
|
||
|
||
# 进行形态学操作以去除细小噪声
|
||
kernel = np.ones((3, 3), np.uint8)
|
||
mask = cv2.morphologyEx(mask, cv2.MORPH_OPEN, kernel)
|
||
|
||
# 查找轮廓
|
||
# RETR_EXTERNAL 只查找最外层轮廓
|
||
# CHAIN_APPROX_TC89_KCOS 使用精度较高的近似算法
|
||
contours, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_TC89_KCOS)
|
||
|
||
buildings_data = []
|
||
|
||
for cnt in contours:
|
||
# 过滤掉面积过小的噪点
|
||
if cv2.contourArea(cnt) < 50:
|
||
continue
|
||
|
||
# 多边形拟合,epsilon 越小,顶点越密集,形状越精确
|
||
epsilon = 0.002 * cv2.arcLength(cnt, True)
|
||
approx = cv2.approxPolyDP(cnt, epsilon, True)
|
||
|
||
points = []
|
||
for point in approx:
|
||
x, y = point[0]
|
||
points.append((float(x), float(y)))
|
||
|
||
buildings_data.append(points)
|
||
|
||
# 输出结果
|
||
for i, building in enumerate(buildings_data):
|
||
print(f"# Building {i+1}")
|
||
for x, y in building:
|
||
print(f"{x}, {y}")
|
||
print() # 每个建筑间空一行
|
||
|
||
if __name__ == "__main__":
|
||
# 将 'nasa.jpg' 替换为你的文件名
|
||
extract_building_coordinates('nasa.png') |