我已经将两个图像转换为numpy数组
image1Array
image2Array
这两个图像都已转换为灰度,因此只有0
或255
个值。
在两个示例中,顶部(和底部)都有很多白色行:
[255 255 255 255 .... 255 255 255 255]
我相信我所说的“行”实际上是一个数组。我是使用Numpy的新手。因此,图像中的每一行都有一个数组,并且该行中的每个像素都用0
或255
表示。
如何找到包含黑色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的两倍。
答案 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)
plot_times([georgy_solution, yodish_solution],
np.arange(200, 10000, 800),
repeats=1)
1 参见How to pad numpy array with zeros中的示例。
2 How to turn a boolean array into index array in numpy。