我需要分析一个坐标列表。该程序应“汇总”列表。
from PIL import Image
im = Image.open('map.png')
rgb_im = im.convert('RGB')
l = []
x = 0
y = 0
for y in range(im.size[1]):
for x in range(im.size[0]):
if sum(rgb_im.getpixel((x, y))) == 0:
a = [x, y]
l.append(a)
这将生成白色表面上带有多个黑色矩形的图像中所有黑色像素的坐标列表。输出是这样的:
[[599, 257], [600, 257], [601, 257], [602, 257], [603, 257], [604, 257], [605, 257], [606, 257], [599, 258], [600, 258], [601, 258], [602, 258], [603, 258], [604, 258], [605, 258], [606, 258], [599, 259], [600, 259], [601, 259], [602, 259], [603, 259], [604, 259], [605, 259], [606, 259], [599, 260], [600, 260], [601, 260], [602, 260], [603, 260], [604, 260], [605, 260], [606, 260], [599, 261], [600, 261], [601, 261], [602, 261], [603, 261], [604, 261], [605, 261], [606, 261], [599, 262], [600, 262], [601, 262], [602, 262], [603, 262], [604, 262], [605, 262], [606, 262], [599, 263], [600, 263], [601, 263], [602, 263], [603, 263], [604, 263], [605, 263], [606, 263], [622, 286], [623, 286], [624, 286], [625, 286], [626, 286], [627, 286], [622, 287], [623, 287], [624, 287], [625, 287], [626, 287], [627, 287], [622, 288], [623, 288], [624, 288], [625, 288], [626, 288], [627, 288], [622, 289], [623, 289], [624, 289], [625, 289], [626, 289], [627, 289], [622, 290], [623, 290], [624, 290], [625, 290], [626, 290], [627, 290], [622, 291], [623, 291], [624, 291], [625, 291], [626, 291], [627, 291]]
“摘要”应该是有关黑色矩形的信息。对于每个矩形,输出应为:[x坐标,y坐标,长度,高度],这需要原点的坐标。
在这种情况下:[[599, 257, 8, 7], [622, 287, 6, 6]]
我不知道是否应该使用数组或矩阵或完全不同的东西。我愿意接受想法。重要的部分是从这类图像中获取信息。
谢谢大家!
答案 0 :(得分:0)
您可以使用floodfill或connected components,也可以使用其他方法。
在这里我们将利用我们知道要寻找与x
和y
轴对齐的矩形的优势。
该算法在x和y方向上扫描每个给定像素的四个相邻像素,并确定它们是否是孤立的黑色矩形的一部分;如果是,则将像素添加到组件;如果没有发现新像素属于某个组件,则将下一个可用像素用作下一个组件的种子,依此类推。
从孤立的单个组件(黑色矩形)中,很容易找到边界框,并根据需要对其进行表示。
import tkinter as tk
def find_extent(points):
xmin = min(x for x, _ in points)
xmax = max(x for x, _ in points)
ymin = min(y for _, y in points)
ymax = max(y for _, y in points)
return(xmin, ymin, xmax, ymax)
def get_four_neighbors(point):
x, y = point
return (x, y+1), (x, y-1), (x+1, y), (x-1, y)
def isolate_components(points):
"""return connected components,
taking advantage that we are looking for rectangles
"""
components = []
points_ = set(tuple(point) for point in points)
while points_:
current_comp_head = points_.pop()
to_visit = [current_comp_head]
component = []
while to_visit:
current = to_visit.pop()
component.append(current)
for point in get_four_neighbors(current):
if point in points_:
to_visit.append(point)
points_.remove(point)
components.append(component)
return components
root = tk.Tk()
canvas = tk.Canvas(root, width=800, height=800)
canvas.pack(expand=True, fill=tk.BOTH)
points = [[599, 257], [600, 257], [601, 257], [602, 257], [603, 257], [604, 257], [605, 257], [606, 257], [599, 258], [600, 258], [601, 258], [602, 258], [603, 258], [604, 258], [605, 258], [606, 258], [599, 259], [600, 259], [601, 259], [602, 259], [603, 259], [604, 259], [605, 259], [606, 259], [599, 260], [600, 260], [601, 260], [602, 260], [603, 260], [604, 260], [605, 260], [606, 260], [599, 261], [600, 261], [601, 261], [602, 261], [603, 261], [604, 261], [605, 261], [606, 261], [599, 262], [600, 262], [601, 262], [602, 262], [603, 262], [604, 262], [605, 262], [606, 262], [599, 263], [600, 263], [601, 263], [602, 263], [603, 263], [604, 263], [605, 263], [606, 263], [622, 286], [623, 286], [624, 286], [625, 286], [626, 286], [627, 286], [622, 287], [623, 287], [624, 287], [625, 287], [626, 287], [627, 287], [622, 288], [623, 288], [624, 288], [625, 288], [626, 288], [627, 288], [622, 289], [623, 289], [624, 289], [625, 289], [626, 289], [627, 289], [622, 290], [623, 290], [624, 290], [625, 290], [626, 290], [627, 290], [622, 291], [623, 291], [624, 291], [625, 291], [626, 291], [627, 291]]
components = isolate_components(points)
summaries = []
for component in components:
summaries.append(find_extent(component))
for x, y in component:
canvas.create_rectangle(x, y, x, y, outline='blue', fill='blue')
for summary in summaries:
x0, y0, x1, y1 = summary
print(f'{x0}, {y0}, {x1-x0+1}, {y1-y0+1}')
canvas.create_rectangle(x0, y0, x1+1, y1+1, outline='green', width=2)
root.mainloop()
599, 257, 8, 7
622, 286, 6, 6
(画布的截图)