Numpy -将小数组放在大数组的坐标上?

cu6pst1q  于 2024-01-08  发布在  其他
关注(0)|答案(4)|浏览(255)

下面是一个2D-numpy数组:

  1. matrix = np.zeros((250, 250))

字符串
现在,在不同的坐标上,我不仅要用一个更小的数组替换坐标值,还要用一个更小的数组替换它的局部邻域。作为示例性的替换,我们可以取一个菱形:

  1. import skimage.morphology
  2. star = skimage.morphology.diamond(3) # small array / replacement
  3. coords_r = np.random.randint(0, 250, 20) # row coordinates
  4. coords_c = np.random.randint(0, 250, 20) # column coordinates


我想出了以下相当草率的方法,并想知道是否有一个更简单/更优雅的解决方案。此外,如果两个对象足够接近,此方法将覆盖:

  1. max_r, max_c = matrix.shape
  2. obj = star
  3. half_obj = int((star.shape[0])/2)
  4. for r, c in zip(coords_r, coords_c):
  5. curr_obj = obj
  6. start_r = r-half_obj-1
  7. end_r = r+half_obj
  8. start_c = c-half_obj-1
  9. end_c = c+half_obj
  10. # Check if on corners
  11. if r-half_obj-1 < 0:
  12. start_r = 0
  13. curr_obj = curr_obj[-r:, :]
  14. if r+half_obj > matrix.shape[0]:
  15. end_r = max_r
  16. curr_obj = curr_obj[:max_r-start_r, :]
  17. if c-half_obj-1 < 0:
  18. start_c = 0
  19. curr_obj = curr_obj[:, -c:]
  20. if c+half_obj > matrix.shape[1]:
  21. end_c = max_c
  22. curr_obj = curr_obj[:, :max_c-start_c]
  23. matrix[start_r:end_r, start_c:end_c] = curr_obj


先谢了。

kwvwclae

kwvwclae1#

你需要更好地利用numpy切片。据我所知,两个随机数组coords_r, coords_c是你想要放置星星的中心坐标。我会
1.将这些转换为矩形裁剪坐标列表
1.在坐标上循环并将星星放置在每个切片中

  1. def center_to_bbox(coords, star_size):
  2. coords_x, coords_y = coords
  3. x1, y1, x2, y2 = coords_x - star_size, coords_y - star_size, coords_x + star_size + 1,
  4. coords_y + star_size + 1,
  5. bboxes =(x1, y1, x2, y2)
  6. return bboxes
  7. x_coords = np.random.randint(0, 250 - 3, 20)
  8. y_coords = np.random.randint(0, 250 - 3 , 20)
  9. x1, y1, x2, y2 = bboxes
  10. for x1_, y1_, x2_, y2_ in zip(x1, y1, x2, y2):
  11. matrix[y1_:y2_, x1_:x2_] = star

字符串
还请注意,您也可以减去星星的维度,这样就不必在以后的边界处进行补偿

展开查看全部
n9vozmp4

n9vozmp42#

看起来你可能想使用scipy sparse matrices。只需定义小矩阵并将它们添加到更大的矩阵中。lil_matrix似乎是你正在寻找的合适格式。
编辑:@iantonuk我在想下面的方法,它在添加/组装矩阵时效果很好,但在替换条目时效果不好。

  1. from scipy.sparse import coo_matrix
  2. data1 = ((1.0,2.0,3.0),([0,1,2],[0,1,2]))
  3. mat1 = coo_matrix(data1,shape=(3,3))
  4. print(mat1.todense())
  5. data2 = ((2.0,3.0),([1,2],[1,2]))
  6. mat2 = coo_matrix(data2,shape=(3,3))
  7. print(mat2.todense())
  8. mat3 = mat1 + mat2
  9. print(mat3.todense())

字符串

tp5buhyn

tp5buhyn3#

我问过类似的问题:Add small image to the canvas as numpy arrays
以下是我对你的问题的解决方案:

  1. matrix_size = 250
  2. star_size = 3
  3. matrix = np.ones((matrix_size, matrix_size))
  4. star = 1 - skimage.morphology.diamond(star_size)
  5. coords_r = np.random.randint(0, matrix_size, 20) # row coordinates
  6. coords_c = np.random.randint(0, matrix_size, 20) # column coordinates
  7. for r, c in zip(coords_r, coords_c):
  8. matrix[max(r - star_size, 0):r + star_size + 1, max(c - star_size, 0):c + star_size + 1] *= star[max(star_size - r, 0):star_size + matrix_size - r, max(star_size - c, 0):star_size + matrix_size - c]
  9. matrix = 1-matrix

字符串
这就是我得到的:

展开查看全部
lo8azlld

lo8azlld4#

以下是你可以用矢量化的方式轻松做到这一点:

  1. def put_rounds(image:np.array, ptsx, ptsy):
  2. xm1, x, xp1 = (ptsx-1,ptsx,ptsx+1)
  3. ym1, y, yp1 = (ptsy-1,ptsy,ptsy+1)
  4. #make a round, r=3 or diamond pattern or whatever you need
  5. ptsx3 = np.dstack((xm1, xm1, ptsx,xm1,ptsx, xp1, ptsx,xm1, xp1)).flatten()
  6. ptsy3 = np.dstack((ym1, yp1, ym1,ptsy,ptsy, ptsy,yp1, yp1, yp1)).flatten()
  7. #this at least 7.5-12 times faster then loops(at least 50+ times faster on torch)
  8. image[ptsy3, ptsx3] = np.array([255,255,0])

字符串

相关问题