我写了一份if-elif声明,我认为这不是很有效:
first_number = 1000
second_number = 700
switch = {
'upperRight': False,
'upperLeft': False,
'lowerRight': False,
'lowerLeft': False,
'middleLeft': False,
'middleRight': False,
'upperMiddle': False,
'lowerMiddle': False,
'middle': False
}
for i in range(first_number):
for j in range(second_number):
if pixel_is_black:
if i <= int(first_number/3) and j <= int(second_number/3):
switch['upperLeft'] = True
elif i <= int(first_number/3) and int(second_number/3) < j <= int(2*second_number/3):
switch['middleLeft'] = True
elif i <= int(first_number/3) and j > int(2*second_number/3):
switch['lowerLeft'] = True
elif int(first_number / 3) <= i < int(2 * first_number / 3) and j < int(second_number / 3):
switch['upperMiddle'] = True
elif int(first_number / 3) <= i < int(2 * first_number / 3) and int(second_number / 3) < j <= int(2 * second_number / 3):
switch['middle'] = True
elif int(first_number / 3) <= i < int(2 * first_number / 3) and j >= int(2 * second_number / 3):
switch['lowerMiddle'] = True
elif i >= int(2 * first_number / 3) and j <= int(2 * second_number / 3):
switch['upperRight'] = True
elif i >= int(2 * first_number / 3) and int(second_number / 3) < j <= int(2 * second_number / 3):
switch['middleRight'] = True
elif i >= int(2 * first_number / 3) and j >= int(2 * second_number / 3):
switch['lowerRight'] = True
for i in switch:
if(switch[i] == True):
print(i)
正如你所看到的,这个声明看起来很难看。 由于数字很大,执行大约需要2秒。 在循环中,我要遍历图像的像素。在if elif语句中,我将图像分成9部分,如果该区域的像素是黑色的,则打印相应的数字。在
有什么方法可以降低CPU时间吗?在
我尝试了this answer,但我的语句条件不同。在
谢谢。在
在本例中,您可以避免整个
if
/elif
/else
的混乱,因为您的条件可以由从i
和j
值直接计算到字典中来代替。在注意,给一些变量起一个更有意义的名字可能是个好主意。},而{}可能变成{}(反之亦然),而{}和{}的值可以变成{}和{}(尽管后两个不那么糟糕,因为{}和{}是非常传统的循环变量)。在
first_number
可能变成{如果您愿意对
switch
稍作修改以进一步提高性能,那么可以用一个列表替换字典,使用从零开始的整数作为索引。您只需要从key
计算中删除+ 1
和str
调用(我还将重命名变量index
)。可以使用switch = [False] * 9
初始化列表。在由于您正在处理图像并使用numpy,我认为最简单的方法是将图像分割成块,然后查看这些块中是否有像素是黑色的。例如,假设我有一个边缘图像,中间没有任何黑色像素,如下所示:
我们可以使用列表理解将图像转换为块:
现在为了让事情简单一点,我们可以在列表字典中按照块的相同顺序创建一个键列表;这样,
^{pr2}$blocks[0]
将对应于switch_list[0]
,即"upperLeft"
。在最后要做的就是找到每个块中的黑色像素。所以我们要遍历9个块(使用循环),然后将块内的值与我们感兴趣的任何颜色进行比较。如果您有一个3通道8位图像,那么黑色通常在每个通道中用
^{3}$0
表示。所以对于一个像素,如果它是黑色的,那么我们可以用pixel == [0,0,0]
来比较它。但这会为每个值返回一个布尔值:当这三个值都匹配时,像素才是黑色的,所以我们可以对结果使用}:
.all()
,如果整个数组是True
,则只返回{所以这是一个单一像素是黑色的指示器。但我们需要检查块内是否有任何像素是黑色的。为了简单起见,我们先来看看单通道图像。假设我们有阵列
如果我们在这里使用逻辑比较
M == 5
,我们将返回一个布尔数组,与M
形状相同,将每个元素与5
进行比较:在我们的例子中,我们不需要知道每个比较,我们只想知道块内的一个单个像素是否为黑色,所以我们只需要一个布尔值。我们可以使用内是
.any()
来检查是否有任何值在^{True
:因此,我们需要将这两个操作结合起来;我们将确保所有的值与我们感兴趣的颜色(
^{8}$[0,0,0]
)相匹配,以便对该像素进行计数,然后我们可以从每个块内的比较中查看是否返回True
:注意}:
axis=2
参数:.all(axis=2)
将把多通道图像缩小为一个像素位置的布尔值;True
,如果每个通道的颜色匹配。然后我们可以检查是否有任何像素位置返回真值。这将为每个块减少为一个布尔值,告诉它是否包含颜色。因此,我们可以根据是否找到黑色像素将字典值设置为True
或{最后,
print
结果是:仅此操作在一张(21402870)图像上花费了~0.1秒。在
按照同样的思路,您可以首先为带有
.all()
的整个图像创建一个True
,False
值的矩阵,然后将拆分成块,然后在块内使用.any()
。这对于内存来说会更好,因为您存储的是9(h,w)
块,而不是9(h,w,depth)
块。在相关问题 更多 >
编程相关推荐