Python 二维NumPy阵列中重叠矩形中心的求法
我有一个2D NumPy数组,其中有几个大小可变的可能重叠的矩形。如何计算每个矩形中心的坐标?在附图中,我的目标是计算红点的坐标 除表示矩形边框的像素值为1外,数组均为零。在示例图像中,黑色像素的值为零,白色像素的值为一Python 二维NumPy阵列中重叠矩形中心的求法,python,computational-geometry,Python,Computational Geometry,我有一个2D NumPy数组,其中有几个大小可变的可能重叠的矩形。如何计算每个矩形中心的坐标?在附图中,我的目标是计算红点的坐标 除表示矩形边框的像素值为1外,数组均为零。在示例图像中,黑色像素的值为零,白色像素的值为一 这取决于你掌握的信息 如果有左下角和右上角的坐标,则中心将是两者之间的平均值 如果有一个角和尺寸标注,则可以使用一半尺寸标注从角移动到中心 import numpy as np # Bottom left and top right bl = np.array([1, 0])
这取决于你掌握的信息 如果有左下角和右上角的坐标,则中心将是两者之间的平均值 如果有一个角和尺寸标注,则可以使用一半尺寸标注从角移动到中心
import numpy as np
# Bottom left and top right
bl = np.array([1, 0])
tr = np.array([2, 1])
center = np.mean((bl, tr), axis = 0)
# Bottom left corner and dimensions
bl = np.array([1, 0])
dimensions = np.array([1, 1])
center = bl + 0.5 * dimensions
从0,0角开始逐行搜索图像。遇到的第一个非零像素必须是矩形的左上角。沿着像素向右移动,直到到达右上角,然后向下,然后向左,最后再次向上移动。如果你最后的像素与你开始的像素相同,那就是一个完整的矩形 跟踪被标识为矩形一部分的所有像素,这样就不会再次跟踪它们 编辑: 该算法的一个要求是不同矩形的角不相互接触。对于3像素宽的边框,该算法将跟踪矩形的外部像素。它还将尝试在外部矩形内跟踪两个1像素宽的矩形,但这些矩形将被丢弃
import numpy as np
import matplotlib.pyplot as plt
def search_rectangles(img):
"""Search rectangles in 2D boolean image array.
Return: rectangles - array shape (n, 3, 2) for n rectangles.
rectangles[i, 0, :] represents the top left corner [i, j]
recnangles[i, 1, :] represents the bottom right corner [i, j]
rectangles[i, 2, :] represents the center (rounded as integer).
"""
seen = np.zeros_like(img, dtype=np.bool)
ny, nx = img.shape
rectangles = []
for i in range(ny):
for j in range(nx):
if img[i, j] == 0 or seen[i, j]:
continue
# new rectangle pixel; assume it's the top left corner.
# follow it clockwise.
didjs = [(0, 1), (1, 0), (0, -1), (-1, 0)]
ii, jj = i, j
corners = np.array([[i, j], [-1, -1], [-1, -1]])
for k, (di, dj) in enumerate(didjs):
if k == 2:
# opposite corner
corners[1, :] = [ii, jj]
while img[ii+di, jj+dj]:
ii += di
jj += dj
seen[ii, jj] = True
if (ii, jj) == (i, j):
corners[2, :] = np.around(corners[:2, :].mean(axis=1))
rectangles.append(corners)
return np.array(rectangles)
def draw_rectangle(img, i0, i1, j0, j1):
"""Draw rectangle with 3px border width."""
img[i0:i1+1, j0:j0+3] = 1
img[i0:i1+1, j1-2:j1+1] = 1
img[i0:i0+3, j0:j1+1] = 1
img[i1-2:i1+1, j0:j1+1] = 1
# test case
img = np.zeros((100, 150), dtype=np.uint8)
draw_rectangle(img, 10, 40, 20, 50)
draw_rectangle(img, 15, 34, 25, 44)
draw_rectangle(img, 20, 70, 70, 90)
draw_rectangle(img, 50, 90, 75, 120)
plt.close('all')
plt.imshow(img)
print(search_rectangles(img))
输出:
阵列是什么样子的?只是角坐标?请张贴代码。你如何知道,在你的图片中,看起来像两个相交的矩形,实际上是否不是三个矩形?两个以上的矩形可以同时重叠吗?边可以在多个点上重叠吗?@dmuir这是个好点,我认为不可能确定这一点。然而,在我的应用程序中,任意选择两个矩形中的一个就足够了。@YvesDaoust是的,两个以上的矩形可以同时重叠。边缘当前为3像素宽,因此它们可以在多个点上重叠。
[[[ 10 20]
[ 40 50]
[ 15 45]]
[[ 15 25]
[ 34 44]
[ 20 39]]
[[ 20 70]
[ 70 90]
[ 45 80]]
[[ 50 75]
[ 90 120]
[ 62 105]]]