使用numpy和像素位置查找图像的高度和宽度

时间:2018-10-22 13:49:51

标签: python numpy

我已经将两个图像转换为numpy数组

image1Array

Image 1

image2Array

Image 2

这两个图像都已转换为灰度,因此只有0255个值。

在两个示例中,顶部(​​和底部)都有很多白色行:

[255 255 255 255 .... 255 255 255 255]

我相信我所说的“行”实际上是一个数组。我是使用Numpy的新手。因此,图像中的每一行都有一个数组,并且该行中的每个像素都用0255表示。

如何找到包含黑色0像素的第一行和包含黑色0像素的最后一行?我应该可以用它来计算高度。在这些示例中,该数字应大致相同。

我相信numpy.where(image1Array == 0)[0]将返回每个黑色像素的行; min()max()似乎正是我想要的,但我不确定。

相反,如何找到每个图像的宽度?在这些示例中,Image 2的宽度应大于Image 1

编辑

我认为我所需要的只是这样:

高度(黑色像素的第一行与黑色像素的最后一行之差):

(max(numpy.where(image1Array == 0)[0])) - (min(numpy.where(image1Array == 0)[0]))

宽度(黑色像素的最低列值与黑色像素的最高列值之差):

(max(numpy.where(image1Array == 0)[1])) - (min(numpy.where(image1Array == 0)[1]))

到目前为止,我的测试表明这是正确的。比较上面示例中的两个图像,它们的高度相等,而image2Array的宽度是image1Array的两倍。

2 个答案:

答案 0 :(得分:1)

这是一个应该与python 2或python 3一起使用的脚本。如果您使用IPython或jupyter,则“ magic” %pylab会为您完成所有导入,并且您不需要所有的{{1 }}语句。这些声明之后,我们将创建一个图像,就像您发布的图像一样。

from...

from __future__ import print_function # makes script work with python 2 and python 3 from matplotlib.pyplot import show, imshow, imread from matplotlib.mlab import find from numpy import zeros, int8, sum img1 = zeros((256, 256), dtype=int8) img1[50:200, 100:150] = 100 imshow(img1) show() # You don't need this call if you are using ipython or jupyter # You now see a figure like the first one you posted print('Axis 0 blob limits', find(sum(img1, axis=0) != 0)[[0, -1]]) print('Axis 1 blob limits', find(sum(img1, axis=1) != 0)[[0, -1]]) 函数与sum的显式说明一起使用会使它沿给定方向返回总和。 axis函数返回条件为true的所有索引的数组,在这种情况下,“列或行的和为零?”最后,切片find选择找到的第一列和最后一列。

如果图像没有行或列全为零,则[0, -1]返回一个空数组,索引尝试find引发一个[0, -1]。如果在其周围包裹一个IndexError块,就可以使错误情况更加美观。

答案 1 :(得分:1)

您想要这样的东西:

mask = x == 0  # or `x != 255` where x is your array

columns_indices = np.where(np.any(mask, axis=0))[0]
rows_indices = np.where(np.any(mask, axis=1))[0]

first_column_index, last_column_index = columns_indices[0], columns_indices[-1]
first_row_index, last_row_index = rows_indices[0], rows_indices[-1]

说明:

让我们使用np.pad 1

创建一个示例数组
import numpy as np


x = np.pad(array=np.zeros((3, 4)), 
           pad_width=((1, 2), (3, 4)),
           mode='constant',
           constant_values=255)
print(x)

[[255. 255. 255. 255. 255. 255. 255. 255. 255. 255. 255.]
 [255. 255. 255.   0.   0.   0.   0. 255. 255. 255. 255.]
 [255. 255. 255.   0.   0.   0.   0. 255. 255. 255. 255.]
 [255. 255. 255.   0.   0.   0.   0. 255. 255. 255. 255.]
 [255. 255. 255. 255. 255. 255. 255. 255. 255. 255. 255.]
 [255. 255. 255. 255. 255. 255. 255. 255. 255. 255. 255.]]

从这里我们可以像这样简单地得到一个boolean mask array零元素:

mask = x == 0
print(mask)

[[False False False False False False False False False False False]
 [False False False  True  True  True  True False False False False]
 [False False False  True  True  True  True False False False False]
 [False False False  True  True  True  True False False False False]
 [False False False False False False False False False False False]
 [False False False False False False False False False False False]]

现在,我们可以使用np.any来获取那些至少有一个零元素的行。
对于列:

print(np.any(mask, axis=0))
>>> [False False False  True  True  True  True False False False False]

以及行:

print(np.any(mask, axis=1))
>>> [False  True  True  True False False]

现在我们只需要将布尔数组转换为索引数组 2

columns_indices = np.where(np.any(mask, axis=0))[0]
print(columns_indices)
>>> [3 4 5 6]

rows_indices = np.where(np.any(mask, axis=1))[0]
print(rows_indices)
>>> [1 2 3]

从这里获取第一行和最后一行的行/列索引非常简单:

first_column_index, last_column_index = columns_indices[0], columns_indices[-1]
first_row_index, last_row_index = rows_indices[0], rows_indices[-1]

时间:
我使用以下代码计算时序并绘制时序:Plot timings for a range of inputs
将我的版本与您的版本进行比较,但重构如下:

indices = np.where(x == 0)
first_row_index, last_row_index = indices[0][0], indices[0][-1]
first_column_index, last_column_index = indices[1][0], indices[1][-1]
plot_times([georgy_solution, yodish_solution],
           np.arange(10, 200, 5), 
           repeats=500)

enter image description here

plot_times([georgy_solution, yodish_solution],
           np.arange(200, 10000, 800), 
           repeats=1)

enter image description here


1 参见How to pad numpy array with zeros中的示例。
2 How to turn a boolean array into index array in numpy