简体   繁体   English

在布尔的二维列表(Python)中找到最左边和最右边的单元格为True

[英]Finding the leftmost and the rightmost cell that is True in a 2d-list of booleans (Python)

I have a 2d-array (28 x 28) that has boolean values. 我有一个具有布尔值的2d数组(28 x 28)。

array([[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, 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, 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, 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, False, False, False, False, False, False, False,
        False],
       [False, False, False, False, False, False, False, False, False,
        False, False, False, False, False, False, False,  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,  True,  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,  True,  True,  True,  True,
         True,  True, False, False, False, False, False, False, False,
        False],
       ...

This represents an image of a digit. 这代表一个数字的图像。 In order to stretch this image so that the horizontal and vertical range of ink pixels runs the full horizontal/vertical range of the box. 为了拉伸此图像,以便墨水像素的水平和垂直范围运行在框的整个水平/垂直范围内。

Below are the steps that I am trying to take: 以下是我要采取的步骤:

1. Find the leftmost (x_min) and the rightmost (x_max) pixels that have ink (after thresholding). 
2. Find the topmost (y_min) and bottom-most (y_max) pixels similarly. 
3. Find the centerpoint (x,y) by taking the mean of x_min and x_max and y_min and y_max respectively. 
4. Now, the 20x20 bounding is defined as img[y_center-10 : y_center + 10, x_center-10:x_center+10]

I tried to do Step 1 in a naive way, just iterating all pixels, but I know that is not the best way. 我尝试以幼稚的方式执行Step 1 ,只是迭代所有像素,但是我知道这不是最好的方法。 What is the best way to find the left and rightmost pixel that is True ? 找到最左端和最右端像素为True的最佳方法是什么?

You can use the function index, which returns the first index of the value you search for: 您可以使用函数索引,该函数返回您搜索的值的第一个索引:

eg 例如

array = ([False, False, True, True, False])
print(array.index(True))

Returns 返回

2

You can reverse the array to find the last one, by adding: 您可以通过添加以下内容来反转数组以找到最后一个数组:

array.reverse();
print(array.index(True))

Which returns 哪个返回

1

However, reverse is very expensive operation for what you need. 但是,反向操作非常昂贵,无法满足您的需求。

Will this work for you? 这对您有用吗? not most efficient, but works. 并非最有效,但可行。 the idea is to remove rows and columns that's all False, so you get your 'cropped' digit. 这个想法是删除所有为False的行和列,这样您就可以得到“裁剪的”数字。

import pandas as pd

img = np.array([[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, 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, 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, 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, False, False, False, False, False, False, False,
        False],
       [False, False, False, False, False, False, False, False, False,
        False, False, False, False, False, False, False,  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,  True,  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,  True,  True,  True,  True,
         True,  True, False, False, False, False, False, False, False,
        False]])

img = pd.DataFrame(img)
img.replace(False,np.nan, inplace = True)
newimage = img.dropna(axis = 0, how = 'all')
newimage = newimage.dropna(axis = 1, how = 'all')
newimage.T.values
array = [[False, False, False, False],
         [False, False, False, False],
         [True , False, False, False],
         [False, False, False, False]]

print('left: ')
print(min([x.index(True) if True in x else 100 for x in array]))

print('right: ')
print(min([x[::-1].index(True) if True in x else 100 for x in array]))

print('top')
print([any(x) for x in array].index(True))

print('bottom')    
print([any(x) for x in array[::-1]].index(True))

prints 版画

left: 
0
right: 
3
top
2
bottom
1

Side notes: 旁注:

  • I used 100 for left/right in case there is no True at all in a row. 如果连续没有True,我将100用作左/右。
  • If there is a chance for no True value at all in the entire matrix, conditions for top and bottom have to be changed slightly. 如果整个矩阵中根本没有True值,则顶部和底部的条件必须稍作更改。
  • ::-1 iterates the list in reverse order ::-1以相反的顺序迭代列表
  • any checks for the occurrence of a non 0/empty/False value. any检查是否存在非0 /空/ False值。
  • min checks for the minimum value of a list min检查列表的最小值
  • [...] is called list comprehension in case you want to find more about it [...]称为列表理解,如果您想找到更多关于它的信息

With your values I get: 用您的价值观,我得到:

left:
14
right:
8
top:
4
bottom:
0

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM