给出2张图片

时间:2015-04-27 20:59:55

标签: python numpy

有些随机创建给定2张图像的3D点

目标是从2个图像创建一组n个3D坐标(种子)。 n可以是100-1000点的任何地方。

我有2张纯黑白图像,其高度相同,宽度可变。图像的大小可以大到1000x1000像素。我将它们读成numpy数组并将rgb代码压平为1(黑色)和0(白色)。

以下是处理2张非常小的图片的示例:

In [6]: img1
Out[6]: 
array([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
       [1, 1, 0, 0, 0, 0, 0, 0, 1, 1],
       [1, 1, 0, 0, 0, 0, 0, 0, 1, 1],
       [1, 1, 0, 0, 0, 0, 0, 0, 1, 1],
       [1, 1, 0, 0, 0, 0, 0, 0, 1, 1],
       [1, 1, 0, 0, 0, 0, 0, 0, 1, 1],
       [1, 1, 0, 0, 0, 0, 0, 0, 1, 1],
       [1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]], dtype=uint8)

In [8]: img2
Out[8]: 
array([[0, 0, 0, 0, 0, 0, 1, 0, 0, 0],
       [0, 0, 0, 0, 1, 1, 1, 0, 0, 0],
       [0, 0, 0, 1, 1, 0, 0, 1, 0, 0],
       [0, 0, 1, 1, 0, 0, 0, 1, 0, 0],
       [1, 1, 0, 0, 0, 0, 0, 0, 1, 1],
       [1, 1, 0, 0, 0, 0, 0, 0, 1, 1],
       [0, 0, 1, 0, 0, 0, 1, 1, 0, 0],
       [0, 0, 1, 0, 0, 1, 1, 0, 0, 0],
       [0, 0, 0, 1, 1, 1, 0, 0, 0, 0],
       [0, 0, 0, 1, 0, 0, 0, 0, 0, 0]], dtype=uint8)

接下来,我创建一个索引数组来映射每个图像的黑色像素的所有位置,如下所示:

In [10]: np.transpose(np.nonzero(img1))
Out[10]: 
array([[0, 0],
       [0, 1],
       [0, 2],
       [0, 3],
       [0, 4],
       [0, 5],
       [0, 6],
       ...

然后我想将每个图像的每个2D黑色像素扩展到3D空间。在那些3D点相交的地方,我想随机抓取n个3D字体(种子)。此外,作为一种增强功能,如果我可以将这些3d点在3d空间中稍微均匀地分散以避免“聚类”,那就更好了。有黑色像素密度较大的区域。但我还没有能够绕过这个过程。

这是设置的可视化:

line up images extrude image intersecting images

我在下面尝试的内容似乎适用于非常小的图像,但随着图像变大而减速停止。瓶颈似乎发生在我分配common_points的地方。

img1_array = process_image("Images/nhx.jpg", nheight)
img2_array = process_image("Images/ku.jpg", nheight)

img1_black = get_black_pixels(img1_array)
img2_black = get_black_pixels(img2_array)

# create all img1 3D points:
img1_3d = []
z1 = len(img2_array[1])  # number of img2 columns

for pixel in img1_black:
    for i in range(z1):
        img1_3d.append((pixel[0], pixel[1], i))  # (img1_row, img1_col, img2_col)

# create all img2 3D points:
img2_3d = []
z2 = len(img1_array[1])  # number of img1 columns

for pixel in img2_black:
    for i in range(z2):
        img2_3d.append((pixel[0], pixel[1], i))  # (img2_row, img2_col, img1_col)

# get all common 3D points
common_points = [x for x in img1_3d if x in img2_3d]

# get num_seeds number of random common_points
seed_indices = np.random.choice(len(common_points), num_seeds, replace=False)

seeds = []
for index_num in seed_indices:
    seeds.append(common_points[index_num])

问题:

  • 如何避免瓶颈?我还没有能够提出一个笨拙的解决方案。
  • 一般来说,我是如何编写这个更好的解决方案吗?
  • 关于如何在一定程度上均匀分散种子的任何想法?

更新编辑

根据Luke的算法,我提出了以下工作代码。这是正确的实施吗?这可以改进吗?

img1_array = process_image("Images/John.JPG", 500)
img2_array = process_image("Images/Ryan.jpg", 500)

img1_black = get_black_pixels(img1_array)
# img2_black = get_black_pixels(img2_array)

density = 0.00001
seeds = []

for img1_pixel in img1_black:
    row = img1_pixel[0]

    img2_row = np.array(np.nonzero(img2_array[row]))  # array of column numbers where there is a black pixel

    if np.any(img2_row):
        for img2_col in img2_row[0]:
            if np.random.uniform(0, 1) < density:
                seeds.append([row, img1_pixel[1], img2_col])

1 个答案:

答案 0 :(得分:0)

瓶颈是因为您将“苹果”阴影区域中的每个3D点与“橙色”阴影区域中的每个3D点进行比较,这是大量的比较。只需查看同一行中的点,您就可以通过imgHeight加速它。您还可以通过将img2_3d存储为集合而不是列表来加快速度,因为在集合上调用“in”要快得多(它是O(1)操作而不是O(n)操作)。

但是,最好完全避免制作所有3D点的列表。这是一个解决方案:

  1. 选择任意密度参数,将其命名为“密度”。尝试使用密度= 0.10填充10%的交点。
  2. 对于Apple中的每个黑色像素,循环遍历橙色的同一行中的黑色像素。如果(random.uniform(0,1)&lt; Density),在(applex,orangex,row)或者坐标系的正确排列处创建一个3D点。
  3. 该算法将均匀采样,因此具有更多黑色的3D区域将具有更多样本。如果我理解你的最后一个问题,你想在黑色较少的区域采样更密集(虽然我不知道为什么)。要做到这一点,你可以:

    1. 对两个图像的反转进行高斯模糊(OpenCV具有此功能),并且每次乘以0.9并加0.1。现在,您的图像具有更高的值,其中图像更白。
    2. 执行上述算法,但对于步骤2中的每个像素对,请设置Density = blurredOrangePixel * blurredApplePixel。因此,白色区域的选择密度会更高。
    3. 我会首先尝试基本算法;我觉得它看起来会更好。